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: ~WebSocketDelegate()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. OnError(WebSocket * socket)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|. OnSocketError(const WebSocket * socket,int error)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: Request(const GURL & url,const std::string protocol,const std::string origin,const std::string location,ProtocolVersion version,net::URLRequestContext * context)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) {} ~Request()86 ~Request() {} 87 url()88 const GURL& url() const { return url_; } protocol()89 const std::string& protocol() const { return protocol_; } origin()90 const std::string& origin() const { return origin_; } location()91 const std::string& location() const { return location_; } version()92 ProtocolVersion version() const { return version_; } context()93 net::URLRequestContext* context() const { return context_; } 94 95 // Sets an alternative HostResolver. For testing purposes only. SetHostResolver(HostResolver * host_resolver)96 void SetHostResolver(HostResolver* host_resolver) { 97 host_resolver_ = host_resolver; 98 } host_resolver()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. SetClientSocketFactory(ClientSocketFactory * factory)103 void SetClientSocketFactory(ClientSocketFactory* factory) { 104 client_socket_factory_ = factory; 105 } client_socket_factory()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 request()129 const Request* request() const { return request_.get(); } delegate()130 WebSocketDelegate* delegate() const { return delegate_; } 131 ready_state()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