OLD | NEW |
| (Empty) |
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 #include "net/websockets/websocket_job.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/bind_helpers.h" | |
12 #include "base/callback.h" | |
13 #include "base/memory/ref_counted.h" | |
14 #include "base/string_split.h" | |
15 #include "base/string_util.h" | |
16 #include "googleurl/src/gurl.h" | |
17 #include "net/base/completion_callback.h" | |
18 #include "net/base/cookie_store.h" | |
19 #include "net/base/cookie_store_test_helpers.h" | |
20 #include "net/base/mock_host_resolver.h" | |
21 #include "net/base/net_errors.h" | |
22 #include "net/base/ssl_config_service.h" | |
23 #include "net/base/sys_addrinfo.h" | |
24 #include "net/base/test_completion_callback.h" | |
25 #include "net/base/transport_security_state.h" | |
26 #include "net/http/http_transaction_factory.h" | |
27 #include "net/proxy/proxy_service.h" | |
28 #include "net/socket/socket_test_util.h" | |
29 #include "net/socket_stream/socket_stream.h" | |
30 #include "net/spdy/spdy_session.h" | |
31 #include "net/spdy/spdy_test_util.h" | |
32 #include "net/spdy/spdy_websocket_test_util.h" | |
33 #include "net/url_request/url_request_context.h" | |
34 #include "net/websockets/websocket_throttle.h" | |
35 #include "testing/gtest/include/gtest/gtest.h" | |
36 #include "testing/gmock/include/gmock/gmock.h" | |
37 #include "testing/platform_test.h" | |
38 | |
39 namespace { | |
40 | |
41 class MockSocketStream : public net::SocketStream { | |
42 public: | |
43 MockSocketStream(const GURL& url, net::SocketStream::Delegate* delegate) | |
44 : SocketStream(url, delegate) {} | |
45 virtual ~MockSocketStream() {} | |
46 | |
47 virtual void Connect() OVERRIDE {} | |
48 virtual bool SendData(const char* data, int len) OVERRIDE { | |
49 sent_data_ += std::string(data, len); | |
50 return true; | |
51 } | |
52 | |
53 virtual void Close() OVERRIDE {} | |
54 virtual void RestartWithAuth( | |
55 const net::AuthCredentials& credentials) OVERRIDE { | |
56 } | |
57 | |
58 virtual void DetachDelegate() OVERRIDE { | |
59 delegate_ = NULL; | |
60 } | |
61 | |
62 const std::string& sent_data() const { | |
63 return sent_data_; | |
64 } | |
65 | |
66 private: | |
67 std::string sent_data_; | |
68 }; | |
69 | |
70 class MockSocketStreamDelegate : public net::SocketStream::Delegate { | |
71 public: | |
72 MockSocketStreamDelegate() | |
73 : amount_sent_(0), allow_all_cookies_(true) {} | |
74 void set_allow_all_cookies(bool allow_all_cookies) { | |
75 allow_all_cookies_ = allow_all_cookies; | |
76 } | |
77 virtual ~MockSocketStreamDelegate() {} | |
78 | |
79 void SetOnStartOpenConnection(const base::Closure& callback) { | |
80 on_start_open_connection_ = callback; | |
81 } | |
82 void SetOnConnected(const base::Closure& callback) { | |
83 on_connected_ = callback; | |
84 } | |
85 void SetOnSentData(const base::Closure& callback) { | |
86 on_sent_data_ = callback; | |
87 } | |
88 void SetOnReceivedData(const base::Closure& callback) { | |
89 on_received_data_ = callback; | |
90 } | |
91 void SetOnClose(const base::Closure& callback) { | |
92 on_close_ = callback; | |
93 } | |
94 | |
95 virtual int OnStartOpenConnection(net::SocketStream* socket, | |
96 const net::CompletionCallback& callback) { | |
97 if (!on_start_open_connection_.is_null()) | |
98 on_start_open_connection_.Run(); | |
99 return net::OK; | |
100 } | |
101 virtual void OnConnected(net::SocketStream* socket, | |
102 int max_pending_send_allowed) { | |
103 if (!on_connected_.is_null()) | |
104 on_connected_.Run(); | |
105 } | |
106 virtual void OnSentData(net::SocketStream* socket, int amount_sent) { | |
107 amount_sent_ += amount_sent; | |
108 if (!on_sent_data_.is_null()) | |
109 on_sent_data_.Run(); | |
110 } | |
111 virtual void OnReceivedData(net::SocketStream* socket, | |
112 const char* data, int len) { | |
113 received_data_ += std::string(data, len); | |
114 if (!on_received_data_.is_null()) | |
115 on_received_data_.Run(); | |
116 } | |
117 virtual void OnClose(net::SocketStream* socket) { | |
118 if (!on_close_.is_null()) | |
119 on_close_.Run(); | |
120 } | |
121 virtual bool CanGetCookies(net::SocketStream* socket, const GURL& url) { | |
122 return allow_all_cookies_; | |
123 } | |
124 virtual bool CanSetCookie(net::SocketStream* request, | |
125 const GURL& url, | |
126 const std::string& cookie_line, | |
127 net::CookieOptions* options) { | |
128 return allow_all_cookies_; | |
129 } | |
130 | |
131 size_t amount_sent() const { return amount_sent_; } | |
132 const std::string& received_data() const { return received_data_; } | |
133 | |
134 private: | |
135 int amount_sent_; | |
136 bool allow_all_cookies_; | |
137 std::string received_data_; | |
138 base::Closure on_start_open_connection_; | |
139 base::Closure on_connected_; | |
140 base::Closure on_sent_data_; | |
141 base::Closure on_received_data_; | |
142 base::Closure on_close_; | |
143 }; | |
144 | |
145 class MockCookieStore : public net::CookieStore { | |
146 public: | |
147 struct Entry { | |
148 GURL url; | |
149 std::string cookie_line; | |
150 net::CookieOptions options; | |
151 }; | |
152 MockCookieStore() {} | |
153 | |
154 virtual bool SetCookieWithOptions(const GURL& url, | |
155 const std::string& cookie_line, | |
156 const net::CookieOptions& options) { | |
157 Entry entry; | |
158 entry.url = url; | |
159 entry.cookie_line = cookie_line; | |
160 entry.options = options; | |
161 entries_.push_back(entry); | |
162 return true; | |
163 } | |
164 | |
165 virtual void SetCookieWithOptionsAsync( | |
166 const GURL& url, | |
167 const std::string& cookie_line, | |
168 const net::CookieOptions& options, | |
169 const SetCookiesCallback& callback) { | |
170 bool result = SetCookieWithOptions(url, cookie_line, options); | |
171 if (!callback.is_null()) | |
172 callback.Run(result); | |
173 } | |
174 virtual std::string GetCookiesWithOptions( | |
175 const GURL& url, | |
176 const net::CookieOptions& options) { | |
177 std::string result; | |
178 for (size_t i = 0; i < entries_.size(); i++) { | |
179 Entry &entry = entries_[i]; | |
180 if (url == entry.url) { | |
181 if (!result.empty()) { | |
182 result += "; "; | |
183 } | |
184 result += entry.cookie_line; | |
185 } | |
186 } | |
187 return result; | |
188 } | |
189 virtual void GetCookiesWithOptionsAsync( | |
190 const GURL& url, | |
191 const net::CookieOptions& options, | |
192 const GetCookiesCallback& callback) { | |
193 if (!callback.is_null()) | |
194 callback.Run(GetCookiesWithOptions(url, options)); | |
195 } | |
196 virtual void GetCookiesWithInfo(const GURL& url, | |
197 const net::CookieOptions& options, | |
198 std::string* cookie_line, | |
199 std::vector<CookieInfo>* cookie_infos) { | |
200 ADD_FAILURE(); | |
201 } | |
202 virtual void GetCookiesWithInfoAsync( | |
203 const GURL& url, | |
204 const net::CookieOptions& options, | |
205 const GetCookieInfoCallback& callback) { | |
206 ADD_FAILURE(); | |
207 } | |
208 virtual void DeleteCookie(const GURL& url, | |
209 const std::string& cookie_name) { | |
210 ADD_FAILURE(); | |
211 } | |
212 virtual void DeleteCookieAsync(const GURL& url, | |
213 const std::string& cookie_name, | |
214 const base::Closure& callback) { | |
215 ADD_FAILURE(); | |
216 } | |
217 virtual void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, | |
218 const base::Time& delete_end, | |
219 const DeleteCallback& callback) { | |
220 ADD_FAILURE(); | |
221 } | |
222 | |
223 virtual net::CookieMonster* GetCookieMonster() { return NULL; } | |
224 | |
225 const std::vector<Entry>& entries() const { return entries_; } | |
226 | |
227 private: | |
228 friend class base::RefCountedThreadSafe<MockCookieStore>; | |
229 virtual ~MockCookieStore() {} | |
230 | |
231 std::vector<Entry> entries_; | |
232 }; | |
233 | |
234 class MockSSLConfigService : public net::SSLConfigService { | |
235 public: | |
236 virtual void GetSSLConfig(net::SSLConfig* config) {}; | |
237 }; | |
238 | |
239 class MockURLRequestContext : public net::URLRequestContext { | |
240 public: | |
241 explicit MockURLRequestContext(net::CookieStore* cookie_store) | |
242 : transport_security_state_(std::string()) { | |
243 set_cookie_store(cookie_store); | |
244 set_transport_security_state(&transport_security_state_); | |
245 net::TransportSecurityState::DomainState state; | |
246 state.expiry = base::Time::Now() + base::TimeDelta::FromSeconds(1000); | |
247 transport_security_state_.EnableHost("upgrademe.com", state); | |
248 } | |
249 | |
250 private: | |
251 friend class base::RefCountedThreadSafe<MockURLRequestContext>; | |
252 virtual ~MockURLRequestContext() {} | |
253 | |
254 net::TransportSecurityState transport_security_state_; | |
255 }; | |
256 | |
257 class MockHttpTransactionFactory : public net::HttpTransactionFactory { | |
258 public: | |
259 MockHttpTransactionFactory(net::OrderedSocketData* data) { | |
260 data_ = data; | |
261 net::MockConnect connect_data(net::SYNCHRONOUS, net::OK); | |
262 data_->set_connect_data(connect_data); | |
263 session_deps_.reset(new net::SpdySessionDependencies); | |
264 session_deps_->socket_factory->AddSocketDataProvider(data_); | |
265 http_session_ = | |
266 net::SpdySessionDependencies::SpdyCreateSession(session_deps_.get()); | |
267 host_port_pair_.set_host("example.com"); | |
268 host_port_pair_.set_port(80); | |
269 host_port_proxy_pair_.first = host_port_pair_; | |
270 host_port_proxy_pair_.second = net::ProxyServer::Direct(); | |
271 net::SpdySessionPool* spdy_session_pool = | |
272 http_session_->spdy_session_pool(); | |
273 DCHECK(spdy_session_pool); | |
274 EXPECT_FALSE(spdy_session_pool->HasSession(host_port_proxy_pair_)); | |
275 session_ = | |
276 spdy_session_pool->Get(host_port_proxy_pair_, net::BoundNetLog()); | |
277 EXPECT_TRUE(spdy_session_pool->HasSession(host_port_proxy_pair_)); | |
278 | |
279 transport_params_ = new net::TransportSocketParams(host_port_pair_, | |
280 net::MEDIUM, | |
281 false, | |
282 false); | |
283 net::ClientSocketHandle* connection = new net::ClientSocketHandle; | |
284 EXPECT_EQ(net::OK, | |
285 connection->Init(host_port_pair_.ToString(), transport_params_, | |
286 net::MEDIUM, net::CompletionCallback(), | |
287 http_session_->GetTransportSocketPool(), | |
288 net::BoundNetLog())); | |
289 EXPECT_EQ(net::OK, | |
290 session_->InitializeWithSocket(connection, false, net::OK)); | |
291 } | |
292 virtual int CreateTransaction(scoped_ptr<net::HttpTransaction>* trans) { | |
293 NOTREACHED(); | |
294 return net::ERR_UNEXPECTED; | |
295 } | |
296 virtual net::HttpCache* GetCache() { | |
297 NOTREACHED(); | |
298 return NULL; | |
299 } | |
300 virtual net::HttpNetworkSession* GetSession() { | |
301 return http_session_.get(); | |
302 } | |
303 private: | |
304 net::OrderedSocketData* data_; | |
305 scoped_ptr<net::SpdySessionDependencies> session_deps_; | |
306 scoped_refptr<net::HttpNetworkSession> http_session_; | |
307 scoped_refptr<net::TransportSocketParams> transport_params_; | |
308 scoped_refptr<net::SpdySession> session_; | |
309 net::HostPortPair host_port_pair_; | |
310 net::HostPortProxyPair host_port_proxy_pair_; | |
311 }; | |
312 } | |
313 | |
314 namespace net { | |
315 | |
316 class WebSocketJobTest : public PlatformTest { | |
317 public: | |
318 virtual void SetUp() { | |
319 spdy::SpdyFramer::set_enable_compression_default(false); | |
320 stream_type_ = STREAM_INVALID; | |
321 cookie_store_ = new MockCookieStore; | |
322 context_ = new MockURLRequestContext(cookie_store_.get()); | |
323 } | |
324 virtual void TearDown() { | |
325 cookie_store_ = NULL; | |
326 context_ = NULL; | |
327 websocket_ = NULL; | |
328 socket_ = NULL; | |
329 } | |
330 void DoSendRequest() { | |
331 EXPECT_TRUE(websocket_->SendData(kHandshakeRequestWithoutCookie, | |
332 kHandshakeRequestWithoutCookieLength)); | |
333 } | |
334 void DoSendData() { | |
335 if (received_data().size() == kHandshakeResponseWithoutCookieLength) | |
336 websocket_->SendData(kDataHello, kDataHelloLength); | |
337 } | |
338 void DoSync() { | |
339 sync_test_callback_.callback().Run(OK); | |
340 } | |
341 int WaitForResult() { | |
342 return sync_test_callback_.WaitForResult(); | |
343 } | |
344 protected: | |
345 enum StreamType { | |
346 STREAM_INVALID, | |
347 STREAM_MOCK_SOCKET, | |
348 STREAM_SOCKET, | |
349 STREAM_SPDY_WEBSOCKET, | |
350 }; | |
351 enum ThrottlingOption { | |
352 THROTTLING_OFF, | |
353 THROTTLING_ON, | |
354 }; | |
355 enum SpdyOption { | |
356 SPDY_OFF, | |
357 SPDY_ON, | |
358 }; | |
359 void InitWebSocketJob(const GURL& url, | |
360 MockSocketStreamDelegate* delegate, | |
361 StreamType stream_type) { | |
362 DCHECK_NE(STREAM_INVALID, stream_type); | |
363 stream_type_ = stream_type; | |
364 websocket_ = new WebSocketJob(delegate); | |
365 | |
366 if (stream_type == STREAM_MOCK_SOCKET) | |
367 socket_ = new MockSocketStream(url, websocket_.get()); | |
368 | |
369 if (stream_type == STREAM_SOCKET || stream_type == STREAM_SPDY_WEBSOCKET) { | |
370 if (stream_type == STREAM_SPDY_WEBSOCKET) { | |
371 http_factory_.reset(new MockHttpTransactionFactory(data_.get())); | |
372 context_->set_http_transaction_factory(http_factory_.get()); | |
373 } | |
374 | |
375 ssl_config_service_ = new MockSSLConfigService(); | |
376 context_->set_ssl_config_service(ssl_config_service_); | |
377 proxy_service_.reset(net::ProxyService::CreateDirect()); | |
378 context_->set_proxy_service(proxy_service_.get()); | |
379 host_resolver_.reset(new net::MockHostResolver); | |
380 context_->set_host_resolver(host_resolver_.get()); | |
381 | |
382 socket_ = new SocketStream(url, websocket_.get()); | |
383 socket_factory_.reset(new MockClientSocketFactory); | |
384 DCHECK(data_.get()); | |
385 socket_factory_->AddSocketDataProvider(data_.get()); | |
386 socket_->SetClientSocketFactory(socket_factory_.get()); | |
387 } | |
388 | |
389 websocket_->InitSocketStream(socket_.get()); | |
390 websocket_->set_context(context_.get()); | |
391 struct addrinfo addr; | |
392 memset(&addr, 0, sizeof(struct addrinfo)); | |
393 addr.ai_family = AF_INET; | |
394 addr.ai_addrlen = sizeof(struct sockaddr_in); | |
395 struct sockaddr_in sa_in; | |
396 memset(&sa_in, 0, sizeof(struct sockaddr_in)); | |
397 memcpy(&sa_in.sin_addr, "\x7f\0\0\1", 4); | |
398 addr.ai_addr = reinterpret_cast<sockaddr*>(&sa_in); | |
399 addr.ai_next = NULL; | |
400 websocket_->addresses_ = AddressList::CreateByCopying(&addr); | |
401 } | |
402 void SkipToConnecting() { | |
403 websocket_->state_ = WebSocketJob::CONNECTING; | |
404 WebSocketThrottle::GetInstance()->PutInQueue(websocket_); | |
405 } | |
406 WebSocketJob::State GetWebSocketJobState() { | |
407 return websocket_->state_; | |
408 } | |
409 void CloseWebSocketJob() { | |
410 if (websocket_->socket_) { | |
411 websocket_->socket_->DetachDelegate(); | |
412 WebSocketThrottle::GetInstance()->RemoveFromQueue(websocket_); | |
413 } | |
414 websocket_->state_ = WebSocketJob::CLOSED; | |
415 websocket_->delegate_ = NULL; | |
416 websocket_->socket_ = NULL; | |
417 } | |
418 SocketStream* GetSocket(SocketStreamJob* job) { | |
419 return job->socket_.get(); | |
420 } | |
421 const std::string& sent_data() const { | |
422 DCHECK_EQ(STREAM_MOCK_SOCKET, stream_type_); | |
423 MockSocketStream* socket = | |
424 static_cast<MockSocketStream*>(socket_.get()); | |
425 DCHECK(socket); | |
426 return socket->sent_data(); | |
427 } | |
428 const std::string& received_data() const { | |
429 DCHECK_NE(STREAM_INVALID, stream_type_); | |
430 MockSocketStreamDelegate* delegate = | |
431 static_cast<MockSocketStreamDelegate*>(websocket_->delegate_); | |
432 DCHECK(delegate); | |
433 return delegate->received_data(); | |
434 } | |
435 | |
436 void TestSimpleHandshake(); | |
437 void TestSlowHandshake(); | |
438 void TestHandshakeWithCookie(); | |
439 void TestHandshakeWithCookieButNotAllowed(); | |
440 void TestHSTSUpgrade(); | |
441 void TestInvalidSendData(); | |
442 void TestConnectByWebSocket(ThrottlingOption throttling); | |
443 void TestConnectBySpdy(SpdyOption spdy, ThrottlingOption throttling); | |
444 | |
445 StreamType stream_type_; | |
446 scoped_refptr<MockCookieStore> cookie_store_; | |
447 scoped_refptr<MockURLRequestContext> context_; | |
448 scoped_refptr<WebSocketJob> websocket_; | |
449 scoped_refptr<SocketStream> socket_; | |
450 scoped_ptr<MockClientSocketFactory> socket_factory_; | |
451 scoped_ptr<OrderedSocketData> data_; | |
452 TestCompletionCallback sync_test_callback_; | |
453 scoped_refptr<MockSSLConfigService> ssl_config_service_; | |
454 scoped_ptr<net::ProxyService> proxy_service_; | |
455 scoped_ptr<net::MockHostResolver> host_resolver_; | |
456 scoped_ptr<MockHttpTransactionFactory> http_factory_; | |
457 | |
458 static const char kHandshakeRequestWithoutCookie[]; | |
459 static const char kHandshakeRequestWithCookie[]; | |
460 static const char kHandshakeRequestWithFilteredCookie[]; | |
461 static const char kHandshakeResponseWithoutCookie[]; | |
462 static const char kHandshakeResponseWithCookie[]; | |
463 static const char kDataHello[]; | |
464 static const char kDataWorld[]; | |
465 static const char* const kHandshakeRequestForSpdy[]; | |
466 static const char* const kHandshakeResponseForSpdy[]; | |
467 static const size_t kHandshakeRequestWithoutCookieLength; | |
468 static const size_t kHandshakeRequestWithCookieLength; | |
469 static const size_t kHandshakeRequestWithFilteredCookieLength; | |
470 static const size_t kHandshakeResponseWithoutCookieLength; | |
471 static const size_t kHandshakeResponseWithCookieLength; | |
472 static const size_t kDataHelloLength; | |
473 static const size_t kDataWorldLength; | |
474 }; | |
475 | |
476 const char WebSocketJobTest::kHandshakeRequestWithoutCookie[] = | |
477 "GET /demo HTTP/1.1\r\n" | |
478 "Host: example.com\r\n" | |
479 "Connection: Upgrade\r\n" | |
480 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" | |
481 "Sec-WebSocket-Protocol: sample\r\n" | |
482 "Upgrade: WebSocket\r\n" | |
483 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" | |
484 "Origin: http://example.com\r\n" | |
485 "\r\n" | |
486 "^n:ds[4U"; | |
487 | |
488 const char WebSocketJobTest::kHandshakeRequestWithCookie[] = | |
489 "GET /demo HTTP/1.1\r\n" | |
490 "Host: example.com\r\n" | |
491 "Connection: Upgrade\r\n" | |
492 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" | |
493 "Sec-WebSocket-Protocol: sample\r\n" | |
494 "Upgrade: WebSocket\r\n" | |
495 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" | |
496 "Origin: http://example.com\r\n" | |
497 "Cookie: WK-test=1\r\n" | |
498 "\r\n" | |
499 "^n:ds[4U"; | |
500 | |
501 const char WebSocketJobTest::kHandshakeRequestWithFilteredCookie[] = | |
502 "GET /demo HTTP/1.1\r\n" | |
503 "Host: example.com\r\n" | |
504 "Connection: Upgrade\r\n" | |
505 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" | |
506 "Sec-WebSocket-Protocol: sample\r\n" | |
507 "Upgrade: WebSocket\r\n" | |
508 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" | |
509 "Origin: http://example.com\r\n" | |
510 "Cookie: CR-test=1; CR-test-httponly=1\r\n" | |
511 "\r\n" | |
512 "^n:ds[4U"; | |
513 | |
514 const char WebSocketJobTest::kHandshakeResponseWithoutCookie[] = | |
515 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | |
516 "Upgrade: WebSocket\r\n" | |
517 "Connection: Upgrade\r\n" | |
518 "Sec-WebSocket-Origin: http://example.com\r\n" | |
519 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | |
520 "Sec-WebSocket-Protocol: sample\r\n" | |
521 "\r\n" | |
522 "8jKS'y:G*Co,Wxa-"; | |
523 | |
524 const char WebSocketJobTest::kHandshakeResponseWithCookie[] = | |
525 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | |
526 "Upgrade: WebSocket\r\n" | |
527 "Connection: Upgrade\r\n" | |
528 "Sec-WebSocket-Origin: http://example.com\r\n" | |
529 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | |
530 "Sec-WebSocket-Protocol: sample\r\n" | |
531 "Set-Cookie: CR-set-test=1\r\n" | |
532 "\r\n" | |
533 "8jKS'y:G*Co,Wxa-"; | |
534 | |
535 const char WebSocketJobTest::kDataHello[] = "Hello, "; | |
536 | |
537 const char WebSocketJobTest::kDataWorld[] = "World!\n"; | |
538 | |
539 // TODO(toyoshim): I should clarify which WebSocket headers for handshake must | |
540 // be exported to SPDY SYN_STREAM and SYN_REPLY. | |
541 // Because it depends on HyBi versions, just define it as follow for now. | |
542 const char* const WebSocketJobTest::kHandshakeRequestForSpdy[] = { | |
543 "host", "example.com", | |
544 "origin", "http://example.com", | |
545 "sec-websocket-protocol", "sample", | |
546 "url", "ws://example.com/demo" | |
547 }; | |
548 | |
549 const char* const WebSocketJobTest::kHandshakeResponseForSpdy[] = { | |
550 "sec-websocket-origin", "http://example.com", | |
551 "sec-websocket-location", "ws://example.com/demo", | |
552 "sec-websocket-protocol", "sample", | |
553 }; | |
554 | |
555 const size_t WebSocketJobTest::kHandshakeRequestWithoutCookieLength = | |
556 arraysize(kHandshakeRequestWithoutCookie) - 1; | |
557 const size_t WebSocketJobTest::kHandshakeRequestWithCookieLength = | |
558 arraysize(kHandshakeRequestWithCookie) - 1; | |
559 const size_t WebSocketJobTest::kHandshakeRequestWithFilteredCookieLength = | |
560 arraysize(kHandshakeRequestWithFilteredCookie) - 1; | |
561 const size_t WebSocketJobTest::kHandshakeResponseWithoutCookieLength = | |
562 arraysize(kHandshakeResponseWithoutCookie) - 1; | |
563 const size_t WebSocketJobTest::kHandshakeResponseWithCookieLength = | |
564 arraysize(kHandshakeResponseWithCookie) - 1; | |
565 const size_t WebSocketJobTest::kDataHelloLength = | |
566 arraysize(kDataHello) - 1; | |
567 const size_t WebSocketJobTest::kDataWorldLength = | |
568 arraysize(kDataWorld) - 1; | |
569 | |
570 void WebSocketJobTest::TestSimpleHandshake() { | |
571 GURL url("ws://example.com/demo"); | |
572 MockSocketStreamDelegate delegate; | |
573 InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET); | |
574 SkipToConnecting(); | |
575 | |
576 DoSendRequest(); | |
577 MessageLoop::current()->RunAllPending(); | |
578 EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data()); | |
579 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
580 websocket_->OnSentData(socket_.get(), | |
581 kHandshakeRequestWithoutCookieLength); | |
582 EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent()); | |
583 | |
584 websocket_->OnReceivedData(socket_.get(), | |
585 kHandshakeResponseWithoutCookie, | |
586 kHandshakeResponseWithoutCookieLength); | |
587 MessageLoop::current()->RunAllPending(); | |
588 EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data()); | |
589 EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState()); | |
590 CloseWebSocketJob(); | |
591 } | |
592 | |
593 void WebSocketJobTest::TestSlowHandshake() { | |
594 GURL url("ws://example.com/demo"); | |
595 MockSocketStreamDelegate delegate; | |
596 InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET); | |
597 SkipToConnecting(); | |
598 | |
599 DoSendRequest(); | |
600 // We assume request is sent in one data chunk (from WebKit) | |
601 // We don't support streaming request. | |
602 MessageLoop::current()->RunAllPending(); | |
603 EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data()); | |
604 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
605 websocket_->OnSentData(socket_.get(), | |
606 kHandshakeRequestWithoutCookieLength); | |
607 EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent()); | |
608 | |
609 std::vector<std::string> lines; | |
610 base::SplitString(kHandshakeResponseWithoutCookie, '\n', &lines); | |
611 for (size_t i = 0; i < lines.size() - 2; i++) { | |
612 std::string line = lines[i] + "\r\n"; | |
613 SCOPED_TRACE("Line: " + line); | |
614 websocket_->OnReceivedData(socket_, | |
615 line.c_str(), | |
616 line.size()); | |
617 MessageLoop::current()->RunAllPending(); | |
618 EXPECT_TRUE(delegate.received_data().empty()); | |
619 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
620 } | |
621 websocket_->OnReceivedData(socket_.get(), "\r\n", 2); | |
622 MessageLoop::current()->RunAllPending(); | |
623 EXPECT_TRUE(delegate.received_data().empty()); | |
624 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
625 websocket_->OnReceivedData(socket_.get(), "8jKS'y:G*Co,Wxa-", 16); | |
626 EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data()); | |
627 EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState()); | |
628 CloseWebSocketJob(); | |
629 } | |
630 | |
631 TEST_F(WebSocketJobTest, DelayedCookies) { | |
632 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
633 GURL url("ws://example.com/demo"); | |
634 GURL cookieUrl("http://example.com/demo"); | |
635 CookieOptions cookie_options; | |
636 scoped_refptr<DelayedCookieMonster> cookie_store = new DelayedCookieMonster(); | |
637 context_->set_cookie_store(cookie_store); | |
638 cookie_store->SetCookieWithOptionsAsync( | |
639 cookieUrl, "CR-test=1", cookie_options, | |
640 net::CookieMonster::SetCookiesCallback()); | |
641 cookie_options.set_include_httponly(); | |
642 cookie_store->SetCookieWithOptionsAsync( | |
643 cookieUrl, "CR-test-httponly=1", cookie_options, | |
644 net::CookieMonster::SetCookiesCallback()); | |
645 | |
646 MockSocketStreamDelegate delegate; | |
647 InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET); | |
648 SkipToConnecting(); | |
649 | |
650 bool sent = websocket_->SendData(kHandshakeRequestWithCookie, | |
651 kHandshakeRequestWithCookieLength); | |
652 EXPECT_TRUE(sent); | |
653 MessageLoop::current()->RunAllPending(); | |
654 EXPECT_EQ(kHandshakeRequestWithFilteredCookie, sent_data()); | |
655 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
656 websocket_->OnSentData(socket_, | |
657 kHandshakeRequestWithFilteredCookieLength); | |
658 EXPECT_EQ(kHandshakeRequestWithCookieLength, | |
659 delegate.amount_sent()); | |
660 | |
661 websocket_->OnReceivedData(socket_.get(), | |
662 kHandshakeResponseWithCookie, | |
663 kHandshakeResponseWithCookieLength); | |
664 MessageLoop::current()->RunAllPending(); | |
665 EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data()); | |
666 EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState()); | |
667 | |
668 CloseWebSocketJob(); | |
669 } | |
670 | |
671 void WebSocketJobTest::TestHandshakeWithCookie() { | |
672 GURL url("ws://example.com/demo"); | |
673 GURL cookieUrl("http://example.com/demo"); | |
674 CookieOptions cookie_options; | |
675 cookie_store_->SetCookieWithOptions( | |
676 cookieUrl, "CR-test=1", cookie_options); | |
677 cookie_options.set_include_httponly(); | |
678 cookie_store_->SetCookieWithOptions( | |
679 cookieUrl, "CR-test-httponly=1", cookie_options); | |
680 | |
681 MockSocketStreamDelegate delegate; | |
682 InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET); | |
683 SkipToConnecting(); | |
684 | |
685 bool sent = websocket_->SendData(kHandshakeRequestWithCookie, | |
686 kHandshakeRequestWithCookieLength); | |
687 EXPECT_TRUE(sent); | |
688 MessageLoop::current()->RunAllPending(); | |
689 EXPECT_EQ(kHandshakeRequestWithFilteredCookie, sent_data()); | |
690 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
691 websocket_->OnSentData(socket_, | |
692 kHandshakeRequestWithFilteredCookieLength); | |
693 EXPECT_EQ(kHandshakeRequestWithCookieLength, | |
694 delegate.amount_sent()); | |
695 | |
696 websocket_->OnReceivedData(socket_.get(), | |
697 kHandshakeResponseWithCookie, | |
698 kHandshakeResponseWithCookieLength); | |
699 MessageLoop::current()->RunAllPending(); | |
700 EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data()); | |
701 EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState()); | |
702 | |
703 EXPECT_EQ(3U, cookie_store_->entries().size()); | |
704 EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url); | |
705 EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line); | |
706 EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url); | |
707 EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line); | |
708 EXPECT_EQ(cookieUrl, cookie_store_->entries()[2].url); | |
709 EXPECT_EQ("CR-set-test=1", cookie_store_->entries()[2].cookie_line); | |
710 | |
711 CloseWebSocketJob(); | |
712 } | |
713 | |
714 void WebSocketJobTest::TestHandshakeWithCookieButNotAllowed() { | |
715 GURL url("ws://example.com/demo"); | |
716 GURL cookieUrl("http://example.com/demo"); | |
717 CookieOptions cookie_options; | |
718 cookie_store_->SetCookieWithOptions( | |
719 cookieUrl, "CR-test=1", cookie_options); | |
720 cookie_options.set_include_httponly(); | |
721 cookie_store_->SetCookieWithOptions( | |
722 cookieUrl, "CR-test-httponly=1", cookie_options); | |
723 | |
724 MockSocketStreamDelegate delegate; | |
725 delegate.set_allow_all_cookies(false); | |
726 InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET); | |
727 SkipToConnecting(); | |
728 | |
729 bool sent = websocket_->SendData(kHandshakeRequestWithCookie, | |
730 kHandshakeRequestWithCookieLength); | |
731 EXPECT_TRUE(sent); | |
732 MessageLoop::current()->RunAllPending(); | |
733 EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data()); | |
734 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
735 websocket_->OnSentData(socket_, kHandshakeRequestWithoutCookieLength); | |
736 EXPECT_EQ(kHandshakeRequestWithCookieLength, | |
737 delegate.amount_sent()); | |
738 | |
739 websocket_->OnReceivedData(socket_.get(), | |
740 kHandshakeResponseWithCookie, | |
741 kHandshakeResponseWithCookieLength); | |
742 MessageLoop::current()->RunAllPending(); | |
743 EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data()); | |
744 EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState()); | |
745 | |
746 EXPECT_EQ(2U, cookie_store_->entries().size()); | |
747 EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url); | |
748 EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line); | |
749 EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url); | |
750 EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line); | |
751 | |
752 CloseWebSocketJob(); | |
753 } | |
754 | |
755 void WebSocketJobTest::TestHSTSUpgrade() { | |
756 GURL url("ws://upgrademe.com/"); | |
757 MockSocketStreamDelegate delegate; | |
758 scoped_refptr<SocketStreamJob> job = | |
759 SocketStreamJob::CreateSocketStreamJob( | |
760 url, &delegate, context_->transport_security_state(), | |
761 context_->ssl_config_service()); | |
762 EXPECT_TRUE(GetSocket(job.get())->is_secure()); | |
763 job->DetachDelegate(); | |
764 | |
765 url = GURL("ws://donotupgrademe.com/"); | |
766 job = SocketStreamJob::CreateSocketStreamJob( | |
767 url, &delegate, context_->transport_security_state(), | |
768 context_->ssl_config_service()); | |
769 EXPECT_FALSE(GetSocket(job.get())->is_secure()); | |
770 job->DetachDelegate(); | |
771 } | |
772 | |
773 void WebSocketJobTest::TestInvalidSendData() { | |
774 GURL url("ws://example.com/demo"); | |
775 MockSocketStreamDelegate delegate; | |
776 InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET); | |
777 SkipToConnecting(); | |
778 | |
779 DoSendRequest(); | |
780 // We assume request is sent in one data chunk (from WebKit) | |
781 // We don't support streaming request. | |
782 MessageLoop::current()->RunAllPending(); | |
783 EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data()); | |
784 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
785 websocket_->OnSentData(socket_.get(), | |
786 kHandshakeRequestWithoutCookieLength); | |
787 EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent()); | |
788 | |
789 // We could not send any data until connection is established. | |
790 bool sent = websocket_->SendData(kHandshakeRequestWithoutCookie, | |
791 kHandshakeRequestWithoutCookieLength); | |
792 EXPECT_FALSE(sent); | |
793 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | |
794 CloseWebSocketJob(); | |
795 } | |
796 | |
797 // Following tests verify cooperation between WebSocketJob and SocketStream. | |
798 // Other former tests use MockSocketStream as SocketStream, so we could not | |
799 // check SocketStream behavior. | |
800 // OrderedSocketData provide socket level verifiation by checking out-going | |
801 // packets in comparison with the MockWrite array and emulating in-coming | |
802 // packets with MockRead array. | |
803 | |
804 void WebSocketJobTest::TestConnectByWebSocket(ThrottlingOption throttling) { | |
805 // This is a test for verifying cooperation between WebSocketJob and | |
806 // SocketStream. If |throttling| was |THROTTLING_OFF|, it test basic | |
807 // situation. If |throttling| was |THROTTLING_ON|, throttling limits the | |
808 // latter connection. | |
809 MockWrite writes[] = { | |
810 MockWrite(ASYNC, | |
811 kHandshakeRequestWithoutCookie, | |
812 kHandshakeRequestWithoutCookieLength, | |
813 1), | |
814 MockWrite(ASYNC, | |
815 kDataHello, | |
816 kDataHelloLength, | |
817 3) | |
818 }; | |
819 MockRead reads[] = { | |
820 MockRead(ASYNC, | |
821 kHandshakeResponseWithoutCookie, | |
822 kHandshakeResponseWithoutCookieLength, | |
823 2), | |
824 MockRead(ASYNC, | |
825 kDataWorld, | |
826 kDataWorldLength, | |
827 4), | |
828 MockRead(SYNCHRONOUS, 0, 5) // EOF | |
829 }; | |
830 data_.reset(new OrderedSocketData( | |
831 reads, arraysize(reads), writes, arraysize(writes))); | |
832 | |
833 GURL url("ws://example.com/demo"); | |
834 MockSocketStreamDelegate delegate; | |
835 WebSocketJobTest* test = this; | |
836 if (throttling == THROTTLING_ON) | |
837 delegate.SetOnStartOpenConnection( | |
838 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); | |
839 delegate.SetOnConnected( | |
840 base::Bind(&WebSocketJobTest::DoSendRequest, base::Unretained(test))); | |
841 delegate.SetOnReceivedData( | |
842 base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test))); | |
843 delegate.SetOnClose( | |
844 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); | |
845 InitWebSocketJob(url, &delegate, STREAM_SOCKET); | |
846 | |
847 scoped_refptr<WebSocketJob> block_websocket; | |
848 if (throttling == THROTTLING_ON) { | |
849 // Create former WebSocket object which obstructs the latter one. | |
850 block_websocket = new WebSocketJob(NULL); | |
851 block_websocket->addresses_ = AddressList(websocket_->address_list()); | |
852 WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()); | |
853 } | |
854 | |
855 websocket_->Connect(); | |
856 | |
857 if (throttling == THROTTLING_ON) { | |
858 EXPECT_EQ(OK, WaitForResult()); | |
859 EXPECT_TRUE(websocket_->IsWaiting()); | |
860 | |
861 // Remove the former WebSocket object from throttling queue to unblock the | |
862 // latter. | |
863 WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket); | |
864 block_websocket->state_ = WebSocketJob::CLOSED; | |
865 block_websocket = NULL; | |
866 WebSocketThrottle::GetInstance()->WakeupSocketIfNecessary(); | |
867 } | |
868 | |
869 EXPECT_EQ(OK, WaitForResult()); | |
870 EXPECT_TRUE(data_->at_read_eof()); | |
871 EXPECT_TRUE(data_->at_write_eof()); | |
872 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); | |
873 } | |
874 | |
875 void WebSocketJobTest::TestConnectBySpdy( | |
876 SpdyOption spdy, ThrottlingOption throttling) { | |
877 // This is a test for verifying cooperation between WebSocketJob and | |
878 // SocketStream in the situation we have SPDY session to the server. If | |
879 // |throttling| was |THROTTLING_ON|, throttling limits the latter connection. | |
880 // If you enabled spdy, you should specify |spdy| as |SPDY_ON|. Expected | |
881 // results depend on its configuration. | |
882 MockWrite writes_websocket[] = { | |
883 MockWrite(ASYNC, | |
884 kHandshakeRequestWithoutCookie, | |
885 kHandshakeRequestWithoutCookieLength, | |
886 1), | |
887 MockWrite(ASYNC, | |
888 kDataHello, | |
889 kDataHelloLength, | |
890 3) | |
891 }; | |
892 MockRead reads_websocket[] = { | |
893 MockRead(ASYNC, | |
894 kHandshakeResponseWithoutCookie, | |
895 kHandshakeResponseWithoutCookieLength, | |
896 2), | |
897 MockRead(ASYNC, | |
898 kDataWorld, | |
899 kDataWorldLength, | |
900 4), | |
901 MockRead(SYNCHRONOUS, 0, 5) // EOF | |
902 }; | |
903 | |
904 const spdy::SpdyStreamId kStreamId = 1; | |
905 scoped_ptr<spdy::SpdyFrame> request_frame( | |
906 ConstructSpdyWebSocketHandshakeRequestFrame( | |
907 kHandshakeRequestForSpdy, | |
908 arraysize(kHandshakeRequestForSpdy) / 2, | |
909 kStreamId, | |
910 MEDIUM)); | |
911 scoped_ptr<spdy::SpdyFrame> response_frame( | |
912 ConstructSpdyWebSocketHandshakeResponseFrame( | |
913 kHandshakeResponseForSpdy, | |
914 arraysize(kHandshakeResponseForSpdy) / 2, | |
915 kStreamId, | |
916 MEDIUM)); | |
917 scoped_ptr<spdy::SpdyFrame> data_hello_frame( | |
918 ConstructSpdyWebSocketDataFrame( | |
919 kDataHello, | |
920 kDataHelloLength, | |
921 kStreamId, | |
922 false)); | |
923 scoped_ptr<spdy::SpdyFrame> data_world_frame( | |
924 ConstructSpdyWebSocketDataFrame( | |
925 kDataWorld, | |
926 kDataWorldLength, | |
927 kStreamId, | |
928 false)); | |
929 MockWrite writes_spdy[] = { | |
930 CreateMockWrite(*request_frame.get(), 1), | |
931 CreateMockWrite(*data_hello_frame.get(), 3), | |
932 }; | |
933 MockRead reads_spdy[] = { | |
934 CreateMockRead(*response_frame.get(), 2), | |
935 CreateMockRead(*data_world_frame.get(), 4), | |
936 MockRead(SYNCHRONOUS, 0, 5) // EOF | |
937 }; | |
938 | |
939 if (spdy == SPDY_ON) | |
940 data_.reset(new OrderedSocketData( | |
941 reads_spdy, arraysize(reads_spdy), | |
942 writes_spdy, arraysize(writes_spdy))); | |
943 else | |
944 data_.reset(new OrderedSocketData( | |
945 reads_websocket, arraysize(reads_websocket), | |
946 writes_websocket, arraysize(writes_websocket))); | |
947 | |
948 GURL url("ws://example.com/demo"); | |
949 MockSocketStreamDelegate delegate; | |
950 WebSocketJobTest* test = this; | |
951 if (throttling == THROTTLING_ON) | |
952 delegate.SetOnStartOpenConnection( | |
953 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); | |
954 delegate.SetOnConnected( | |
955 base::Bind(&WebSocketJobTest::DoSendRequest, base::Unretained(test))); | |
956 delegate.SetOnReceivedData( | |
957 base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test))); | |
958 delegate.SetOnClose( | |
959 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); | |
960 InitWebSocketJob(url, &delegate, STREAM_SPDY_WEBSOCKET); | |
961 | |
962 scoped_refptr<WebSocketJob> block_websocket; | |
963 if (throttling == THROTTLING_ON) { | |
964 // Create former WebSocket object which obstructs the latter one. | |
965 block_websocket = new WebSocketJob(NULL); | |
966 block_websocket->addresses_ = AddressList(websocket_->address_list()); | |
967 WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()); | |
968 } | |
969 | |
970 websocket_->Connect(); | |
971 | |
972 if (throttling == THROTTLING_ON) { | |
973 EXPECT_EQ(OK, WaitForResult()); | |
974 EXPECT_TRUE(websocket_->IsWaiting()); | |
975 | |
976 // Remove the former WebSocket object from throttling queue to unblock the | |
977 // latter. | |
978 WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket); | |
979 block_websocket->state_ = WebSocketJob::CLOSED; | |
980 block_websocket = NULL; | |
981 WebSocketThrottle::GetInstance()->WakeupSocketIfNecessary(); | |
982 } | |
983 | |
984 EXPECT_EQ(OK, WaitForResult()); | |
985 EXPECT_TRUE(data_->at_read_eof()); | |
986 EXPECT_TRUE(data_->at_write_eof()); | |
987 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); | |
988 } | |
989 | |
990 // Execute tests in both spdy-disabled mode and spdy-enabled mode. | |
991 TEST_F(WebSocketJobTest, SimpleHandshake) { | |
992 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
993 TestSimpleHandshake(); | |
994 } | |
995 | |
996 TEST_F(WebSocketJobTest, SlowHandshake) { | |
997 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
998 TestSlowHandshake(); | |
999 } | |
1000 | |
1001 TEST_F(WebSocketJobTest, HandshakeWithCookie) { | |
1002 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1003 TestHandshakeWithCookie(); | |
1004 } | |
1005 | |
1006 TEST_F(WebSocketJobTest, HandshakeWithCookieButNotAllowed) { | |
1007 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1008 TestHandshakeWithCookieButNotAllowed(); | |
1009 } | |
1010 | |
1011 TEST_F(WebSocketJobTest, HSTSUpgrade) { | |
1012 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1013 TestHSTSUpgrade(); | |
1014 } | |
1015 | |
1016 TEST_F(WebSocketJobTest, InvalidSendData) { | |
1017 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1018 TestInvalidSendData(); | |
1019 } | |
1020 | |
1021 TEST_F(WebSocketJobTest, SimpleHandshakeSpdyEnabled) { | |
1022 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1023 TestSimpleHandshake(); | |
1024 } | |
1025 | |
1026 TEST_F(WebSocketJobTest, SlowHandshakeSpdyEnabled) { | |
1027 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1028 TestSlowHandshake(); | |
1029 } | |
1030 | |
1031 TEST_F(WebSocketJobTest, HandshakeWithCookieSpdyEnabled) { | |
1032 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1033 TestHandshakeWithCookie(); | |
1034 } | |
1035 | |
1036 TEST_F(WebSocketJobTest, HandshakeWithCookieButNotAllowedSpdyEnabled) { | |
1037 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1038 TestHandshakeWithCookieButNotAllowed(); | |
1039 } | |
1040 | |
1041 TEST_F(WebSocketJobTest, HSTSUpgradeSpdyEnabled) { | |
1042 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1043 TestHSTSUpgrade(); | |
1044 } | |
1045 | |
1046 TEST_F(WebSocketJobTest, InvalidSendDataSpdyEnabled) { | |
1047 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1048 TestInvalidSendData(); | |
1049 } | |
1050 | |
1051 TEST_F(WebSocketJobTest, ConnectByWebSocket) { | |
1052 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1053 TestConnectByWebSocket(THROTTLING_OFF); | |
1054 } | |
1055 | |
1056 TEST_F(WebSocketJobTest, ConnectByWebSocketSpdyEnabled) { | |
1057 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1058 TestConnectByWebSocket(THROTTLING_OFF); | |
1059 } | |
1060 | |
1061 TEST_F(WebSocketJobTest, ConnectBySpdy) { | |
1062 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1063 TestConnectBySpdy(SPDY_OFF, THROTTLING_OFF); | |
1064 } | |
1065 | |
1066 TEST_F(WebSocketJobTest, ConnectBySpdySpdyEnabled) { | |
1067 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1068 TestConnectBySpdy(SPDY_ON, THROTTLING_OFF); | |
1069 } | |
1070 | |
1071 TEST_F(WebSocketJobTest, ThrottlingWebSocket) { | |
1072 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1073 TestConnectByWebSocket(THROTTLING_ON); | |
1074 } | |
1075 | |
1076 TEST_F(WebSocketJobTest, ThrottlingWebSocketSpdyEnabled) { | |
1077 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1078 TestConnectByWebSocket(THROTTLING_ON); | |
1079 } | |
1080 | |
1081 TEST_F(WebSocketJobTest, ThrottlingSpdy) { | |
1082 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
1083 TestConnectBySpdy(SPDY_OFF, THROTTLING_ON); | |
1084 } | |
1085 | |
1086 TEST_F(WebSocketJobTest, ThrottlingSpdySpdyEnabled) { | |
1087 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
1088 TestConnectBySpdy(SPDY_ON, THROTTLING_ON); | |
1089 } | |
1090 | |
1091 // TODO(toyoshim): Add tests to verify throttling, SPDY stream limitation. | |
1092 // TODO(toyoshim,yutak): Add tests to verify closing handshake. | |
1093 | |
1094 } // namespace net | |
OLD | NEW |