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 |