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