Home | History | Annotate | Download | only in websockets
      1 // Copyright (c) 2012 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 #ifndef NET_WEBSOCKETS_WEBSOCKET_JOB_H_
      6 #define NET_WEBSOCKETS_WEBSOCKET_JOB_H_
      7 
      8 #include <deque>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/memory/weak_ptr.h"
     13 #include "net/base/address_list.h"
     14 #include "net/base/completion_callback.h"
     15 #include "net/socket_stream/socket_stream_job.h"
     16 #include "net/spdy/spdy_header_block.h"
     17 #include "net/spdy/spdy_websocket_stream.h"
     18 
     19 class GURL;
     20 
     21 namespace net {
     22 
     23 class DrainableIOBuffer;
     24 class SSLInfo;
     25 class WebSocketHandshakeRequestHandler;
     26 class WebSocketHandshakeResponseHandler;
     27 
     28 // WebSocket protocol specific job on SocketStream.
     29 // It captures WebSocket handshake message and handles cookie operations.
     30 // Chrome security policy doesn't allow renderer process (except dev tools)
     31 // see HttpOnly cookies, so it injects cookie header in handshake request and
     32 // strips set-cookie headers in handshake response.
     33 // TODO(ukai): refactor websocket.cc to use this.
     34 class NET_EXPORT WebSocketJob
     35     : public SocketStreamJob,
     36       public SocketStream::Delegate,
     37       public SpdyWebSocketStream::Delegate {
     38  public:
     39   // This is state of WebSocket, not SocketStream.
     40   enum State {
     41     INITIALIZED = -1,
     42     CONNECTING = 0,
     43     OPEN = 1,
     44     CLOSING = 2,
     45     CLOSED = 3,
     46   };
     47 
     48   explicit WebSocketJob(SocketStream::Delegate* delegate);
     49 
     50   static void EnsureInit();
     51 
     52   State state() const { return state_; }
     53   virtual void Connect() OVERRIDE;
     54   virtual bool SendData(const char* data, int len) OVERRIDE;
     55   virtual void Close() OVERRIDE;
     56   virtual void RestartWithAuth(const AuthCredentials& credentials) OVERRIDE;
     57   virtual void DetachDelegate() OVERRIDE;
     58 
     59   // SocketStream::Delegate methods.
     60   virtual int OnStartOpenConnection(
     61       SocketStream* socket, const CompletionCallback& callback) OVERRIDE;
     62   virtual void OnConnected(SocketStream* socket,
     63                            int max_pending_send_allowed) OVERRIDE;
     64   virtual void OnSentData(SocketStream* socket, int amount_sent) OVERRIDE;
     65   virtual void OnReceivedData(SocketStream* socket,
     66                               const char* data,
     67                               int len) OVERRIDE;
     68   virtual void OnClose(SocketStream* socket) OVERRIDE;
     69   virtual void OnAuthRequired(
     70       SocketStream* socket, AuthChallengeInfo* auth_info) OVERRIDE;
     71   virtual void OnSSLCertificateError(SocketStream* socket,
     72                                      const SSLInfo& ssl_info,
     73                                      bool fatal) OVERRIDE;
     74   virtual void OnError(const SocketStream* socket, int error) OVERRIDE;
     75 
     76   // SpdyWebSocketStream::Delegate methods.
     77   virtual void OnCreatedSpdyStream(int status) OVERRIDE;
     78   virtual void OnSentSpdyHeaders() OVERRIDE;
     79   virtual void OnSpdyResponseHeadersUpdated(
     80       const SpdyHeaderBlock& response_headers) OVERRIDE;
     81   virtual void OnSentSpdyData(size_t bytes_sent) OVERRIDE;
     82   virtual void OnReceivedSpdyData(scoped_ptr<SpdyBuffer> buffer) OVERRIDE;
     83   virtual void OnCloseSpdyStream() OVERRIDE;
     84 
     85  private:
     86   friend class WebSocketThrottle;
     87   friend class WebSocketJobTest;
     88   virtual ~WebSocketJob();
     89 
     90   bool SendHandshakeRequest(const char* data, int len);
     91   void AddCookieHeaderAndSend();
     92   void LoadCookieCallback(const std::string& cookie);
     93 
     94   void OnSentHandshakeRequest(SocketStream* socket, int amount_sent);
     95   // Parses received data into handshake_response_. When finished receiving the
     96   // response, calls SaveCookiesAndNotifyHeadersComplete().
     97   void OnReceivedHandshakeResponse(
     98       SocketStream* socket, const char* data, int len);
     99   // Saves received cookies to the cookie store, and then notifies the
    100   // delegate_ of completion of handshake.
    101   void SaveCookiesAndNotifyHeadersComplete();
    102   void SaveNextCookie();
    103   void OnCookieSaved(bool cookie_status);
    104   // Clears variables for handling cookies, rebuilds handshake string excluding
    105   // cookies, and then pass the handshake string to delegate_.
    106   void NotifyHeadersComplete();
    107   void DoSendData();
    108 
    109   GURL GetURLForCookies() const;
    110 
    111   const AddressList& address_list() const;
    112   int TrySpdyStream();
    113   void SetWaiting();
    114   bool IsWaiting() const;
    115   void Wakeup();
    116   void RetryPendingIO();
    117   void CompleteIO(int result);
    118 
    119   bool SendDataInternal(const char* data, int length);
    120   void CloseInternal();
    121   void SendPending();
    122 
    123   SocketStream::Delegate* delegate_;
    124   State state_;
    125   bool waiting_;
    126   AddressList addresses_;
    127   CompletionCallback callback_;  // for throttling.
    128 
    129   scoped_ptr<WebSocketHandshakeRequestHandler> handshake_request_;
    130   scoped_ptr<WebSocketHandshakeResponseHandler> handshake_response_;
    131 
    132   bool started_to_send_handshake_request_;
    133   size_t handshake_request_sent_;
    134 
    135   std::vector<std::string> response_cookies_;
    136   size_t response_cookies_save_index_;
    137 
    138   std::deque<scoped_refptr<IOBufferWithSize> > send_buffer_queue_;
    139   scoped_refptr<DrainableIOBuffer> current_send_buffer_;
    140   std::vector<char> received_data_after_handshake_;
    141 
    142   int spdy_protocol_version_;
    143   scoped_ptr<SpdyWebSocketStream> spdy_websocket_stream_;
    144   std::string challenge_;
    145 
    146   bool save_next_cookie_running_;
    147   bool callback_pending_;
    148 
    149   base::WeakPtrFactory<WebSocketJob> weak_ptr_factory_;
    150   base::WeakPtrFactory<WebSocketJob> weak_ptr_factory_for_send_pending_;
    151 
    152   DISALLOW_COPY_AND_ASSIGN(WebSocketJob);
    153 };
    154 
    155 }  // namespace
    156 
    157 #endif  // NET_WEBSOCKETS_WEBSOCKET_JOB_H_
    158