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 |