summaryrefslogtreecommitdiffstats
path: root/net/socket_stream/socket_stream.h
diff options
context:
space:
mode:
authorukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-09 05:04:14 +0000
committerukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-09 05:04:14 +0000
commitaef03130359ef824153b4ed088622460bbccdb0f (patch)
tree49a2282c1dd5bdd20e9b186701a9206429c00ec3 /net/socket_stream/socket_stream.h
parent18b8d7c19768972e78211a05f0bbd680403533ae (diff)
downloadchromium_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.h254
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_