Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(704)

Side by Side Diff: chrome/browser/devtools/device/android_device_manager.cc

Issue 1078733002: Android device manager should not drop WebSocket frame data even if it arrives together with handsh… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merged horo's CL Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/devtools/device/android_device_manager.h" 5 #include "chrome/browser/devtools/device/android_device_manager.h"
6 6
7 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 const std::string& response) { 45 const std::string& response) {
46 response_message_loop->PostTask(FROM_HERE, 46 response_message_loop->PostTask(FROM_HERE,
47 base::Bind(callback, result, response)); 47 base::Bind(callback, result, response));
48 } 48 }
49 49
50 static void PostHttpUpgradeCallback( 50 static void PostHttpUpgradeCallback(
51 scoped_refptr<base::MessageLoopProxy> response_message_loop, 51 scoped_refptr<base::MessageLoopProxy> response_message_loop,
52 const AndroidDeviceManager::HttpUpgradeCallback& callback, 52 const AndroidDeviceManager::HttpUpgradeCallback& callback,
53 int result, 53 int result,
54 const std::string& extensions, 54 const std::string& extensions,
55 const std::string& body_head,
55 scoped_ptr<net::StreamSocket> socket) { 56 scoped_ptr<net::StreamSocket> socket) {
56 response_message_loop->PostTask( 57 response_message_loop->PostTask(
57 FROM_HERE, 58 FROM_HERE,
58 base::Bind(callback, result, extensions, base::Passed(&socket))); 59 base::Bind(callback, result, extensions, body_head,
60 base::Passed(&socket)));
59 } 61 }
60 62
61 class HttpRequest { 63 class HttpRequest {
62 public: 64 public:
63 typedef AndroidDeviceManager::CommandCallback CommandCallback; 65 typedef AndroidDeviceManager::CommandCallback CommandCallback;
64 typedef AndroidDeviceManager::HttpUpgradeCallback HttpUpgradeCallback; 66 typedef AndroidDeviceManager::HttpUpgradeCallback HttpUpgradeCallback;
65 67
66 static void CommandRequest(const std::string& request, 68 static void CommandRequest(const std::string& request,
67 const CommandCallback& callback, 69 const CommandCallback& callback,
68 int result, 70 int result,
69 scoped_ptr<net::StreamSocket> socket) { 71 scoped_ptr<net::StreamSocket> socket) {
70 if (result != net::OK) { 72 if (result != net::OK) {
71 callback.Run(result, std::string()); 73 callback.Run(result, std::string());
72 return; 74 return;
73 } 75 }
74 new HttpRequest(socket.Pass(), request, callback); 76 new HttpRequest(socket.Pass(), request, callback);
75 } 77 }
76 78
77 static void HttpUpgradeRequest(const std::string& request, 79 static void HttpUpgradeRequest(const std::string& request,
78 const HttpUpgradeCallback& callback, 80 const HttpUpgradeCallback& callback,
79 int result, 81 int result,
80 scoped_ptr<net::StreamSocket> socket) { 82 scoped_ptr<net::StreamSocket> socket) {
81 if (result != net::OK) { 83 if (result != net::OK) {
82 callback.Run(result, "", make_scoped_ptr<net::StreamSocket>(nullptr)); 84 callback.Run(
85 result, "", "", make_scoped_ptr<net::StreamSocket>(nullptr));
83 return; 86 return;
84 } 87 }
85 new HttpRequest(socket.Pass(), request, callback); 88 new HttpRequest(socket.Pass(), request, callback);
86 } 89 }
87 90
88 private: 91 private:
89 HttpRequest(scoped_ptr<net::StreamSocket> socket, 92 HttpRequest(scoped_ptr<net::StreamSocket> socket,
90 const std::string& request, 93 const std::string& request,
91 const CommandCallback& callback) 94 const CommandCallback& callback)
92 : socket_(socket.Pass()), 95 : socket_(socket.Pass()),
93 command_callback_(callback), 96 command_callback_(callback),
94 body_pos_(0) { 97 response_total_size_(-1),
98 response_header_size_(0) {
95 SendRequest(request); 99 SendRequest(request);
96 } 100 }
97 101
98 HttpRequest(scoped_ptr<net::StreamSocket> socket, 102 HttpRequest(scoped_ptr<net::StreamSocket> socket,
99 const std::string& request, 103 const std::string& request,
100 const HttpUpgradeCallback& callback) 104 const HttpUpgradeCallback& callback)
101 : socket_(socket.Pass()), 105 : socket_(socket.Pass()),
102 http_upgrade_callback_(callback), 106 http_upgrade_callback_(callback),
103 body_pos_(0) { 107 response_total_size_(-1),
108 response_header_size_(0) {
104 SendRequest(request); 109 SendRequest(request);
105 } 110 }
106 111
107 ~HttpRequest() { 112 ~HttpRequest() {
108 } 113 }
109 114
110 void SendRequest(const std::string& request) { 115 void SendRequest(const std::string& request) {
111 scoped_refptr<net::StringIOBuffer> request_buffer = 116 scoped_refptr<net::StringIOBuffer> request_buffer =
112 new net::StringIOBuffer(request); 117 new net::StringIOBuffer(request);
113 118
114 int result = socket_->Write( 119 int result = socket_->Write(
115 request_buffer.get(), 120 request_buffer.get(),
116 request_buffer->size(), 121 request_buffer->size(),
117 base::Bind(&HttpRequest::ReadResponse, base::Unretained(this))); 122 base::Bind(&HttpRequest::ReadResponse, base::Unretained(this)));
118 if (result != net::ERR_IO_PENDING) 123 if (result != net::ERR_IO_PENDING)
119 ReadResponse(result); 124 ReadResponse(result);
120 } 125 }
121 126
122 void ReadResponse(int result) { 127 void ReadResponse(int result) {
123 if (!CheckNetResultOrDie(result)) 128 if (!CheckNetResultOrDie(result))
124 return; 129 return;
125 scoped_refptr<net::IOBuffer> response_buffer = 130
126 new net::IOBuffer(kBufferSize); 131 response_buffer_ = new net::IOBuffer(kBufferSize);
127 132
128 result = socket_->Read( 133 result = socket_->Read(
129 response_buffer.get(), 134 response_buffer_.get(),
130 kBufferSize, 135 kBufferSize,
131 base::Bind(&HttpRequest::OnResponseData, base::Unretained(this), 136 base::Bind(&HttpRequest::OnResponseData, base::Unretained(this)));
132 response_buffer,
133 -1));
134 if (result != net::ERR_IO_PENDING) 137 if (result != net::ERR_IO_PENDING)
135 OnResponseData(response_buffer, -1, result); 138 OnResponseData(result);
136 } 139 }
137 140
138 void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, 141 void OnResponseData(int result) {
139 int bytes_total,
140 int result) {
141 if (!CheckNetResultOrDie(result)) 142 if (!CheckNetResultOrDie(result))
142 return; 143 return;
143 if (result == 0) { 144 if (result == 0) {
144 CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); 145 CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED);
145 return; 146 return;
146 } 147 }
147 148
148 response_ += std::string(response_buffer->data(), result); 149 response_.append(response_buffer_->data(), result);
149 int expected_length = 0; 150 if (response_total_size_ < 0) {
150 if (bytes_total < 0) { 151 int expected_length = 0;
152
151 // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header. 153 // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header.
152 std::string content_length = ExtractHeader("Content-Length:"); 154 std::string content_length = ExtractHeader("Content-Length:");
153 if (!content_length.empty()) { 155 if (!content_length.empty()) {
154 if (!base::StringToInt(content_length, &expected_length)) { 156 if (!base::StringToInt(content_length, &expected_length)) {
155 CheckNetResultOrDie(net::ERR_FAILED); 157 CheckNetResultOrDie(net::ERR_FAILED);
156 return; 158 return;
157 } 159 }
158 } 160 }
159 161
160 body_pos_ = response_.find("\r\n\r\n"); 162 response_header_size_ = response_.find("\r\n\r\n");
161 if (body_pos_ != std::string::npos) { 163 if (response_header_size_ != std::string::npos) {
162 body_pos_ += 4; 164 response_header_size_ += 4;
163 bytes_total = body_pos_ + expected_length; 165 response_total_size_ = response_header_size_ + expected_length;
164 } 166 }
165 } 167 }
166 168
167 if (bytes_total == static_cast<int>(response_.length())) { 169 // WebSocket handshake doesn't contain the Content-Length. For this case,
170 // |response_total_size_| is set to the size of the header (handshake).
171 // Some WebSocket frames can be already received into |response_|.
172 if (static_cast<int>(response_.length()) >= response_total_size_) {
173 const std::string& body = response_.substr(response_header_size_);
168 if (!command_callback_.is_null()) { 174 if (!command_callback_.is_null()) {
169 command_callback_.Run(net::OK, response_.substr(body_pos_)); 175 command_callback_.Run(net::OK, body);
170 } else { 176 } else {
177 // Pass the WebSocket frames (in |body|), too.
171 http_upgrade_callback_.Run(net::OK, 178 http_upgrade_callback_.Run(net::OK,
172 ExtractHeader("Sec-WebSocket-Extensions:"), socket_.Pass()); 179 ExtractHeader("Sec-WebSocket-Extensions:"), body, socket_.Pass());
173 } 180 }
174 delete this; 181 delete this;
175 return; 182 return;
176 } 183 }
177 184
178 result = socket_->Read( 185 result = socket_->Read(
179 response_buffer.get(), 186 response_buffer_.get(),
180 kBufferSize, 187 kBufferSize,
181 base::Bind(&HttpRequest::OnResponseData, 188 base::Bind(&HttpRequest::OnResponseData, base::Unretained(this)));
182 base::Unretained(this),
183 response_buffer,
184 bytes_total));
185 if (result != net::ERR_IO_PENDING) 189 if (result != net::ERR_IO_PENDING)
186 OnResponseData(response_buffer, bytes_total, result); 190 OnResponseData(result);
187 } 191 }
188 192
189 std::string ExtractHeader(const std::string& header) { 193 std::string ExtractHeader(const std::string& header) {
190 size_t start_pos = response_.find(header); 194 size_t start_pos = response_.find(header);
191 if (start_pos == std::string::npos) 195 if (start_pos == std::string::npos)
192 return std::string(); 196 return std::string();
193 197
194 size_t endline_pos = response_.find("\n", start_pos); 198 size_t endline_pos = response_.find("\n", start_pos);
195 if (endline_pos == std::string::npos) 199 if (endline_pos == std::string::npos)
196 return std::string(); 200 return std::string();
197 201
198 std::string value = response_.substr( 202 std::string value = response_.substr(
199 start_pos + header.length(), endline_pos - start_pos - header.length()); 203 start_pos + header.length(), endline_pos - start_pos - header.length());
200 base::TrimWhitespace(value, base::TRIM_ALL, &value); 204 base::TrimWhitespace(value, base::TRIM_ALL, &value);
201 return value; 205 return value;
202 } 206 }
203 207
204 bool CheckNetResultOrDie(int result) { 208 bool CheckNetResultOrDie(int result) {
205 if (result >= 0) 209 if (result >= 0)
206 return true; 210 return true;
207 if (!command_callback_.is_null()) { 211 if (!command_callback_.is_null()) {
208 command_callback_.Run(result, std::string()); 212 command_callback_.Run(result, std::string());
209 } else { 213 } else {
210 http_upgrade_callback_.Run( 214 http_upgrade_callback_.Run(
211 result, "", make_scoped_ptr<net::StreamSocket>(nullptr)); 215 result, "", "", make_scoped_ptr<net::StreamSocket>(nullptr));
dgozman 2015/04/09 14:05:22 nit: "" -> std::string()
tyoshino (SeeGerritForStatus) 2015/04/14 12:24:32 Done.
212 } 216 }
213 delete this; 217 delete this;
214 return false; 218 return false;
215 } 219 }
216 220
217 scoped_ptr<net::StreamSocket> socket_; 221 scoped_ptr<net::StreamSocket> socket_;
218 std::string response_; 222 std::string response_;
219 CommandCallback command_callback_; 223 CommandCallback command_callback_;
220 HttpUpgradeCallback http_upgrade_callback_; 224 HttpUpgradeCallback http_upgrade_callback_;
221 size_t body_pos_; 225
226 scoped_refptr<net::IOBuffer> response_buffer_;
227 // Initially -1. Once the end of the header is seen:
228 // - If the Content-Length header is included, this variable is set to the
229 // sum of the header size (including the last two CRLFs) and the value of
230 // the header.
231 // - Otherwise, this variable is set to the size of the header (including the
232 // last two CRLFs).
233 int response_total_size_;
dgozman 2015/04/09 14:05:22 Consider renaming to |expected_size_| to emphasize
tyoshino (SeeGerritForStatus) 2015/04/14 12:24:32 Done.
234 // Set to the size of the header part in |response_|.
235 size_t response_header_size_;
dgozman 2015/04/09 14:05:22 I'd just call this |header_size_|, since this clas
tyoshino (SeeGerritForStatus) 2015/04/14 12:24:32 Done.
222 }; 236 };
223 237
224 class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> { 238 class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> {
225 public: 239 public:
226 typedef AndroidDeviceManager::DeviceInfo DeviceInfo; 240 typedef AndroidDeviceManager::DeviceInfo DeviceInfo;
227 typedef AndroidDeviceManager::DeviceProvider DeviceProvider; 241 typedef AndroidDeviceManager::DeviceProvider DeviceProvider;
228 typedef AndroidDeviceManager::DeviceProviders DeviceProviders; 242 typedef AndroidDeviceManager::DeviceProviders DeviceProviders;
229 typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors; 243 typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors;
230 typedef base::Callback<void(scoped_ptr<DeviceDescriptors>)> 244 typedef base::Callback<void(scoped_ptr<DeviceDescriptors>)>
231 DescriptorsCallback; 245 DescriptorsCallback;
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 it->provider, it->serial); 537 it->provider, it->serial);
524 } else { 538 } else {
525 device = found->second.get(); 539 device = found->second.get();
526 } 540 }
527 response.push_back(device); 541 response.push_back(device);
528 new_devices[it->serial] = device->weak_factory_.GetWeakPtr(); 542 new_devices[it->serial] = device->weak_factory_.GetWeakPtr();
529 } 543 }
530 devices_.swap(new_devices); 544 devices_.swap(new_devices);
531 callback.Run(response); 545 callback.Run(response);
532 } 546 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698