OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/adb_client_socket.h" | 5 #include "chrome/browser/devtools/adb_client_socket.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 std::string result(4, '\0'); | 31 std::string result(4, '\0'); |
32 char b = reinterpret_cast<const char*>(&length)[1]; | 32 char b = reinterpret_cast<const char*>(&length)[1]; |
33 result[0] = kHexChars[(b >> 4) & 0xf]; | 33 result[0] = kHexChars[(b >> 4) & 0xf]; |
34 result[1] = kHexChars[b & 0xf]; | 34 result[1] = kHexChars[b & 0xf]; |
35 b = reinterpret_cast<const char*>(&length)[0]; | 35 b = reinterpret_cast<const char*>(&length)[0]; |
36 result[2] = kHexChars[(b >> 4) & 0xf]; | 36 result[2] = kHexChars[(b >> 4) & 0xf]; |
37 result[3] = kHexChars[b & 0xf]; | 37 result[3] = kHexChars[b & 0xf]; |
38 return result + message; | 38 return result + message; |
39 } | 39 } |
40 | 40 |
41 class AdbSocket { | 41 class AdbTransportSocket : public AdbClientSocket { |
42 public: | |
43 AdbSocket(const std::string& host, int port) : host_(host), port_(port) { | |
44 } | |
45 | |
46 ~AdbSocket() { | |
47 } | |
48 | |
49 protected: | |
50 void Connect(const net::CompletionCallback& callback) { | |
51 net::IPAddressNumber ip_number; | |
52 if (!net::ParseIPLiteralToNumber(host_, &ip_number)) { | |
53 callback.Run(net::ERR_FAILED); | |
54 return; | |
55 } | |
56 | |
57 net::AddressList address_list = | |
58 net::AddressList::CreateFromIPAddress(ip_number, port_); | |
59 socket_.reset(new net::TCPClientSocket(address_list, NULL, | |
60 net::NetLog::Source())); | |
61 int result = socket_->Connect(callback); | |
62 if (result != net::ERR_IO_PENDING) | |
63 callback.Run(result); | |
64 } | |
65 | |
66 void SendCommand(const std::string& command, | |
67 bool is_void, | |
68 const CommandCallback& callback) { | |
69 scoped_refptr<net::StringIOBuffer> request_buffer = | |
70 new net::StringIOBuffer(EncodeMessage(command)); | |
71 int result = socket_->Write(request_buffer, request_buffer->size(), | |
72 base::Bind(&AdbSocket::ReadResponse, base::Unretained(this), | |
73 callback, is_void)); | |
74 if (result != net::ERR_IO_PENDING) | |
75 ReadResponse(callback, is_void, result); | |
76 } | |
77 | |
78 scoped_ptr<net::TCPClientSocket> socket_; | |
79 | |
80 private: | |
81 void ReadResponse(const CommandCallback& callback, bool is_void, int result) { | |
82 if (result < 0) { | |
83 callback.Run(result, "IO error"); | |
84 return; | |
85 } | |
86 scoped_refptr<net::IOBuffer> response_buffer = | |
87 new net::IOBuffer(kBufferSize); | |
88 result = socket_->Read(response_buffer, kBufferSize, | |
89 base::Bind(&AdbSocket::OnResponseHeader, base::Unretained(this), | |
90 callback, is_void, response_buffer)); | |
91 if (result != net::ERR_IO_PENDING) | |
92 OnResponseHeader(callback, is_void, response_buffer, result); | |
93 } | |
94 | |
95 void OnResponseHeader(const CommandCallback& callback, | |
96 bool is_void, | |
97 scoped_refptr<net::IOBuffer> response_buffer, | |
98 int result) { | |
99 if (result < 0) { | |
100 callback.Run(result, "IO error"); | |
101 return; | |
102 } | |
103 | |
104 std::string data = std::string(response_buffer->data(), result); | |
105 if (result < 4) { | |
106 callback.Run(net::ERR_FAILED, "Response is too short: " + data); | |
107 return; | |
108 } | |
109 | |
110 std::string status = data.substr(0, 4); | |
111 if (status != kOkayResponse) { | |
112 callback.Run(net::ERR_FAILED, data); | |
113 return; | |
114 } | |
115 | |
116 data = data.substr(4); | |
117 | |
118 if (!is_void) { | |
119 int payload_length = 0; | |
120 int bytes_left = -1; | |
121 if (data.length() >= 4 && | |
122 base::HexStringToInt(data.substr(0, 4), &payload_length)) { | |
123 data = data.substr(4); | |
124 bytes_left = payload_length - result + 8; | |
125 } else { | |
126 bytes_left = -1; | |
127 } | |
128 OnResponseData(callback, data, response_buffer, bytes_left, 0); | |
129 } else { | |
130 callback.Run(net::OK, data); | |
131 } | |
132 } | |
133 | |
134 void OnResponseData(const CommandCallback& callback, | |
135 const std::string& response, | |
136 scoped_refptr<net::IOBuffer> response_buffer, | |
137 int bytes_left, | |
138 int result) { | |
139 if (result < 0) { | |
140 callback.Run(result, "IO error"); | |
141 return; | |
142 } | |
143 | |
144 bytes_left -= result; | |
145 std::string new_response = | |
146 response + std::string(response_buffer->data(), result); | |
147 if (bytes_left == 0) { | |
148 callback.Run(net::OK, new_response); | |
149 return; | |
150 } | |
151 | |
152 // Read tail | |
153 result = socket_->Read(response_buffer, kBufferSize, | |
154 base::Bind(&AdbSocket::OnResponseData, base::Unretained(this), | |
155 callback, new_response, response_buffer, bytes_left)); | |
156 if (result > 0) { | |
157 OnResponseData(callback, new_response, response_buffer, bytes_left, | |
158 result); | |
159 } else if (result != net::ERR_IO_PENDING) { | |
160 callback.Run(net::OK, new_response); | |
161 } | |
162 } | |
163 | |
164 std::string host_; | |
165 int port_; | |
166 }; | |
167 | |
168 class AdbTransportSocket : public AdbSocket { | |
169 public: | 42 public: |
170 AdbTransportSocket(const std::string& host, | 43 AdbTransportSocket(const std::string& host, |
171 int port, | 44 int port, |
172 const std::string& serial, | 45 const std::string& serial, |
173 const std::string& socket_name, | 46 const std::string& socket_name, |
174 const SocketCallback& callback) | 47 const SocketCallback& callback) |
175 : AdbSocket(host, port), | 48 : AdbClientSocket(host, port), |
176 serial_(serial), | 49 serial_(serial), |
177 socket_name_(socket_name), | 50 socket_name_(socket_name), |
178 callback_(callback) { | 51 callback_(callback) { |
179 Connect(base::Bind(&AdbTransportSocket::OnConnected, | 52 Connect(base::Bind(&AdbTransportSocket::OnConnected, |
180 base::Unretained(this))); | 53 base::Unretained(this))); |
181 } | 54 } |
182 | 55 |
183 private: | 56 private: |
184 ~AdbTransportSocket() {} | 57 ~AdbTransportSocket() {} |
185 | 58 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 response_buffer, -1)); | 160 response_buffer, -1)); |
288 if (result != net::ERR_IO_PENDING) | 161 if (result != net::ERR_IO_PENDING) |
289 OnResponseData(response_buffer, -1, result); | 162 OnResponseData(response_buffer, -1, result); |
290 } | 163 } |
291 | 164 |
292 void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, | 165 void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, |
293 int bytes_total, | 166 int bytes_total, |
294 int result) { | 167 int result) { |
295 if (!CheckNetResultOrDie(result)) | 168 if (!CheckNetResultOrDie(result)) |
296 return; | 169 return; |
| 170 if (result == 0) { |
| 171 CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); |
| 172 return; |
| 173 } |
297 | 174 |
298 response_ += std::string(response_buffer->data(), result); | 175 response_ += std::string(response_buffer->data(), result); |
299 int expected_length = 0; | 176 int expected_length = 0; |
300 if (bytes_total < 0) { | 177 if (bytes_total < 0) { |
301 size_t content_pos = response_.find("Content-Length:"); | 178 size_t content_pos = response_.find("Content-Length:"); |
302 if (content_pos != std::string::npos) { | 179 if (content_pos != std::string::npos) { |
303 size_t endline_pos = response_.find("\n", content_pos); | 180 size_t endline_pos = response_.find("\n", content_pos); |
304 if (endline_pos != std::string::npos) { | 181 if (endline_pos != std::string::npos) { |
305 std::string len = response_.substr(content_pos + 15, | 182 std::string len = response_.substr(content_pos + 15, |
306 endline_pos - content_pos - 15); | 183 endline_pos - content_pos - 15); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 } | 224 } |
348 | 225 |
349 scoped_ptr<net::TCPClientSocket> socket_; | 226 scoped_ptr<net::TCPClientSocket> socket_; |
350 std::string request_; | 227 std::string request_; |
351 std::string response_; | 228 std::string response_; |
352 CommandCallback command_callback_; | 229 CommandCallback command_callback_; |
353 SocketCallback socket_callback_; | 230 SocketCallback socket_callback_; |
354 size_t body_pos_; | 231 size_t body_pos_; |
355 }; | 232 }; |
356 | 233 |
357 class AdbQuerySocket : AdbSocket { | 234 class AdbQuerySocket : AdbClientSocket { |
358 public: | 235 public: |
359 AdbQuerySocket(const std::string& host, | 236 AdbQuerySocket(const std::string& host, |
360 int port, | 237 int port, |
361 const std::string& query, | 238 const std::string& query, |
362 const CommandCallback& callback) | 239 const CommandCallback& callback) |
363 : AdbSocket(host, port), | 240 : AdbClientSocket(host, port), |
364 current_query_(0), | 241 current_query_(0), |
365 callback_(callback) { | 242 callback_(callback) { |
366 if (Tokenize(query, "|", &queries_) == 0) { | 243 if (Tokenize(query, "|", &queries_) == 0) { |
367 CheckNetResultOrDie(net::ERR_INVALID_ARGUMENT); | 244 CheckNetResultOrDie(net::ERR_INVALID_ARGUMENT); |
368 return; | 245 return; |
369 } | 246 } |
370 Connect(base::Bind(&AdbQuerySocket::SendNextQuery, | 247 Connect(base::Bind(&AdbQuerySocket::SendNextQuery, |
371 base::Unretained(this))); | 248 base::Unretained(this))); |
372 } | 249 } |
373 | 250 |
374 private: | 251 private: |
375 ~AdbQuerySocket() { | 252 ~AdbQuerySocket() { |
376 | |
377 } | 253 } |
378 | 254 |
379 void SendNextQuery(int result) { | 255 void SendNextQuery(int result) { |
380 if (!CheckNetResultOrDie(result)) | 256 if (!CheckNetResultOrDie(result)) |
381 return; | 257 return; |
382 std::string query = queries_[current_query_]; | 258 std::string query = queries_[current_query_]; |
383 if (query.length() > 0xFFFF) { | 259 if (query.length() > 0xFFFF) { |
384 CheckNetResultOrDie(net::ERR_MSG_TOO_BIG); | 260 CheckNetResultOrDie(net::ERR_MSG_TOO_BIG); |
385 return; | 261 return; |
386 } | 262 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 // static | 309 // static |
434 void AdbClientSocket::HttpQuery(int port, | 310 void AdbClientSocket::HttpQuery(int port, |
435 const std::string& serial, | 311 const std::string& serial, |
436 const std::string& socket_name, | 312 const std::string& socket_name, |
437 const std::string& request_path, | 313 const std::string& request_path, |
438 const SocketCallback& callback) { | 314 const SocketCallback& callback) { |
439 new HttpOverAdbSocket(kLocalhost, port, serial, socket_name, request_path, | 315 new HttpOverAdbSocket(kLocalhost, port, serial, socket_name, request_path, |
440 callback); | 316 callback); |
441 } | 317 } |
442 | 318 |
443 AdbClientSocket::AdbClientSocket() { | 319 AdbClientSocket::AdbClientSocket(const std::string& host, int port) |
| 320 : host_(host), port_(port) { |
444 } | 321 } |
445 | 322 |
446 AdbClientSocket::~AdbClientSocket() { | 323 AdbClientSocket::~AdbClientSocket() { |
447 } | 324 } |
| 325 |
| 326 void AdbClientSocket::Connect(const net::CompletionCallback& callback) { |
| 327 net::IPAddressNumber ip_number; |
| 328 if (!net::ParseIPLiteralToNumber(host_, &ip_number)) { |
| 329 callback.Run(net::ERR_FAILED); |
| 330 return; |
| 331 } |
| 332 |
| 333 net::AddressList address_list = |
| 334 net::AddressList::CreateFromIPAddress(ip_number, port_); |
| 335 socket_.reset(new net::TCPClientSocket(address_list, NULL, |
| 336 net::NetLog::Source())); |
| 337 int result = socket_->Connect(callback); |
| 338 if (result != net::ERR_IO_PENDING) |
| 339 callback.Run(result); |
| 340 } |
| 341 |
| 342 void AdbClientSocket::SendCommand(const std::string& command, |
| 343 bool is_void, |
| 344 const CommandCallback& callback) { |
| 345 scoped_refptr<net::StringIOBuffer> request_buffer = |
| 346 new net::StringIOBuffer(EncodeMessage(command)); |
| 347 int result = socket_->Write(request_buffer, request_buffer->size(), |
| 348 base::Bind(&AdbClientSocket::ReadResponse, base::Unretained(this), |
| 349 callback, is_void)); |
| 350 if (result != net::ERR_IO_PENDING) |
| 351 ReadResponse(callback, is_void, result); |
| 352 } |
| 353 |
| 354 void AdbClientSocket::ReadResponse(const CommandCallback& callback, |
| 355 bool is_void, |
| 356 int result) { |
| 357 if (result < 0) { |
| 358 callback.Run(result, "IO error"); |
| 359 return; |
| 360 } |
| 361 scoped_refptr<net::IOBuffer> response_buffer = |
| 362 new net::IOBuffer(kBufferSize); |
| 363 result = socket_->Read(response_buffer, kBufferSize, |
| 364 base::Bind(&AdbClientSocket::OnResponseHeader, base::Unretained(this), |
| 365 callback, is_void, response_buffer)); |
| 366 if (result != net::ERR_IO_PENDING) |
| 367 OnResponseHeader(callback, is_void, response_buffer, result); |
| 368 } |
| 369 |
| 370 void AdbClientSocket::OnResponseHeader( |
| 371 const CommandCallback& callback, |
| 372 bool is_void, |
| 373 scoped_refptr<net::IOBuffer> response_buffer, |
| 374 int result) { |
| 375 if (result <= 0) { |
| 376 callback.Run(result == 0 ? net::ERR_CONNECTION_CLOSED : result, |
| 377 "IO error"); |
| 378 return; |
| 379 } |
| 380 |
| 381 std::string data = std::string(response_buffer->data(), result); |
| 382 if (result < 4) { |
| 383 callback.Run(net::ERR_FAILED, "Response is too short: " + data); |
| 384 return; |
| 385 } |
| 386 |
| 387 std::string status = data.substr(0, 4); |
| 388 if (status != kOkayResponse) { |
| 389 callback.Run(net::ERR_FAILED, data); |
| 390 return; |
| 391 } |
| 392 |
| 393 data = data.substr(4); |
| 394 |
| 395 if (!is_void) { |
| 396 int payload_length = 0; |
| 397 int bytes_left = -1; |
| 398 if (data.length() >= 4 && |
| 399 base::HexStringToInt(data.substr(0, 4), &payload_length)) { |
| 400 data = data.substr(4); |
| 401 bytes_left = payload_length - result + 8; |
| 402 } else { |
| 403 bytes_left = -1; |
| 404 } |
| 405 OnResponseData(callback, data, response_buffer, bytes_left, 0); |
| 406 } else { |
| 407 callback.Run(net::OK, data); |
| 408 } |
| 409 } |
| 410 |
| 411 void AdbClientSocket::OnResponseData( |
| 412 const CommandCallback& callback, |
| 413 const std::string& response, |
| 414 scoped_refptr<net::IOBuffer> response_buffer, |
| 415 int bytes_left, |
| 416 int result) { |
| 417 if (result < 0) { |
| 418 callback.Run(result, "IO error"); |
| 419 return; |
| 420 } |
| 421 |
| 422 bytes_left -= result; |
| 423 std::string new_response = |
| 424 response + std::string(response_buffer->data(), result); |
| 425 if (bytes_left == 0) { |
| 426 callback.Run(net::OK, new_response); |
| 427 return; |
| 428 } |
| 429 |
| 430 // Read tail |
| 431 result = socket_->Read(response_buffer, kBufferSize, |
| 432 base::Bind(&AdbClientSocket::OnResponseData, base::Unretained(this), |
| 433 callback, new_response, response_buffer, bytes_left)); |
| 434 if (result > 0) |
| 435 OnResponseData(callback, new_response, response_buffer, bytes_left, result); |
| 436 else if (result != net::ERR_IO_PENDING) |
| 437 callback.Run(net::OK, new_response); |
| 438 } |
OLD | NEW |