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