diff options
author | ukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-09 05:04:14 +0000 |
---|---|---|
committer | ukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-09 05:04:14 +0000 |
commit | aef03130359ef824153b4ed088622460bbccdb0f (patch) | |
tree | 49a2282c1dd5bdd20e9b186701a9206429c00ec3 /net/socket_stream/socket_stream.h | |
parent | 18b8d7c19768972e78211a05f0bbd680403533ae (diff) | |
download | chromium_src-aef03130359ef824153b4ed088622460bbccdb0f.zip chromium_src-aef03130359ef824153b4ed088622460bbccdb0f.tar.gz chromium_src-aef03130359ef824153b4ed088622460bbccdb0f.tar.bz2 |
Add net/socket_stream.
This is used for WebSocket protocol.
BUG=12497
TEST=none
Review URL: http://codereview.chromium.org/243077
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28526 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket_stream/socket_stream.h')
-rw-r--r-- | net/socket_stream/socket_stream.h | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/net/socket_stream/socket_stream.h b/net/socket_stream/socket_stream.h new file mode 100644 index 0000000..13f8680 --- /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> { + 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_ |