Chromium Code Reviews| 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 |