Home | History | Annotate | Download | only in websockets
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // WebSocket protocol implementation in chromium.
      6 // It is intended to be used for live experiment of WebSocket connectivity
      7 // metrics.
      8 // Note that it is not used for WebKit's WebSocket communication.
      9 // See third_party/WebKit/Source/WebCore/websockets/ instead.
     10 
     11 #ifndef NET_WEBSOCKETS_WEBSOCKET_H_
     12 #define NET_WEBSOCKETS_WEBSOCKET_H_
     13 #pragma once
     14 
     15 #include <deque>
     16 #include <string>
     17 
     18 #include "base/memory/ref_counted.h"
     19 #include "base/memory/scoped_ptr.h"
     20 #include "googleurl/src/gurl.h"
     21 #include "net/base/io_buffer.h"
     22 #include "net/socket_stream/socket_stream.h"
     23 #include "net/url_request/url_request_context.h"
     24 
     25 class MessageLoop;
     26 
     27 namespace net {
     28 
     29 class ClientSocketFactory;
     30 class HostResolver;
     31 
     32 class WebSocket;
     33 class WebSocketHandshake;
     34 
     35 // Delegate methods will be called on the same message loop as
     36 // WebSocket is constructed.
     37 class WebSocketDelegate {
     38  public:
     39   virtual ~WebSocketDelegate() {}
     40 
     41   // Called when WebSocket connection has been established.
     42   virtual void OnOpen(WebSocket* socket) = 0;
     43 
     44   // Called when |msg| is received at |socket|.
     45   // |msg| should be in UTF-8.
     46   virtual void OnMessage(WebSocket* socket, const std::string& msg) = 0;
     47 
     48   // Called when WebSocket error has been detected.
     49   virtual void OnError(WebSocket* socket) {}
     50 
     51   // Called when |socket| is closed.
     52   virtual void OnClose(WebSocket* socket, bool was_clean) = 0;
     53 
     54   // Called when an error occured on |socket|.
     55   virtual void OnSocketError(const WebSocket* socket, int error) {}
     56 };
     57 
     58 class WebSocket : public base::RefCountedThreadSafe<WebSocket>,
     59                   public SocketStream::Delegate {
     60  public:
     61   enum State {
     62     INITIALIZED = -1,
     63     CONNECTING = 0,
     64     OPEN = 1,
     65     CLOSING = 2,
     66     CLOSED = 3,
     67   };
     68   enum ProtocolVersion {
     69     DEFAULT_VERSION = 0,
     70     DRAFT75 = 1,
     71   };
     72   class Request {
     73    public:
     74     Request(const GURL& url, const std::string protocol,
     75             const std::string origin, const std::string location,
     76             ProtocolVersion version,
     77             net::URLRequestContext* context)
     78         : url_(url),
     79           protocol_(protocol),
     80           origin_(origin),
     81           location_(location),
     82           version_(version),
     83           context_(context),
     84           host_resolver_(NULL),
     85           client_socket_factory_(NULL) {}
     86     ~Request() {}
     87 
     88     const GURL& url() const { return url_; }
     89     const std::string& protocol() const { return protocol_; }
     90     const std::string& origin() const { return origin_; }
     91     const std::string& location() const { return location_; }
     92     ProtocolVersion version() const { return version_; }
     93     net::URLRequestContext* context() const { return context_; }
     94 
     95     // Sets an alternative HostResolver. For testing purposes only.
     96     void SetHostResolver(HostResolver* host_resolver) {
     97       host_resolver_ = host_resolver;
     98     }
     99     HostResolver* host_resolver() const { return host_resolver_; }
    100 
    101     // Sets an alternative ClientSocketFactory.  Doesn't take ownership of
    102     // |factory|.  For testing purposes only.
    103     void SetClientSocketFactory(ClientSocketFactory* factory) {
    104       client_socket_factory_ = factory;
    105     }
    106     ClientSocketFactory* client_socket_factory() const {
    107       return client_socket_factory_;
    108     }
    109 
    110    private:
    111     GURL url_;
    112     std::string protocol_;
    113     std::string origin_;
    114     std::string location_;
    115     ProtocolVersion version_;
    116     scoped_refptr<net::URLRequestContext> context_;
    117 
    118     HostResolver* host_resolver_;
    119     ClientSocketFactory* client_socket_factory_;
    120 
    121     DISALLOW_COPY_AND_ASSIGN(Request);
    122   };
    123 
    124   // Constructs new WebSocket.
    125   // It takes ownership of |req|.
    126   // |delegate| must be alive while this object is alive.
    127   WebSocket(Request* req, WebSocketDelegate* delegate);
    128 
    129   const Request* request() const { return request_.get(); }
    130   WebSocketDelegate* delegate() const { return delegate_; }
    131 
    132   State ready_state() const { return ready_state_; }
    133 
    134   // Connects new WebSocket.
    135   void Connect();
    136 
    137   // Sends |msg| on the WebSocket connection.
    138   // |msg| should be in UTF-8.
    139   void Send(const std::string& msg);
    140 
    141   // Closes the WebSocket connection.
    142   void Close();
    143 
    144   // Detach delegate.  Call before delegate is deleted.
    145   // Once delegate is detached, close the WebSocket connection and never call
    146   // delegate back.
    147   void DetachDelegate();
    148 
    149   // SocketStream::Delegate methods.
    150   // Called on IO thread.
    151   virtual void OnConnected(SocketStream* socket_stream,
    152                            int max_pending_send_allowed);
    153   virtual void OnSentData(SocketStream* socket_stream, int amount_sent);
    154   virtual void OnReceivedData(SocketStream* socket_stream,
    155                               const char* data, int len);
    156   virtual void OnClose(SocketStream* socket);
    157   virtual void OnError(const SocketStream* socket, int error);
    158 
    159  private:
    160   typedef std::deque< scoped_refptr<IOBufferWithSize> > PendingDataQueue;
    161 
    162   friend class WebSocketTest;
    163 
    164   friend class base::RefCountedThreadSafe<WebSocket>;
    165   virtual ~WebSocket();
    166 
    167   // Sends pending data in |current_write_buf_| and/or |pending_write_bufs_|.
    168   void SendPending();
    169 
    170   // Handles received data.
    171   void DoReceivedData();
    172 
    173   // Processes frame data in |current_read_buf_|.
    174   void ProcessFrameData();
    175 
    176   // Adds |len| bytes of |data| to |current_read_buf_|.
    177   void AddToReadBuffer(const char* data, int len);
    178 
    179   // Skips |len| bytes in |current_read_buf_|.
    180   void SkipReadBuffer(int len);
    181 
    182   void StartClosingHandshake();
    183   void DoForceCloseConnection();
    184   void FailConnection();
    185   // Handles closed connection.
    186   void DoClose();
    187 
    188   // Handles socket error report.
    189   void DoSocketError(int error);
    190 
    191   State ready_state_;
    192   scoped_ptr<Request> request_;
    193   scoped_ptr<WebSocketHandshake> handshake_;
    194   WebSocketDelegate* delegate_;
    195   MessageLoop* origin_loop_;
    196 
    197   scoped_refptr<SocketStream> socket_stream_;
    198   int max_pending_send_allowed_;
    199 
    200   // [0..offset) is received data from |socket_stream_|.
    201   // [0..read_consumed_len_) is already processed.
    202   // [read_consumed_len_..offset) is unprocessed data.
    203   // [offset..capacity) is free space.
    204   scoped_refptr<GrowableIOBuffer> current_read_buf_;
    205   int read_consumed_len_;
    206 
    207   // Drainable IOBuffer on the front of |pending_write_bufs_|.
    208   // [0..offset) is already sent to |socket_stream_|.
    209   // [offset..size) is being sent to |socket_stream_|, waiting OnSentData.
    210   scoped_refptr<DrainableIOBuffer> current_write_buf_;
    211 
    212   // Deque of IOBuffers in pending.
    213   // Front IOBuffer is being sent via |current_write_buf_|.
    214   PendingDataQueue pending_write_bufs_;
    215 
    216   // True when the 0xFF frame with length 0x00 is received.
    217   bool server_closing_handshake_;
    218   // True when trying to send 0xFF and 0x00 bytes.
    219   bool client_closing_handshake_;
    220   // True when send 0xFF and 0x00 bytes.
    221   bool closing_handshake_started_;
    222   // Task to close the connection after closing handshake has started and
    223   // |closing_handshake_timeout_|.
    224   CancelableTask* force_close_task_;
    225   int64 closing_handshake_timeout_;
    226 
    227   DISALLOW_COPY_AND_ASSIGN(WebSocket);
    228 };
    229 
    230 }  // namespace net
    231 
    232 #endif  // NET_WEBSOCKETS_WEBSOCKET_H_
    233