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 "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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |