15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SOCKET_STREAM_SOCKET_STREAM_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SOCKET_STREAM_SOCKET_STREAM_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/privacy_mode.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/cookies/cookie_store.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_service.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_config_service.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AuthChallengeInfo;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CertVerifier;
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ChannelIDService;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSocketFactory;
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class ClientSocketHandle;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CookieOptions;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HostResolver;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpAuthController;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SSLInfo;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SingleRequestHostResolver;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SocketStreamMetrics;
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class TransportSecurityState;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLRequestContext;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SocketStream is used to implement Web Sockets.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It provides plain full-duplex stream with proxy and SSL support.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For proxy authentication, only basic mechanisum is supported.  It will try
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authentication identity for proxy URL first.  If server requires proxy
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authentication, it will try authentication identity for realm that server
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT SocketStream
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCountedThreadSafe<SocketStream> {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Derive from this class and add your own data members to associate extra
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // information with a SocketStream.  Use GetUserData(key) and
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SetUserData(key, data).
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class UserData {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UserData() {}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~UserData() {}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class NET_EXPORT Delegate {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual int OnStartOpenConnection(SocketStream* socket,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const CompletionCallback& callback);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Called when a socket stream has been connected.  The socket stream is
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // allowed to buffer pending send data at most |max_pending_send_allowed|
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // bytes.  A client of the socket stream should keep track of how much
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // pending send data it has and must not call SendData() if the pending
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // data goes over |max_pending_send_allowed| bytes.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnConnected(SocketStream* socket,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int max_pending_send_allowed) = 0;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when |amount_sent| bytes of data are sent.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnSentData(SocketStream* socket,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int amount_sent) = 0;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when |len| bytes of |data| are received.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnReceivedData(SocketStream* socket,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const char* data, int len) = 0;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when the socket stream has been closed.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnClose(SocketStream* socket) = 0;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when proxy authentication required.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The delegate should call RestartWithAuth() if credential for |auth_info|
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is found in password database, or call Close() to close the connection.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnAuthRequired(SocketStream* socket,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                AuthChallengeInfo* auth_info);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when using SSL and the server responds with a certificate with an
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // error. The delegate should call CancelBecauseOfCertError() or
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ContinueDespiteCertError() to resume connection handling.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnSSLCertificateError(SocketStream* socket,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const SSLInfo& ssl_info,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       bool fatal);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when an error occured.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is only for error reporting to the delegate.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |error| is net::Error.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnError(const SocketStream* socket, int error) {}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when reading cookies to allow the delegate to block access to the
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cookie.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool CanGetCookies(SocketStream* socket, const GURL& url);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called when a cookie is set to allow the delegate to block access to the
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cookie.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool CanSetCookie(SocketStream* request,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const GURL& url,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& cookie_line,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              CookieOptions* options);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Delegate() {}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SocketStream(const GURL& url, Delegate* delegate, URLRequestContext* context,
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               CookieStore* cookie_store);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The user data allows the clients to associate data with this job.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multiple user data values can be stored under different keys.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This job will TAKE OWNERSHIP of the given data pointer, and will
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delete the object if it is changed or the job is destroyed.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UserData* GetUserData(const void* key) const;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUserData(const void* key, UserData* data);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& url() const { return url_; }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_secure() const;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AddressList& address_list() const { return addresses_; }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Delegate* delegate() const { return delegate_; }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_pending_send_allowed() const { return max_pending_send_allowed_; }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  URLRequestContext* context() { return context_; }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const SSLConfig& server_ssl_config() const { return server_ssl_config_; }
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PrivacyMode privacy_mode() const { return privacy_mode_; }
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void CheckPrivacyMode();
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog* net_log() { return &net_log_; }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Opens the connection on the IO thread.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once the connection is established, calls delegate's OnConnected.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Connect();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Buffers |data| of |len| bytes for send and returns true if successful.
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If size of buffered data exceeds |max_pending_send_allowed_|, sends no
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // data and returns false. |len| must be positive.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool SendData(const char* data, int len);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Requests to close the connection.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once the connection is closed, calls delegate's OnClose.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Close();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restarts with authentication info.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should be used for response of OnAuthRequired.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RestartWithAuth(const AuthCredentials& credentials);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Detach delegate.  Call before delegate is deleted.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once delegate is detached, close the socket stream and never call delegate
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // back.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DetachDelegate();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Detach the context.
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void DetachContext();
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProxyServer& proxy_server() const;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets an alternative ClientSocketFactory.  Doesn't take ownership of
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |factory|.  For testing purposes only.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetClientSocketFactory(ClientSocketFactory* factory);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancels the connection because of an error.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |error| is net::Error which represents the error.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelWithError(int error);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancels the connection because of receiving a certificate with an error.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelWithSSLError(const SSLInfo& ssl_info);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Continues to establish the connection in spite of an error. Usually this
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // case happens because users allow certificate with an error by manual
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // actions on alert dialog or browser cached such kinds of user actions.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueDespiteError();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CookieStore* cookie_store() const;
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<SocketStream>;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SocketStream();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Delegate* delegate_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(SocketStreamTest, IOPending);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(SocketStreamTest, SwitchAfterPending);
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(SocketStreamTest,
19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                           NullContextSocketStreamShouldNotCrash);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class WebSocketThrottleTest;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<const void*, linked_ptr<UserData> > UserDataMap;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::deque< scoped_refptr<IOBufferWithSize> > PendingDataQueue;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class RequestHeaders : public IOBuffer {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestHeaders() : IOBuffer() {}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetDataOffset(size_t offset) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_ = const_cast<char*>(headers_.data()) + offset;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string headers_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     virtual ~RequestHeaders();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ResponseHeaders : public IOBuffer {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResponseHeaders();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetDataOffset(size_t offset) { data_ = headers_.get() + offset; }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* headers() const { return headers_.get(); }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Reset() { headers_.reset(); }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Realloc(size_t new_size);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     virtual ~ResponseHeaders();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<char, base::FreeDeleter> headers_;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum State {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_NONE,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_BEFORE_CONNECT,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_BEFORE_CONNECT_COMPLETE,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_RESOLVE_PROXY,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_RESOLVE_PROXY_COMPLETE,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_RESOLVE_HOST,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_RESOLVE_HOST_COMPLETE,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_RESOLVE_PROTOCOL,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_RESOLVE_PROTOCOL_COMPLETE,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_TCP_CONNECT,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_TCP_CONNECT_COMPLETE,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_GENERATE_PROXY_AUTH_TOKEN,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_WRITE_TUNNEL_HEADERS,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_WRITE_TUNNEL_HEADERS_COMPLETE,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_READ_TUNNEL_HEADERS,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_READ_TUNNEL_HEADERS_COMPLETE,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SOCKS_CONNECT,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SOCKS_CONNECT_COMPLETE,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SECURE_PROXY_CONNECT,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SECURE_PROXY_CONNECT_COMPLETE,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SECURE_PROXY_HANDLE_CERT_ERROR,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SSL_CONNECT,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SSL_CONNECT_COMPLETE,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SSL_HANDLE_CERT_ERROR,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_SSL_HANDLE_CERT_ERROR_COMPLETE,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_READ_WRITE,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_AUTH_REQUIRED,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CLOSE,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ProxyMode {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kDirectConnection,  // If using a direct connection
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kTunnelProxy,  // If using a tunnel (CONNECT method as HTTPS)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSOCKSProxy,  // If using a SOCKS proxy
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the same number as HttpNetworkTransaction::kMaxHeaderBufSize.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum { kMaxTunnelResponseHeadersSize = 32768 };  // 32 kilobytes.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for WebSocketThrottleTest.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_addresses(const AddressList& addresses);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoClose();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finishes the job.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls OnError and OnClose of delegate, and no more
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications will be sent to delegate.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Finish(int result);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DidEstablishConnection();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DidReceiveData(int result);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Given the number of bytes sent,
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // - notifies the |delegate_| and |metrics_| of this event.
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // - drains sent data from |current_write_buf_|.
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // - if |current_write_buf_| has been fully sent, sets NULL to
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   |current_write_buf_| to get ready for next write.
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and then, returns OK.
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DidSendData(int result);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnIOCompleted(int result);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnReadCompleted(int result);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnWriteCompleted(int result);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoLoop(int result);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoBeforeConnect();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoBeforeConnectComplete(int result);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoResolveProxy();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoResolveProxyComplete(int result);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoResolveHost();
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoResolveHostComplete(int result);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoResolveProtocol(int result);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoResolveProtocolComplete(int result);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoTcpConnect(int result);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoTcpConnectComplete(int result);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoGenerateProxyAuthToken();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoGenerateProxyAuthTokenComplete(int result);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoWriteTunnelHeaders();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoWriteTunnelHeadersComplete(int result);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoReadTunnelHeaders();
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoReadTunnelHeadersComplete(int result);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSOCKSConnect();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSOCKSConnectComplete(int result);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSecureProxyConnect();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSecureProxyConnectComplete(int result);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSecureProxyHandleCertError(int result);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSecureProxyHandleCertErrorComplete(int result);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSSLConnect();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSSLConnectComplete(int result);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSSLHandleCertError(int result);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoSSLHandleCertErrorComplete(int result);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DoReadWrite(int result);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL ProxyAuthOrigin() const;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int HandleAuthChallenge(const HttpResponseHeaders* headers);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int HandleCertificateRequest(int result, SSLConfig* ssl_config);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoAuthRequired();
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoRestartWithAuth();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int HandleCertificateError(int result);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int AllowCertErrorForReconnection(SSLConfig* ssl_config);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns the sum of the size of buffers in |pending_write_bufs_|.
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t GetTotalSizeOfPendingWriteBufs() const;
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog net_log_;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The number of bytes allowed to be buffered in this object. If the size of
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // buffered data which is
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   current_write_buf_.BytesRemaining() +
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   sum of the size of buffers in |pending_write_bufs_|
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // exceeds this limit, SendData() fails.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_pending_send_allowed_;
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  URLRequestContext* context_;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UserDataMap user_data_;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State next_state_;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketFactory* factory_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyMode proxy_mode_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL proxy_url_;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacRequest* pac_request_;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo proxy_info_;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpAuthController> proxy_auth_controller_;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<RequestHeaders> tunnel_request_headers_;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t tunnel_request_headers_bytes_sent_;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ResponseHeaders> tunnel_response_headers_;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tunnel_response_headers_capacity_;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tunnel_response_headers_len_;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SingleRequestHostResolver> resolver_;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addresses_;
3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ClientSocketHandle> connection_;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLConfig server_ssl_config_;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLConfig proxy_ssl_config_;
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PrivacyMode privacy_mode_;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompletionCallback io_callback_;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBuffer> read_buf_;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int read_buf_size_;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Buffer to hold data to pass to socket_.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<DrainableIOBuffer> current_write_buf_;
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // True iff there's no error and this instance is waiting for completion of
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Write operation by socket_.
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool waiting_for_write_completion_;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingDataQueue pending_write_bufs_;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool closing_;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool server_closed_;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SocketStreamMetrics> metrics_;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cookie store to use for this socket stream.
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<CookieStore> cookie_store_;
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SocketStream);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_SOCKET_STREAM_SOCKET_STREAM_H_
405