| Index: chrome/browser/devtools/device/android_device_manager.cc
|
| diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc
|
| index debd55d722e4a293684cae7f3e3881ce60fff77d..655e7afe1ad46cc1517f2a4cbc3532b6977b0f59 100644
|
| --- a/chrome/browser/devtools/device/android_device_manager.cc
|
| +++ b/chrome/browser/devtools/device/android_device_manager.cc
|
| @@ -54,10 +54,12 @@ static void PostHttpUpgradeCallback(
|
| const AndroidDeviceManager::HttpUpgradeCallback& callback,
|
| int result,
|
| const std::string& extensions,
|
| + const std::string& body_head,
|
| scoped_ptr<net::StreamSocket> socket) {
|
| response_message_loop->PostTask(
|
| FROM_HERE,
|
| - base::Bind(callback, result, extensions, base::Passed(&socket)));
|
| + base::Bind(callback, result, extensions, body_head,
|
| + base::Passed(&socket)));
|
| }
|
|
|
| class HttpRequest {
|
| @@ -81,7 +83,9 @@ class HttpRequest {
|
| int result,
|
| scoped_ptr<net::StreamSocket> socket) {
|
| if (result != net::OK) {
|
| - callback.Run(result, "", make_scoped_ptr<net::StreamSocket>(nullptr));
|
| + callback.Run(
|
| + result, std::string(), std::string(),
|
| + make_scoped_ptr<net::StreamSocket>(nullptr));
|
| return;
|
| }
|
| new HttpRequest(socket.Pass(), request, callback);
|
| @@ -93,7 +97,8 @@ class HttpRequest {
|
| const CommandCallback& callback)
|
| : socket_(socket.Pass()),
|
| command_callback_(callback),
|
| - body_pos_(0) {
|
| + expected_size_(-1),
|
| + header_size_(0) {
|
| SendRequest(request);
|
| }
|
|
|
| @@ -102,7 +107,8 @@ class HttpRequest {
|
| const HttpUpgradeCallback& callback)
|
| : socket_(socket.Pass()),
|
| http_upgrade_callback_(callback),
|
| - body_pos_(0) {
|
| + expected_size_(-1),
|
| + header_size_(0) {
|
| SendRequest(request);
|
| }
|
|
|
| @@ -142,22 +148,18 @@ class HttpRequest {
|
| void ReadResponse(int result) {
|
| if (!CheckNetResultOrDie(result))
|
| return;
|
| - scoped_refptr<net::IOBuffer> response_buffer =
|
| - new net::IOBuffer(kBufferSize);
|
| +
|
| + response_buffer_ = new net::IOBuffer(kBufferSize);
|
|
|
| result = socket_->Read(
|
| - response_buffer.get(),
|
| + response_buffer_.get(),
|
| kBufferSize,
|
| - base::Bind(&HttpRequest::OnResponseData, base::Unretained(this),
|
| - response_buffer,
|
| - -1));
|
| + base::Bind(&HttpRequest::OnResponseData, base::Unretained(this)));
|
| if (result != net::ERR_IO_PENDING)
|
| - OnResponseData(response_buffer, -1, result);
|
| + OnResponseData(result);
|
| }
|
|
|
| - void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer,
|
| - int bytes_total,
|
| - int result) {
|
| + void OnResponseData(int result) {
|
| if (!CheckNetResultOrDie(result))
|
| return;
|
| if (result == 0) {
|
| @@ -165,9 +167,10 @@ class HttpRequest {
|
| return;
|
| }
|
|
|
| - response_ += std::string(response_buffer->data(), result);
|
| - int expected_length = 0;
|
| - if (bytes_total < 0) {
|
| + response_.append(response_buffer_->data(), result);
|
| + if (expected_size_ < 0) {
|
| + int expected_length = 0;
|
| +
|
| // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header.
|
| std::string content_length = ExtractHeader("Content-Length:");
|
| if (!content_length.empty()) {
|
| @@ -177,33 +180,35 @@ class HttpRequest {
|
| }
|
| }
|
|
|
| - body_pos_ = response_.find("\r\n\r\n");
|
| - if (body_pos_ != std::string::npos) {
|
| - body_pos_ += 4;
|
| - bytes_total = body_pos_ + expected_length;
|
| + header_size_ = response_.find("\r\n\r\n");
|
| + if (header_size_ != std::string::npos) {
|
| + header_size_ += 4;
|
| + expected_size_ = header_size_ + expected_length;
|
| }
|
| }
|
|
|
| - if (bytes_total == static_cast<int>(response_.length())) {
|
| + // WebSocket handshake doesn't contain the Content-Length. For this case,
|
| + // |expected_size_| is set to the size of the header (handshake).
|
| + // Some WebSocket frames can be already received into |response_|.
|
| + if (static_cast<int>(response_.length()) >= expected_size_) {
|
| + const std::string& body = response_.substr(header_size_);
|
| if (!command_callback_.is_null()) {
|
| - command_callback_.Run(net::OK, response_.substr(body_pos_));
|
| + command_callback_.Run(net::OK, body);
|
| } else {
|
| + // Pass the WebSocket frames (in |body|), too.
|
| http_upgrade_callback_.Run(net::OK,
|
| - ExtractHeader("Sec-WebSocket-Extensions:"), socket_.Pass());
|
| + ExtractHeader("Sec-WebSocket-Extensions:"), body, socket_.Pass());
|
| }
|
| delete this;
|
| return;
|
| }
|
|
|
| result = socket_->Read(
|
| - response_buffer.get(),
|
| + response_buffer_.get(),
|
| kBufferSize,
|
| - base::Bind(&HttpRequest::OnResponseData,
|
| - base::Unretained(this),
|
| - response_buffer,
|
| - bytes_total));
|
| + base::Bind(&HttpRequest::OnResponseData, base::Unretained(this)));
|
| if (result != net::ERR_IO_PENDING)
|
| - OnResponseData(response_buffer, bytes_total, result);
|
| + OnResponseData(result);
|
| }
|
|
|
| std::string ExtractHeader(const std::string& header) {
|
| @@ -228,7 +233,8 @@ class HttpRequest {
|
| command_callback_.Run(result, std::string());
|
| } else {
|
| http_upgrade_callback_.Run(
|
| - result, "", make_scoped_ptr<net::StreamSocket>(nullptr));
|
| + result, std::string(), std::string(),
|
| + make_scoped_ptr<net::StreamSocket>(nullptr));
|
| }
|
| delete this;
|
| return false;
|
| @@ -239,7 +245,17 @@ class HttpRequest {
|
| std::string response_;
|
| CommandCallback command_callback_;
|
| HttpUpgradeCallback http_upgrade_callback_;
|
| - size_t body_pos_;
|
| +
|
| + scoped_refptr<net::IOBuffer> response_buffer_;
|
| + // Initially -1. Once the end of the header is seen:
|
| + // - If the Content-Length header is included, this variable is set to the
|
| + // sum of the header size (including the last two CRLFs) and the value of
|
| + // the header.
|
| + // - Otherwise, this variable is set to the size of the header (including the
|
| + // last two CRLFs).
|
| + int expected_size_;
|
| + // Set to the size of the header part in |response_|.
|
| + size_t header_size_;
|
| };
|
|
|
| class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> {
|
|
|