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 #ifndef EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ | 5 #ifndef EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ |
6 #define EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ | 6 #define EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "extensions/browser/api/socket/passthrough.h" | |
10 #include "extensions/browser/api/socket/socket.h" | 11 #include "extensions/browser/api/socket/socket.h" |
11 | 12 |
12 // This looks like it should be forward-declarable, but it does some tricky | 13 // This looks like it should be forward-declarable, but it does some tricky |
13 // moves that make it easier to just include it. | 14 // moves that make it easier to just include it. |
14 #include "net/socket/tcp_client_socket.h" | 15 #include "net/socket/tcp_client_socket.h" |
15 #include "net/socket/tcp_server_socket.h" | 16 #include "net/socket/tcp_server_socket.h" |
16 | 17 |
17 namespace net { | 18 namespace net { |
18 class Socket; | 19 class Socket; |
19 } | 20 } |
20 | 21 |
21 namespace extensions { | 22 namespace extensions { |
23 typedef base::Callback<void(void)> PauseCompletionCallback; | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
nit: please use a type alias instead of typedef no
| |
24 | |
25 // A wrapper around an existing TCPClientSocket with an internal read buffer | |
26 // to support immediate pausing. If this socket is paused while it still has | |
27 // a pending Read() on its wrapped socket, this socket will buffer the data | |
28 // returned. Further invocations of BufferingStreamSocket::Read() will | |
29 // first return all data from the internal buffer, before causing Read()s on | |
30 // the underlying TCP socket. Other than the buffering Read() behavior, | |
31 // BufferingStreamSocket acts identically to the net::TCPClientSocket that | |
32 // it wraps. | |
33 class SocketPauseBuffer { | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
This class should be in its own header and cc file
| |
34 public: | |
35 typedef base::Callback< | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
nit: type alias
| |
36 int(net::IOBuffer*, int, const net::CompletionCallback&)> | |
37 DownstreamReadCallback; | |
38 | |
39 // Pass in the Read() method of the underlying socket that needs pausing | |
40 // added to it. | |
41 explicit SocketPauseBuffer( | |
42 const DownstreamReadCallback& downstream_read_callback); | |
43 ~SocketPauseBuffer(); | |
44 | |
45 // Return from any pending Read() immediately, invoking the callback. | |
46 // BufferingStreamSocket will then buffer data received from any pending | |
47 // Read() that it may have invoked on the underlying socket. Subsequent | |
48 // Read() calls will have their callbacks posted immediately with data from | |
49 // the buffer until it is drained. When there is no buffered data, Read() | |
50 // acts exactly as net::TCPClientSocket::Read() until there is another | |
51 // invocation to Pause(). Returns true unless DisableBuffering() has been | |
52 // called. | |
53 bool Pause(); | |
54 | |
55 // Turn into a pure pass-through object, with no internal buffer and no | |
56 // ability to Pause() successfully. Any pending Read() invocation is | |
57 // unaffected, preserving its internal buffer until that Read() completes. | |
58 void DisableBuffering(); | |
59 | |
60 // This Read() can return early when pausing via Pause(). It will return | |
61 // (via callback) ERR_ABORTED. Without interference from Pause(), Read() | |
62 // acts identically to net::TCPClientSocket::Read(). | |
63 int Read(net::IOBuffer* buffer, | |
64 int buf_len, | |
65 const net::CompletionCallback& callback); | |
66 | |
67 private: | |
68 // Callback passed to downstream socket's Read(). | |
69 void ReadComplete(int count); | |
70 | |
71 // Buffer state printer. | |
72 std::string StatusDescription(); | |
73 | |
74 // 'Buffered' in the diagram below. | |
75 int BufferedDataCount() const; | |
76 | |
77 // Records that |num_incoming_bytes| has been added to the buffered amount. | |
78 void CreditIncomingData(int num_incoming_bytes); | |
79 | |
80 // Copies data from downstream_read_buffer_ to |dest|, and marks that data | |
81 // as having been returned upstream. | |
82 void ReturnDataInBuffer(net::IOBuffer* dest, int num_outgoing_bytes); | |
83 | |
84 // Shift the buffered data left, freeing buffer space of data that's | |
85 // already been given back upstream. | |
86 void FreeReturnedBufferSpace(); | |
87 | |
88 // Expands buffer if there isn't |num_bytes| of open space left. | |
89 void InsureBufferCanHold(int num_bytes); | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
nit: s/Insure/Ensure/
| |
90 | |
91 // Flush upstream state, usually after having returned a value without | |
92 // invoking the callback. | |
93 void ResetUpstreamState(); | |
94 | |
95 // Will also reset upstream state, and re-entrantly invoke the callback. | |
96 void InvokeCallback(int result); | |
97 | |
98 // Whether a downstream read has been issued with an expected invocation of | |
99 // ReadComplete(). | |
100 bool read_issued_; | |
101 | |
102 // Terminology: clients of BufferingStreamSocket are 'upstream', and | |
103 // BufferingStreamSocket is a client of downstream_socket_. | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
downstream_socket_ doesn't exist
| |
104 DownstreamReadCallback downstream_read_cb_; | |
105 // scoped_ptr<net::StreamSocket> downstream_socket_; | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
Remove this?
| |
106 | |
107 // A GrowableIOBuffer that BufferingStreamSocket::Read passes | |
108 // downstream. The offset state is used to store where in the buffer has | |
109 // already been stored, and where data from the next pending read will go. | |
110 // | |
111 // The buffer's state has this structure: | |
112 // 0 offset() | |
113 // +------------------+----------+--------------------------------------+ | |
114 // | already returned | buffered | open space for other downstream reads| | |
115 // +------------------+----------+--------------------------------------+ | |
116 // ^ upstream_data_returned_ | |
117 // | |
118 // These are represented as integers, counting bytes of buffer. The amount | |
119 // already returned is kept in upstream_data_returned_. The end of the | |
120 // buffered region is stored in downstream_read_buffer_->offset(). The | |
121 // remaining open space is the remaining |capacity| of | |
122 // downstream_read_buffer_. The buffer is compacted (e.g., already | |
123 // returned data flushed) before every downstream Read(). | |
124 scoped_refptr<net::GrowableIOBuffer> downstream_read_buffer_; | |
125 | |
126 // The amount of data in downstream_read_buffer_ that's already been | |
127 // returned upstream. | |
128 int upstream_data_returned_; | |
129 int upstream_read_buffer_offset_; | |
130 // A saved error code when a downstream read returns one, and there is no | |
131 // callback to pass it back to. | |
132 int prior_error_code_; | |
133 | |
134 // The callback, IOBuffer, and requested read amount passed into | |
135 // BufferingStreamSocket::Read. | |
136 net::CompletionCallback upstream_read_callback_; | |
137 scoped_refptr<net::IOBuffer> upstream_read_buffer_; | |
138 int upstream_read_request_size_; | |
139 bool buffering_disabled_; | |
140 }; | |
141 | |
142 // Passthrough to a StreamSocket, but integrates a SocketPauseBuffer for | |
143 // reading. | |
144 class BufferingStreamSocket : public Passthrough<net::StreamSocket> { | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:48
This class should have its own header and cc
| |
145 public: | |
146 explicit BufferingStreamSocket(scoped_ptr<net::StreamSocket> socket); | |
147 ~BufferingStreamSocket() override; | |
148 | |
149 bool Pause(); | |
150 void DisableBuffering(); | |
151 | |
152 // This Read() can return early when pausing via Pause(). It will return | |
153 // (via callback) ERR_ABORTED. Without interference from Pause(), Read() | |
154 // acts identically to net::TCPClientSocket::Read(). | |
155 int Read(net::IOBuffer* buffer, | |
156 int buf_len, | |
157 const net::CompletionCallback& callback) override; | |
158 | |
159 private: | |
160 SocketPauseBuffer pause_buffer_; | |
161 }; | |
162 | |
163 template <> | |
164 class DefaultInitializer<net::TCPClientSocket> : public net::TCPClientSocket { | |
165 public: | |
166 DefaultInitializer() | |
167 : net::TCPClientSocket(net::AddressList(), | |
168 nullptr, | |
169 net::NetLog::Source()) {} | |
170 }; | |
171 | |
172 // Passthrough to a TCPClientSocket, but integrates a SocketPauseBuffer for | |
173 // reading. | |
174 class BufferingTCPClientSocket : public Passthrough<net::TCPClientSocket> { | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
This class should have its own header and cc
| |
175 public: | |
176 explicit BufferingTCPClientSocket(scoped_ptr<net::TCPClientSocket> socket); | |
177 ~BufferingTCPClientSocket() override; | |
178 | |
179 bool Pause(); | |
180 void DisableBuffering(); | |
181 | |
182 // This Read() can return early when pausing via Pause(). It will return | |
183 // (via callback) ERR_ABORTED. Without interference from Pause(), Read() | |
184 // acts identically to net::TCPClientSocket::Read(). | |
185 int Read(net::IOBuffer* buffer, | |
186 int buf_len, | |
187 const net::CompletionCallback& callback) override; | |
188 | |
189 // Additional pass-through APIs for TCPClientSocket (vs Passthrough<>'s | |
190 // implementation of just StreamSocket. | |
191 bool SetKeepAlive(bool enable, int delay) override; | |
192 bool SetNoDelay(bool no_delay) override; | |
193 | |
194 private: | |
195 SocketPauseBuffer pause_buffer_; | |
196 }; | |
22 | 197 |
23 class TCPSocket : public Socket { | 198 class TCPSocket : public Socket { |
24 public: | 199 public: |
25 explicit TCPSocket(const std::string& owner_extension_id); | 200 explicit TCPSocket(const std::string& owner_extension_id); |
26 TCPSocket(net::TCPClientSocket* tcp_client_socket, | 201 TCPSocket(net::TCPClientSocket* tcp_client_socket, |
27 const std::string& owner_extension_id, | 202 const std::string& owner_extension_id, |
28 bool is_connected = false); | 203 bool is_connected = false); |
29 | 204 |
30 ~TCPSocket() override; | 205 ~TCPSocket() override; |
31 | 206 |
(...skipping 30 matching lines...) Expand all Loading... | |
62 static TCPSocket* CreateSocketForTesting( | 237 static TCPSocket* CreateSocketForTesting( |
63 net::TCPClientSocket* tcp_client_socket, | 238 net::TCPClientSocket* tcp_client_socket, |
64 const std::string& owner_extension_id, | 239 const std::string& owner_extension_id, |
65 bool is_connected = false); | 240 bool is_connected = false); |
66 static TCPSocket* CreateServerSocketForTesting( | 241 static TCPSocket* CreateServerSocketForTesting( |
67 net::TCPServerSocket* tcp_server_socket, | 242 net::TCPServerSocket* tcp_server_socket, |
68 const std::string& owner_extension_id); | 243 const std::string& owner_extension_id); |
69 | 244 |
70 // Returns NULL if GetSocketType() isn't TYPE_TCP or if the connection | 245 // Returns NULL if GetSocketType() isn't TYPE_TCP or if the connection |
71 // wasn't set up via Connect() (vs Listen()/Accept()). | 246 // wasn't set up via Connect() (vs Listen()/Accept()). |
72 net::TCPClientSocket* ClientStream(); | 247 virtual BufferingTCPClientSocket* ClientStream(); |
73 | 248 |
74 // Whether a Read() has been issued, that hasn't come back yet. | 249 // Whether a Read() has been issued, that hasn't come back yet. |
75 bool HasPendingRead() const; | 250 bool HasPendingRead() const; |
76 | 251 |
77 protected: | 252 protected: |
78 int WriteImpl(net::IOBuffer* io_buffer, | 253 int WriteImpl(net::IOBuffer* io_buffer, |
79 int io_buffer_size, | 254 int io_buffer_size, |
80 const net::CompletionCallback& callback) override; | 255 const net::CompletionCallback& callback) override; |
81 | 256 |
82 private: | 257 private: |
83 void RefreshConnectionStatus(); | 258 void RefreshConnectionStatus(); |
84 void OnConnectComplete(int result); | 259 void OnConnectComplete(int result); |
85 void OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, int result); | 260 void OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, int result); |
86 void OnAccept(int result); | 261 void OnAccept(int result); |
87 | 262 |
88 TCPSocket(net::TCPServerSocket* tcp_server_socket, | 263 TCPSocket(net::TCPServerSocket* tcp_server_socket, |
89 const std::string& owner_extension_id); | 264 const std::string& owner_extension_id); |
90 | 265 |
91 scoped_ptr<net::TCPClientSocket> socket_; | 266 scoped_ptr<BufferingTCPClientSocket> socket_; |
92 scoped_ptr<net::TCPServerSocket> server_socket_; | 267 scoped_ptr<net::TCPServerSocket> server_socket_; |
93 | 268 |
94 enum SocketMode { UNKNOWN = 0, CLIENT, SERVER, }; | 269 enum SocketMode { UNKNOWN = 0, CLIENT, SERVER, }; |
95 SocketMode socket_mode_; | 270 SocketMode socket_mode_; |
96 | 271 |
97 CompletionCallback connect_callback_; | 272 CompletionCallback connect_callback_; |
98 | 273 |
99 ReadCompletionCallback read_callback_; | 274 ReadCompletionCallback read_callback_; |
100 | 275 |
101 scoped_ptr<net::StreamSocket> accept_socket_; | 276 scoped_ptr<net::StreamSocket> accept_socket_; |
102 AcceptCompletionCallback accept_callback_; | 277 AcceptCompletionCallback accept_callback_; |
103 }; | 278 }; |
104 | 279 |
105 // TCP Socket instances from the "sockets.tcp" namespace. These are regular | 280 // TCP Socket instances from the "sockets.tcp" namespace. These are regular |
106 // socket objects with additional properties related to the behavior defined in | 281 // socket objects with additional properties related to the behavior defined in |
107 // the "sockets.tcp" namespace. | 282 // the "sockets.tcp" namespace. |
108 class ResumableTCPSocket : public TCPSocket { | 283 class ResumableTCPSocket : public TCPSocket { |
109 public: | 284 public: |
110 explicit ResumableTCPSocket(const std::string& owner_extension_id); | 285 explicit ResumableTCPSocket(const std::string& owner_extension_id); |
111 explicit ResumableTCPSocket(net::TCPClientSocket* tcp_client_socket, | 286 explicit ResumableTCPSocket(net::TCPClientSocket* tcp_client_socket, |
112 const std::string& owner_extension_id, | 287 const std::string& owner_extension_id, |
113 bool is_connected); | 288 bool is_connected); |
114 | 289 |
290 ~ResumableTCPSocket() override; | |
291 | |
115 // Overriden from ApiResource | 292 // Overriden from ApiResource |
116 bool IsPersistent() const override; | 293 bool IsPersistent() const override; |
117 | 294 |
118 const std::string& name() const { return name_; } | 295 const std::string& name() const { return name_; } |
119 void set_name(const std::string& name) { name_ = name; } | 296 void set_name(const std::string& name) { name_ = name; } |
120 | 297 |
121 bool persistent() const { return persistent_; } | 298 bool persistent() const { return persistent_; } |
122 void set_persistent(bool persistent) { persistent_ = persistent; } | 299 void set_persistent(bool persistent) { persistent_ = persistent; } |
123 | 300 |
124 int buffer_size() const { return buffer_size_; } | 301 int buffer_size() const { return buffer_size_; } |
125 void set_buffer_size(int buffer_size) { buffer_size_ = buffer_size; } | 302 void set_buffer_size(int buffer_size) { buffer_size_ = buffer_size; } |
126 | 303 |
127 bool paused() const { return paused_; } | 304 bool paused() const { return paused_; } |
128 void set_paused(bool paused) { paused_ = paused; } | 305 void set_paused(bool paused) { paused_ = paused; } |
129 | 306 |
307 void set_api_pause_complete_callback( | |
308 const PauseCompletionCallback& callback) { | |
309 pause_callback_ = callback; | |
310 } | |
311 | |
312 // Tell this socket that it's pause has actually finished, and it can | |
313 // invoke pause callback. | |
314 void ApiPauseComplete(); | |
Ken Rockot(use gerrit already)
2015/12/15 17:17:49
nit: How about NotifyPauseComplete?
| |
315 | |
130 private: | 316 private: |
131 friend class ApiResourceManager<ResumableTCPSocket>; | 317 friend class ApiResourceManager<ResumableTCPSocket>; |
132 static const char* service_name() { return "ResumableTCPSocketManager"; } | 318 static const char* service_name() { return "ResumableTCPSocketManager"; } |
133 | 319 |
134 // Application-defined string - see sockets_tcp.idl. | 320 // Application-defined string - see sockets_tcp.idl. |
135 std::string name_; | 321 std::string name_; |
136 // Flag indicating whether the socket is left open when the application is | 322 // Flag indicating whether the socket is left open when the application is |
137 // suspended - see sockets_tcp.idl. | 323 // suspended - see sockets_tcp.idl. |
138 bool persistent_; | 324 bool persistent_; |
139 // The size of the buffer used to receive data - see sockets_tcp.idl. | 325 // The size of the buffer used to receive data - see sockets_tcp.idl. |
140 int buffer_size_; | 326 int buffer_size_; |
141 // Flag indicating whether a connected socket blocks its peer from sending | 327 // Flag indicating whether a connected socket blocks its peer from sending |
142 // more data - see sockets_tcp.idl. | 328 // more data - see sockets_tcp.idl. |
143 bool paused_; | 329 bool paused_; |
330 // An optional callback to save and invoke from ResumableTCPServerSocket. | |
331 PauseCompletionCallback pause_callback_; | |
144 }; | 332 }; |
145 | 333 |
146 // TCP Socket instances from the "sockets.tcpServer" namespace. These are | 334 // TCP Socket instances from the "sockets.tcpServer" namespace. These are |
147 // regular socket objects with additional properties related to the behavior | 335 // regular socket objects with additional properties related to the behavior |
148 // defined in the "sockets.tcpServer" namespace. | 336 // defined in the "sockets.tcpServer" namespace. |
149 class ResumableTCPServerSocket : public TCPSocket { | 337 class ResumableTCPServerSocket : public TCPSocket { |
150 public: | 338 public: |
151 explicit ResumableTCPServerSocket(const std::string& owner_extension_id); | 339 explicit ResumableTCPServerSocket(const std::string& owner_extension_id); |
152 | 340 |
153 // Overriden from ApiResource | 341 // Overriden from ApiResource |
(...skipping 20 matching lines...) Expand all Loading... | |
174 // suspended - see sockets_tcp_server.idl. | 362 // suspended - see sockets_tcp_server.idl. |
175 bool persistent_; | 363 bool persistent_; |
176 // Flag indicating whether a connected socket blocks its peer from sending | 364 // Flag indicating whether a connected socket blocks its peer from sending |
177 // more data - see sockets_tcp_server.idl. | 365 // more data - see sockets_tcp_server.idl. |
178 bool paused_; | 366 bool paused_; |
179 }; | 367 }; |
180 | 368 |
181 } // namespace extensions | 369 } // namespace extensions |
182 | 370 |
183 #endif // EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ | 371 #endif // EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ |
OLD | NEW |