OLD | NEW |
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 <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 const std::string& response) { | 47 const std::string& response) { |
48 response_message_loop->PostTask(FROM_HERE, | 48 response_message_loop->PostTask(FROM_HERE, |
49 base::Bind(callback, result, response)); | 49 base::Bind(callback, result, response)); |
50 } | 50 } |
51 | 51 |
52 static void PostHttpUpgradeCallback( | 52 static void PostHttpUpgradeCallback( |
53 scoped_refptr<base::MessageLoopProxy> response_message_loop, | 53 scoped_refptr<base::MessageLoopProxy> response_message_loop, |
54 const AndroidDeviceManager::HttpUpgradeCallback& callback, | 54 const AndroidDeviceManager::HttpUpgradeCallback& callback, |
55 int result, | 55 int result, |
56 const std::string& extensions, | 56 const std::string& extensions, |
| 57 const std::string& body_head, |
57 scoped_ptr<net::StreamSocket> socket) { | 58 scoped_ptr<net::StreamSocket> socket) { |
58 response_message_loop->PostTask( | 59 response_message_loop->PostTask( |
59 FROM_HERE, | 60 FROM_HERE, |
60 base::Bind(callback, result, extensions, base::Passed(&socket))); | 61 base::Bind(callback, result, extensions, body_head, |
| 62 base::Passed(&socket))); |
61 } | 63 } |
62 | 64 |
63 class HttpRequest { | 65 class HttpRequest { |
64 public: | 66 public: |
65 typedef AndroidDeviceManager::CommandCallback CommandCallback; | 67 typedef AndroidDeviceManager::CommandCallback CommandCallback; |
66 typedef AndroidDeviceManager::HttpUpgradeCallback HttpUpgradeCallback; | 68 typedef AndroidDeviceManager::HttpUpgradeCallback HttpUpgradeCallback; |
67 | 69 |
68 static void CommandRequest(const std::string& request, | 70 static void CommandRequest(const std::string& request, |
69 const CommandCallback& callback, | 71 const CommandCallback& callback, |
70 int result, | 72 int result, |
71 scoped_ptr<net::StreamSocket> socket) { | 73 scoped_ptr<net::StreamSocket> socket) { |
72 if (result != net::OK) { | 74 if (result != net::OK) { |
73 callback.Run(result, std::string()); | 75 callback.Run(result, std::string()); |
74 return; | 76 return; |
75 } | 77 } |
76 new HttpRequest(socket.Pass(), request, callback); | 78 new HttpRequest(socket.Pass(), request, callback); |
77 } | 79 } |
78 | 80 |
79 static void HttpUpgradeRequest(const std::string& request, | 81 static void HttpUpgradeRequest(const std::string& request, |
80 const HttpUpgradeCallback& callback, | 82 const HttpUpgradeCallback& callback, |
81 int result, | 83 int result, |
82 scoped_ptr<net::StreamSocket> socket) { | 84 scoped_ptr<net::StreamSocket> socket) { |
83 if (result != net::OK) { | 85 if (result != net::OK) { |
84 callback.Run(result, "", make_scoped_ptr<net::StreamSocket>(nullptr)); | 86 callback.Run( |
| 87 result, std::string(), std::string(), |
| 88 make_scoped_ptr<net::StreamSocket>(nullptr)); |
85 return; | 89 return; |
86 } | 90 } |
87 new HttpRequest(socket.Pass(), request, callback); | 91 new HttpRequest(socket.Pass(), request, callback); |
88 } | 92 } |
89 | 93 |
90 private: | 94 private: |
91 HttpRequest(scoped_ptr<net::StreamSocket> socket, | 95 HttpRequest(scoped_ptr<net::StreamSocket> socket, |
92 const std::string& request, | 96 const std::string& request, |
93 const CommandCallback& callback) | 97 const CommandCallback& callback) |
94 : socket_(socket.Pass()), | 98 : socket_(socket.Pass()), |
95 command_callback_(callback), | 99 command_callback_(callback), |
96 body_pos_(0) { | 100 expected_size_(-1), |
| 101 header_size_(0) { |
97 SendRequest(request); | 102 SendRequest(request); |
98 } | 103 } |
99 | 104 |
100 HttpRequest(scoped_ptr<net::StreamSocket> socket, | 105 HttpRequest(scoped_ptr<net::StreamSocket> socket, |
101 const std::string& request, | 106 const std::string& request, |
102 const HttpUpgradeCallback& callback) | 107 const HttpUpgradeCallback& callback) |
103 : socket_(socket.Pass()), | 108 : socket_(socket.Pass()), |
104 http_upgrade_callback_(callback), | 109 http_upgrade_callback_(callback), |
105 body_pos_(0) { | 110 expected_size_(-1), |
| 111 header_size_(0) { |
106 SendRequest(request); | 112 SendRequest(request); |
107 } | 113 } |
108 | 114 |
109 ~HttpRequest() { | 115 ~HttpRequest() { |
110 } | 116 } |
111 | 117 |
112 void DoSendRequest(int result) { | 118 void DoSendRequest(int result) { |
113 while (result != net::ERR_IO_PENDING) { | 119 while (result != net::ERR_IO_PENDING) { |
114 if (!CheckNetResultOrDie(result)) | 120 if (!CheckNetResultOrDie(result)) |
115 return; | 121 return; |
(...skipping 19 matching lines...) Expand all Loading... |
135 new net::IOBuffer(request.size()); | 141 new net::IOBuffer(request.size()); |
136 memcpy(base_buffer->data(), request.data(), request.size()); | 142 memcpy(base_buffer->data(), request.data(), request.size()); |
137 request_ = new net::DrainableIOBuffer(base_buffer.get(), request.size()); | 143 request_ = new net::DrainableIOBuffer(base_buffer.get(), request.size()); |
138 | 144 |
139 DoSendRequest(net::OK); | 145 DoSendRequest(net::OK); |
140 } | 146 } |
141 | 147 |
142 void ReadResponse(int result) { | 148 void ReadResponse(int result) { |
143 if (!CheckNetResultOrDie(result)) | 149 if (!CheckNetResultOrDie(result)) |
144 return; | 150 return; |
145 scoped_refptr<net::IOBuffer> response_buffer = | 151 |
146 new net::IOBuffer(kBufferSize); | 152 response_buffer_ = new net::IOBuffer(kBufferSize); |
147 | 153 |
148 result = socket_->Read( | 154 result = socket_->Read( |
149 response_buffer.get(), | 155 response_buffer_.get(), |
150 kBufferSize, | 156 kBufferSize, |
151 base::Bind(&HttpRequest::OnResponseData, base::Unretained(this), | 157 base::Bind(&HttpRequest::OnResponseData, base::Unretained(this))); |
152 response_buffer, | |
153 -1)); | |
154 if (result != net::ERR_IO_PENDING) | 158 if (result != net::ERR_IO_PENDING) |
155 OnResponseData(response_buffer, -1, result); | 159 OnResponseData(result); |
156 } | 160 } |
157 | 161 |
158 void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, | 162 void OnResponseData(int result) { |
159 int bytes_total, | |
160 int result) { | |
161 if (!CheckNetResultOrDie(result)) | 163 if (!CheckNetResultOrDie(result)) |
162 return; | 164 return; |
163 if (result == 0) { | 165 if (result == 0) { |
164 CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); | 166 CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); |
165 return; | 167 return; |
166 } | 168 } |
167 | 169 |
168 response_ += std::string(response_buffer->data(), result); | 170 response_.append(response_buffer_->data(), result); |
169 int expected_length = 0; | 171 if (expected_size_ < 0) { |
170 if (bytes_total < 0) { | 172 int expected_length = 0; |
| 173 |
171 // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header. | 174 // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header. |
172 std::string content_length = ExtractHeader("Content-Length:"); | 175 std::string content_length = ExtractHeader("Content-Length:"); |
173 if (!content_length.empty()) { | 176 if (!content_length.empty()) { |
174 if (!base::StringToInt(content_length, &expected_length)) { | 177 if (!base::StringToInt(content_length, &expected_length)) { |
175 CheckNetResultOrDie(net::ERR_FAILED); | 178 CheckNetResultOrDie(net::ERR_FAILED); |
176 return; | 179 return; |
177 } | 180 } |
178 } | 181 } |
179 | 182 |
180 body_pos_ = response_.find("\r\n\r\n"); | 183 header_size_ = response_.find("\r\n\r\n"); |
181 if (body_pos_ != std::string::npos) { | 184 if (header_size_ != std::string::npos) { |
182 body_pos_ += 4; | 185 header_size_ += 4; |
183 bytes_total = body_pos_ + expected_length; | 186 expected_size_ = header_size_ + expected_length; |
184 } | 187 } |
185 } | 188 } |
186 | 189 |
187 if (bytes_total == static_cast<int>(response_.length())) { | 190 // WebSocket handshake doesn't contain the Content-Length. For this case, |
| 191 // |expected_size_| is set to the size of the header (handshake). |
| 192 // Some WebSocket frames can be already received into |response_|. |
| 193 if (static_cast<int>(response_.length()) >= expected_size_) { |
| 194 const std::string& body = response_.substr(header_size_); |
188 if (!command_callback_.is_null()) { | 195 if (!command_callback_.is_null()) { |
189 command_callback_.Run(net::OK, response_.substr(body_pos_)); | 196 command_callback_.Run(net::OK, body); |
190 } else { | 197 } else { |
| 198 // Pass the WebSocket frames (in |body|), too. |
191 http_upgrade_callback_.Run(net::OK, | 199 http_upgrade_callback_.Run(net::OK, |
192 ExtractHeader("Sec-WebSocket-Extensions:"), socket_.Pass()); | 200 ExtractHeader("Sec-WebSocket-Extensions:"), body, socket_.Pass()); |
193 } | 201 } |
194 delete this; | 202 delete this; |
195 return; | 203 return; |
196 } | 204 } |
197 | 205 |
198 result = socket_->Read( | 206 result = socket_->Read( |
199 response_buffer.get(), | 207 response_buffer_.get(), |
200 kBufferSize, | 208 kBufferSize, |
201 base::Bind(&HttpRequest::OnResponseData, | 209 base::Bind(&HttpRequest::OnResponseData, base::Unretained(this))); |
202 base::Unretained(this), | |
203 response_buffer, | |
204 bytes_total)); | |
205 if (result != net::ERR_IO_PENDING) | 210 if (result != net::ERR_IO_PENDING) |
206 OnResponseData(response_buffer, bytes_total, result); | 211 OnResponseData(result); |
207 } | 212 } |
208 | 213 |
209 std::string ExtractHeader(const std::string& header) { | 214 std::string ExtractHeader(const std::string& header) { |
210 size_t start_pos = response_.find(header); | 215 size_t start_pos = response_.find(header); |
211 if (start_pos == std::string::npos) | 216 if (start_pos == std::string::npos) |
212 return std::string(); | 217 return std::string(); |
213 | 218 |
214 size_t endline_pos = response_.find("\n", start_pos); | 219 size_t endline_pos = response_.find("\n", start_pos); |
215 if (endline_pos == std::string::npos) | 220 if (endline_pos == std::string::npos) |
216 return std::string(); | 221 return std::string(); |
217 | 222 |
218 std::string value = response_.substr( | 223 std::string value = response_.substr( |
219 start_pos + header.length(), endline_pos - start_pos - header.length()); | 224 start_pos + header.length(), endline_pos - start_pos - header.length()); |
220 base::TrimWhitespace(value, base::TRIM_ALL, &value); | 225 base::TrimWhitespace(value, base::TRIM_ALL, &value); |
221 return value; | 226 return value; |
222 } | 227 } |
223 | 228 |
224 bool CheckNetResultOrDie(int result) { | 229 bool CheckNetResultOrDie(int result) { |
225 if (result >= 0) | 230 if (result >= 0) |
226 return true; | 231 return true; |
227 if (!command_callback_.is_null()) { | 232 if (!command_callback_.is_null()) { |
228 command_callback_.Run(result, std::string()); | 233 command_callback_.Run(result, std::string()); |
229 } else { | 234 } else { |
230 http_upgrade_callback_.Run( | 235 http_upgrade_callback_.Run( |
231 result, "", make_scoped_ptr<net::StreamSocket>(nullptr)); | 236 result, std::string(), std::string(), |
| 237 make_scoped_ptr<net::StreamSocket>(nullptr)); |
232 } | 238 } |
233 delete this; | 239 delete this; |
234 return false; | 240 return false; |
235 } | 241 } |
236 | 242 |
237 scoped_ptr<net::StreamSocket> socket_; | 243 scoped_ptr<net::StreamSocket> socket_; |
238 scoped_refptr<net::DrainableIOBuffer> request_; | 244 scoped_refptr<net::DrainableIOBuffer> request_; |
239 std::string response_; | 245 std::string response_; |
240 CommandCallback command_callback_; | 246 CommandCallback command_callback_; |
241 HttpUpgradeCallback http_upgrade_callback_; | 247 HttpUpgradeCallback http_upgrade_callback_; |
242 size_t body_pos_; | 248 |
| 249 scoped_refptr<net::IOBuffer> response_buffer_; |
| 250 // Initially -1. Once the end of the header is seen: |
| 251 // - If the Content-Length header is included, this variable is set to the |
| 252 // sum of the header size (including the last two CRLFs) and the value of |
| 253 // the header. |
| 254 // - Otherwise, this variable is set to the size of the header (including the |
| 255 // last two CRLFs). |
| 256 int expected_size_; |
| 257 // Set to the size of the header part in |response_|. |
| 258 size_t header_size_; |
243 }; | 259 }; |
244 | 260 |
245 class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> { | 261 class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> { |
246 public: | 262 public: |
247 typedef AndroidDeviceManager::DeviceInfo DeviceInfo; | 263 typedef AndroidDeviceManager::DeviceInfo DeviceInfo; |
248 typedef AndroidDeviceManager::DeviceProvider DeviceProvider; | 264 typedef AndroidDeviceManager::DeviceProvider DeviceProvider; |
249 typedef AndroidDeviceManager::DeviceProviders DeviceProviders; | 265 typedef AndroidDeviceManager::DeviceProviders DeviceProviders; |
250 typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors; | 266 typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors; |
251 typedef base::Callback<void(scoped_ptr<DeviceDescriptors>)> | 267 typedef base::Callback<void(scoped_ptr<DeviceDescriptors>)> |
252 DescriptorsCallback; | 268 DescriptorsCallback; |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 it->provider, it->serial); | 560 it->provider, it->serial); |
545 } else { | 561 } else { |
546 device = found->second.get(); | 562 device = found->second.get(); |
547 } | 563 } |
548 response.push_back(device); | 564 response.push_back(device); |
549 new_devices[it->serial] = device->weak_factory_.GetWeakPtr(); | 565 new_devices[it->serial] = device->weak_factory_.GetWeakPtr(); |
550 } | 566 } |
551 devices_.swap(new_devices); | 567 devices_.swap(new_devices); |
552 callback.Run(response); | 568 callback.Run(response); |
553 } | 569 } |
OLD | NEW |