| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/devtools/tethering_handler.h" | 5 #include "content/browser/devtools/tethering_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "content/browser/devtools/devtools_http_handler_impl.h" | 11 #include "content/browser/devtools/devtools_http_handler_impl.h" |
| 12 #include "content/browser/devtools/devtools_protocol_constants.h" | 12 #include "content/browser/devtools/devtools_protocol_constants.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/devtools_http_handler_delegate.h" | 14 #include "content/public/browser/devtools_http_handler_delegate.h" |
| 15 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
| 16 #include "net/base/ip_endpoint.h" | 16 #include "net/base/ip_endpoint.h" |
| 17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 18 #include "net/base/net_log.h" | 18 #include "net/base/net_log.h" |
| 19 #include "net/socket/stream_listen_socket.h" | 19 #include "net/socket/server_socket.h" |
| 20 #include "net/socket/stream_socket.h" | 20 #include "net/socket/stream_socket.h" |
| 21 #include "net/socket/tcp_server_socket.h" | 21 #include "net/socket/tcp_server_socket.h" |
| 22 | 22 |
| 23 namespace content { | 23 namespace content { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 const char kLocalhost[] = "127.0.0.1"; | 27 const char kLocalhost[] = "127.0.0.1"; |
| 28 | 28 |
| 29 const int kListenBacklog = 5; | 29 const int kListenBacklog = 5; |
| 30 const int kBufferSize = 16 * 1024; | 30 const int kBufferSize = 16 * 1024; |
| 31 | 31 |
| 32 const int kMinTetheringPort = 1024; | 32 const int kMinTetheringPort = 1024; |
| 33 const int kMaxTetheringPort = 32767; | 33 const int kMaxTetheringPort = 32767; |
| 34 | 34 |
| 35 class SocketPump : public net::StreamListenSocket::Delegate { | 35 class SocketPump { |
| 36 public: | 36 public: |
| 37 SocketPump(DevToolsHttpHandlerDelegate* delegate, | 37 SocketPump(DevToolsHttpHandlerDelegate* delegate, |
| 38 net::StreamSocket* client_socket) | 38 net::StreamSocket* client_socket) |
| 39 : client_socket_(client_socket), | 39 : client_socket_(client_socket), |
| 40 delegate_(delegate), | 40 delegate_(delegate), |
| 41 wire_buffer_size_(0), | 41 pending_writes_(0), |
| 42 pending_destruction_(false) { | 42 pending_destruction_(false) { |
| 43 } | 43 } |
| 44 | 44 |
| 45 std::string Init() { | 45 std::string Init() { |
| 46 std::string channel_name; | 46 std::string channel_name; |
| 47 server_socket_ = delegate_->CreateSocketForTethering(this, &channel_name); | 47 server_socket_ = delegate_->CreateSocketForTethering(&channel_name); |
| 48 if (!server_socket_.get() || channel_name.empty()) | 48 if (!server_socket_.get() || channel_name.empty()) |
| 49 SelfDestruct(); | 49 SelfDestruct(); |
| 50 |
| 51 int result = server_socket_->Accept( |
| 52 &accepted_socket_, |
| 53 base::Bind(&SocketPump::OnAccepted, base::Unretained(this))); |
| 54 if (result != net::ERR_IO_PENDING) |
| 55 OnAccepted(result); |
| 50 return channel_name; | 56 return channel_name; |
| 51 } | 57 } |
| 52 | 58 |
| 53 ~SocketPump() override {} | 59 private: |
| 60 void OnAccepted(int result) { |
| 61 if (result < 0) { |
| 62 SelfDestruct(); |
| 63 return; |
| 64 } |
| 54 | 65 |
| 55 private: | 66 ++pending_writes_; // avoid SelfDestruct in first Pump |
| 56 void DidAccept(net::StreamListenSocket* server, | 67 Pump(client_socket_.get(), accepted_socket_.get()); |
| 57 scoped_ptr<net::StreamListenSocket> socket) override { | 68 --pending_writes_; |
| 58 if (accepted_socket_.get()) | 69 if (pending_destruction_) { |
| 59 return; | 70 SelfDestruct(); |
| 60 | 71 } else { |
| 61 buffer_ = new net::IOBuffer(kBufferSize); | 72 Pump(accepted_socket_.get(), client_socket_.get()); |
| 62 wire_buffer_ = new net::GrowableIOBuffer(); | 73 } |
| 63 wire_buffer_->SetCapacity(kBufferSize); | |
| 64 | |
| 65 accepted_socket_ = socket.Pass(); | |
| 66 int result = client_socket_->Read( | |
| 67 buffer_.get(), | |
| 68 kBufferSize, | |
| 69 base::Bind(&SocketPump::OnClientRead, base::Unretained(this))); | |
| 70 if (result != net::ERR_IO_PENDING) | |
| 71 OnClientRead(result); | |
| 72 } | 74 } |
| 73 | 75 |
| 74 void DidRead(net::StreamListenSocket* socket, | 76 void Pump(net::StreamSocket* from, net::StreamSocket* to) { |
| 75 const char* data, | 77 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize); |
| 76 int len) override { | 78 int result = from->Read( |
| 77 int old_size = wire_buffer_size_; | 79 buffer.get(), |
| 78 wire_buffer_size_ += len; | 80 kBufferSize, |
| 79 while (wire_buffer_->capacity() < wire_buffer_size_) | 81 base::Bind( |
| 80 wire_buffer_->SetCapacity(wire_buffer_->capacity() * 2); | 82 &SocketPump::OnRead, base::Unretained(this), from, to, buffer)); |
| 81 memcpy(wire_buffer_->StartOfBuffer() + old_size, data, len); | 83 if (result != net::ERR_IO_PENDING) |
| 82 if (old_size != wire_buffer_->offset()) | 84 OnRead(from, to, buffer, result); |
| 83 return; | |
| 84 OnClientWrite(0); | |
| 85 } | 85 } |
| 86 | 86 |
| 87 void DidClose(net::StreamListenSocket* socket) override { SelfDestruct(); } | 87 void OnRead(net::StreamSocket* from, |
| 88 | 88 net::StreamSocket* to, |
| 89 void OnClientRead(int result) { | 89 scoped_refptr<net::IOBuffer> buffer, |
| 90 int result) { |
| 90 if (result <= 0) { | 91 if (result <= 0) { |
| 91 SelfDestruct(); | 92 SelfDestruct(); |
| 92 return; | 93 return; |
| 93 } | 94 } |
| 94 | 95 |
| 95 accepted_socket_->Send(buffer_->data(), result); | 96 int total = result; |
| 96 result = client_socket_->Read( | 97 scoped_refptr<net::DrainableIOBuffer> drainable = |
| 97 buffer_.get(), | 98 new net::DrainableIOBuffer(buffer.get(), total); |
| 98 kBufferSize, | 99 |
| 99 base::Bind(&SocketPump::OnClientRead, base::Unretained(this))); | 100 ++pending_writes_; |
| 101 result = to->Write(drainable.get(), |
| 102 total, |
| 103 base::Bind(&SocketPump::OnWritten, |
| 104 base::Unretained(this), |
| 105 drainable, |
| 106 from, |
| 107 to)); |
| 100 if (result != net::ERR_IO_PENDING) | 108 if (result != net::ERR_IO_PENDING) |
| 101 OnClientRead(result); | 109 OnWritten(drainable, from, to, result); |
| 102 } | 110 } |
| 103 | 111 |
| 104 void OnClientWrite(int result) { | 112 void OnWritten(scoped_refptr<net::DrainableIOBuffer> drainable, |
| 113 net::StreamSocket* from, |
| 114 net::StreamSocket* to, |
| 115 int result) { |
| 116 --pending_writes_; |
| 105 if (result < 0) { | 117 if (result < 0) { |
| 106 SelfDestruct(); | 118 SelfDestruct(); |
| 107 return; | 119 return; |
| 108 } | 120 } |
| 109 | 121 |
| 110 wire_buffer_->set_offset(wire_buffer_->offset() + result); | 122 drainable->DidConsume(result); |
| 111 | 123 if (drainable->BytesRemaining() > 0) { |
| 112 int remaining = wire_buffer_size_ - wire_buffer_->offset(); | 124 ++pending_writes_; |
| 113 if (remaining == 0) { | 125 result = to->Write(drainable.get(), |
| 114 if (pending_destruction_) | 126 drainable->BytesRemaining(), |
| 115 SelfDestruct(); | 127 base::Bind(&SocketPump::OnWritten, |
| 128 base::Unretained(this), |
| 129 drainable, |
| 130 from, |
| 131 to)); |
| 132 if (result != net::ERR_IO_PENDING) |
| 133 OnWritten(drainable, from, to, result); |
| 116 return; | 134 return; |
| 117 } | 135 } |
| 118 | 136 |
| 119 | 137 if (pending_destruction_) { |
| 120 if (remaining > kBufferSize) | 138 SelfDestruct(); |
| 121 remaining = kBufferSize; | 139 return; |
| 122 | |
| 123 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(remaining); | |
| 124 memcpy(buffer->data(), wire_buffer_->data(), remaining); | |
| 125 result = client_socket_->Write( | |
| 126 buffer.get(), | |
| 127 remaining, | |
| 128 base::Bind(&SocketPump::OnClientWrite, base::Unretained(this))); | |
| 129 | |
| 130 // Shrink buffer | |
| 131 int offset = wire_buffer_->offset(); | |
| 132 if (offset > kBufferSize) { | |
| 133 memcpy(wire_buffer_->StartOfBuffer(), wire_buffer_->data(), | |
| 134 wire_buffer_size_ - offset); | |
| 135 wire_buffer_size_ -= offset; | |
| 136 wire_buffer_->set_offset(0); | |
| 137 } | 140 } |
| 138 | 141 Pump(from, to); |
| 139 if (result != net::ERR_IO_PENDING) | |
| 140 OnClientWrite(result); | |
| 141 return; | |
| 142 } | 142 } |
| 143 | 143 |
| 144 void SelfDestruct() { | 144 void SelfDestruct() { |
| 145 if (wire_buffer_.get() && wire_buffer_->offset() != wire_buffer_size_) { | 145 if (pending_writes_ > 0) { |
| 146 pending_destruction_ = true; | 146 pending_destruction_ = true; |
| 147 return; | 147 return; |
| 148 } | 148 } |
| 149 delete this; | 149 delete this; |
| 150 } | 150 } |
| 151 | 151 |
| 152 |
| 152 private: | 153 private: |
| 153 scoped_ptr<net::StreamSocket> client_socket_; | 154 scoped_ptr<net::StreamSocket> client_socket_; |
| 154 scoped_ptr<net::StreamListenSocket> server_socket_; | 155 scoped_ptr<net::ServerSocket> server_socket_; |
| 155 scoped_ptr<net::StreamListenSocket> accepted_socket_; | 156 scoped_ptr<net::StreamSocket> accepted_socket_; |
| 156 scoped_refptr<net::IOBuffer> buffer_; | |
| 157 scoped_refptr<net::GrowableIOBuffer> wire_buffer_; | |
| 158 DevToolsHttpHandlerDelegate* delegate_; | 157 DevToolsHttpHandlerDelegate* delegate_; |
| 159 int wire_buffer_size_; | 158 int pending_writes_; |
| 160 bool pending_destruction_; | 159 bool pending_destruction_; |
| 161 }; | 160 }; |
| 162 | 161 |
| 163 static int GetPort(scoped_refptr<DevToolsProtocol::Command> command, | 162 static int GetPort(scoped_refptr<DevToolsProtocol::Command> command, |
| 164 const std::string& paramName) { | 163 const std::string& paramName) { |
| 165 base::DictionaryValue* params = command->params(); | 164 base::DictionaryValue* params = command->params(); |
| 166 int port = 0; | 165 int port = 0; |
| 167 if (!params || | 166 if (!params || |
| 168 !params->GetInteger(paramName, &port) || | 167 !params->GetInteger(paramName, &port) || |
| 169 port < kMinTetheringPort || port > kMaxTetheringPort) | 168 port < kMinTetheringPort || port > kMaxTetheringPort) |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 SendAsyncResponse(command->SuccessResponse(nullptr)); | 431 SendAsyncResponse(command->SuccessResponse(nullptr)); |
| 433 } | 432 } |
| 434 | 433 |
| 435 void TetheringHandler::SendInternalError( | 434 void TetheringHandler::SendInternalError( |
| 436 scoped_refptr<DevToolsProtocol::Command> command, | 435 scoped_refptr<DevToolsProtocol::Command> command, |
| 437 const std::string& message) { | 436 const std::string& message) { |
| 438 SendAsyncResponse(command->InternalErrorResponse(message)); | 437 SendAsyncResponse(command->InternalErrorResponse(message)); |
| 439 } | 438 } |
| 440 | 439 |
| 441 } // namespace content | 440 } // namespace content |
| OLD | NEW |