Index: net/socket_stream/socket_stream.h |
diff --git a/net/socket_stream/socket_stream.h b/net/socket_stream/socket_stream.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..13f868009cc5346009847a4563f6923712c91e80 |
--- /dev/null |
+++ b/net/socket_stream/socket_stream.h |
@@ -0,0 +1,254 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef NET_SOCKET_STREAM_SOCKET_STREAM_H_ |
+#define NET_SOCKET_STREAM_SOCKET_STREAM_H_ |
+ |
+#include <deque> |
+#include <string> |
+#include <vector> |
+ |
+#include "base/linked_ptr.h" |
+#include "base/ref_counted.h" |
+#include "base/scoped_ptr.h" |
+#include "base/task.h" |
+#include "net/base/address_list.h" |
+#include "net/base/completion_callback.h" |
+#include "net/base/io_buffer.h" |
+#include "net/proxy/proxy_service.h" |
+#include "net/socket/tcp_client_socket.h" |
+#include "net/url_request/url_request_context.h" |
+ |
+namespace net { |
+ |
+class ClientSocketFactory; |
+class HostResolver; |
+class SSLConfigService; |
+class SingleRequestHostResolver; |
+ |
+class SocketStream : public base::RefCountedThreadSafe<SocketStream> { |
wtc
2009/10/22 23:33:18
I forgot to email you this suggestion: I believe t
|
+ public: |
+ // Derive from this class and add your own data members to associate extra |
+ // information with a SocketStream. Use GetUserData(key) and |
+ // SetUserData(key, data). |
+ class UserData { |
+ public: |
+ UserData() {} |
+ virtual ~UserData() {} |
+ }; |
+ |
+ class Delegate { |
+ public: |
+ virtual ~Delegate() {} |
+ |
+ // Called when socket stream has been connected. The socket stream accepts |
+ // at most |max_pending_send_allowed| so that a client of the socket stream |
+ // should keep track of how much it has pending and shouldn't go over |
+ // |max_pending_send_allowed| bytes. |
+ virtual void OnConnected(SocketStream* socket, |
+ int max_pending_send_allowed) = 0; |
+ |
+ // Called when |amount_sent| bytes of data are sent. |
+ virtual void OnSentData(SocketStream* socket, |
+ int amount_sent) = 0; |
+ |
+ // Called when |len| bytes of |data| are received. |
+ virtual void OnReceivedData(SocketStream* socket, |
+ const char* data, int len) = 0; |
+ |
+ // Called when the socket stream has been closed. |
+ virtual void OnClose(SocketStream* socket) = 0; |
+ }; |
+ |
+ SocketStream(const GURL& url, Delegate* delegate); |
+ |
+ // The user data allows the clients to associate data with this job. |
+ // Multiple user data values can be stored under different keys. |
+ // This job will TAKE OWNERSHIP of the given data pointer, and will |
+ // delete the object if it is changed or the job is destroyed. |
+ UserData* GetUserData(const void* key) const; |
+ void SetUserData(const void* key, UserData* data); |
+ |
+ const GURL& url() const { return url_; } |
+ Delegate* delegate() const { return delegate_; } |
+ int max_pending_send_allowed() const { return max_pending_send_allowed_; } |
+ |
+ URLRequestContext* context() const { return context_.get(); } |
+ void set_context(URLRequestContext* context); |
+ |
+ // Opens the connection on the IO thread. |
+ // Once the connection is established, calls delegate's OnConnected. |
+ void Connect(); |
+ |
+ // Requests to send |len| bytes of |data| on the connection. |
+ // Returns true if |data| is buffered in the job. |
+ // Returns false if size of buffered data would exceeds |
+ // |max_pending_send_allowed_| and |data| is not sent at all. |
+ bool SendData(const char* data, int len); |
+ |
+ // Requests to close the connection. |
+ // Once the connection is closed, calls delegate's OnClose. |
+ void Close(); |
+ |
+ // Detach delegate. Call before delegate is deleted. |
+ // Once delegate is detached, close the socket stream and never call delegate |
+ // back. |
+ void DetachDelegate(); |
+ |
+ // Sets an alternative HostResolver. For testing purposes only. |
+ void SetHostResolver(HostResolver* host_resolver); |
+ |
+ // Sets an alternative ClientSocketFactory. Doesn't take ownership of |
+ // |factory|. For testing purposes only. |
+ void SetClientSocketFactory(ClientSocketFactory* factory); |
+ |
+ private: |
+ class RequestHeaders : public IOBuffer { |
+ public: |
+ RequestHeaders() : IOBuffer() {} |
+ ~RequestHeaders() { data_ = NULL; } |
+ |
+ void SetDataOffset(size_t offset) { |
+ data_ = const_cast<char*>(headers_.data()) + offset; |
+ } |
+ std::string headers_; |
+ }; |
+ |
+ class ResponseHeaders : public IOBuffer { |
+ public: |
+ ResponseHeaders() : IOBuffer() {} |
+ ~ResponseHeaders() { data_ = NULL; } |
+ |
+ void SetDataOffset(size_t offset) { data_ = headers_.get() + offset; } |
+ char* headers() const { return headers_.get(); } |
+ void Reset() { headers_.reset(); } |
+ void Realloc(size_t new_size); |
+ |
+ private: |
+ scoped_ptr_malloc<char> headers_; |
+ }; |
+ |
+ enum State { |
+ STATE_NONE, |
+ STATE_RESOLVE_PROXY, |
+ STATE_RESOLVE_PROXY_COMPLETE, |
+ STATE_RESOLVE_HOST, |
+ STATE_RESOLVE_HOST_COMPLETE, |
+ STATE_TCP_CONNECT, |
+ STATE_TCP_CONNECT_COMPLETE, |
+ STATE_WRITE_TUNNEL_HEADERS, |
+ STATE_WRITE_TUNNEL_HEADERS_COMPLETE, |
+ STATE_READ_TUNNEL_HEADERS, |
+ STATE_READ_TUNNEL_HEADERS_COMPLETE, |
+ STATE_SOCKS_CONNECT, |
+ STATE_SOCKS_CONNECT_COMPLETE, |
+ STATE_SSL_CONNECT, |
+ STATE_SSL_CONNECT_COMPLETE, |
+ STATE_CONNECTION_ESTABLISHED, |
+ STATE_READ_WRITE |
+ }; |
+ |
+ enum ProxyMode { |
+ kDirectConnection, // If using a direct connection |
+ kTunnelProxy, // If using a tunnel (CONNECT method as HTTPS) |
+ kSOCKSProxy, // If using a SOCKS proxy |
+ }; |
+ |
+ typedef std::deque< scoped_refptr<IOBufferWithSize> > PendingDataQueue; |
+ friend class base::RefCountedThreadSafe<SocketStream>; |
+ ~SocketStream(); |
+ |
+ // Finish the job. Once finished, calls OnClose of delegate, and no more |
+ // notifications will be sent to delegate. |
+ void Finish(); |
+ |
+ void DidEstablishConnection(); |
+ void DidReceiveData(int result); |
+ void DidSendData(int result); |
+ |
+ void OnIOCompleted(int result); |
+ void OnReadCompleted(int result); |
+ void OnWriteCompleted(int result); |
+ |
+ int DoLoop(int result); |
+ |
+ int DoResolveProxy(); |
+ int DoResolveProxyComplete(int result); |
+ int DoResolveHost(); |
+ int DoResolveHostComplete(int result); |
+ int DoTcpConnect(); |
+ int DoTcpConnectComplete(int result); |
+ int DoWriteTunnelHeaders(); |
+ int DoWriteTunnelHeadersComplete(int result); |
+ int DoReadTunnelHeaders(); |
+ int DoReadTunnelHeadersComplete(int result); |
+ int DoSOCKSConnect(); |
+ int DoSOCKSConnectComplete(int result); |
+ int DoSSLConnect(); |
+ int DoSSLConnectComplete(int result); |
+ int DoReadWrite(int result); |
+ |
+ int HandleCertificateError(int result); |
+ |
+ bool is_secure() const; |
+ SSLConfigService* ssl_config_service() const; |
+ ProxyService* proxy_service() const; |
+ |
+ GURL url_; |
+ Delegate* delegate_; |
+ int max_pending_send_allowed_; |
+ scoped_refptr<URLRequestContext> context_; |
+ |
+ typedef std::map<const void*, linked_ptr<UserData> > UserDataMap; |
+ UserDataMap user_data_; |
+ |
+ State next_state_; |
+ scoped_refptr<HostResolver> host_resolver_; |
+ ClientSocketFactory* factory_; |
+ |
+ ProxyMode proxy_mode_; |
+ |
+ ProxyService::PacRequest* pac_request_; |
+ ProxyInfo proxy_info_; |
+ |
+ scoped_refptr<RequestHeaders> tunnel_request_headers_; |
+ size_t tunnel_request_headers_bytes_sent_; |
+ scoped_refptr<ResponseHeaders> tunnel_response_headers_; |
+ int tunnel_response_headers_capacity_; |
+ int tunnel_response_headers_len_; |
+ |
+ // Use the same number as HttpNetworkTransaction::kMaxHeaderBufSize. |
+ enum { kMaxTunnelResponseHeadersSize = 32768 }; // 32 kilobytes. |
+ |
+ scoped_ptr<SingleRequestHostResolver> resolver_; |
+ AddressList addresses_; |
+ scoped_ptr<ClientSocket> socket_; |
+ |
+ SSLConfig ssl_config_; |
+ |
+ CompletionCallbackImpl<SocketStream> io_callback_; |
+ CompletionCallbackImpl<SocketStream> read_callback_; |
+ CompletionCallbackImpl<SocketStream> write_callback_; |
+ |
+ scoped_refptr<IOBuffer> read_buf_; |
+ int read_buf_size_; |
+ |
+ // Total amount of buffer (|write_buf_size_| - |write_buf_offset_| + |
+ // sum of size of |pending_write_bufs_|) should not exceed |
+ // |max_pending_send_allowed_|. |
+ // |write_buf_| holds requested data and |current_write_buf_| is used |
+ // for Write operation, that is, |current_write_buf_| is |
+ // |write_buf_| + |write_buf_offset_|. |
+ scoped_refptr<IOBuffer> write_buf_; |
+ scoped_refptr<ReusedIOBuffer> current_write_buf_; |
+ int write_buf_offset_; |
+ int write_buf_size_; |
+ PendingDataQueue pending_write_bufs_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SocketStream); |
+}; |
+ |
+} // namespace net |
+ |
+#endif // NET_SOCKET_STREAM_SOCKET_STREAM_H_ |