• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
state()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