Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/websockets/websocket_job.h" | 5 #include "net/websockets/websocket_job.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| 11 #include "base/string_split.h" | 11 #include "base/string_split.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "googleurl/src/gurl.h" | 13 #include "googleurl/src/gurl.h" |
| 14 #include "net/base/completion_callback.h" | 14 #include "net/base/completion_callback.h" |
| 15 #include "net/base/cookie_store.h" | 15 #include "net/base/cookie_store.h" |
| 16 #include "net/base/mock_host_resolver.h" | 16 #include "net/base/mock_host_resolver.h" |
| 17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 18 #include "net/base/ssl_config_service.h" | 18 #include "net/base/ssl_config_service.h" |
| 19 #include "net/base/sys_addrinfo.h" | 19 #include "net/base/sys_addrinfo.h" |
| 20 #include "net/base/test_completion_callback.h" | 20 #include "net/base/test_completion_callback.h" |
| 21 #include "net/base/transport_security_state.h" | 21 #include "net/base/transport_security_state.h" |
| 22 #include "net/http/http_transaction_factory.h" | |
| 22 #include "net/proxy/proxy_service.h" | 23 #include "net/proxy/proxy_service.h" |
| 23 #include "net/socket/socket_test_util.h" | 24 #include "net/socket/socket_test_util.h" |
| 24 #include "net/socket_stream/socket_stream.h" | 25 #include "net/socket_stream/socket_stream.h" |
| 26 #include "net/spdy/spdy_session.h" | |
| 27 #include "net/spdy/spdy_test_util.h" | |
| 28 #include "net/spdy/spdy_websocket_test_util.h" | |
| 25 #include "net/url_request/url_request_context.h" | 29 #include "net/url_request/url_request_context.h" |
| 26 #include "net/websockets/websocket_throttle.h" | 30 #include "net/websockets/websocket_throttle.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
| 28 #include "testing/gmock/include/gmock/gmock.h" | 32 #include "testing/gmock/include/gmock/gmock.h" |
| 29 #include "testing/platform_test.h" | 33 #include "testing/platform_test.h" |
| 30 | 34 |
| 31 namespace { | 35 namespace { |
| 32 | 36 |
| 33 class MockSocketStream : public net::SocketStream { | 37 class MockSocketStream : public net::SocketStream { |
| 34 public: | 38 public: |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 transport_security_state_->EnableHost("upgrademe.com", state); | 195 transport_security_state_->EnableHost("upgrademe.com", state); |
| 192 } | 196 } |
| 193 | 197 |
| 194 private: | 198 private: |
| 195 friend class base::RefCountedThreadSafe<MockURLRequestContext>; | 199 friend class base::RefCountedThreadSafe<MockURLRequestContext>; |
| 196 virtual ~MockURLRequestContext() {} | 200 virtual ~MockURLRequestContext() {} |
| 197 | 201 |
| 198 scoped_refptr<net::TransportSecurityState> transport_security_state_; | 202 scoped_refptr<net::TransportSecurityState> transport_security_state_; |
| 199 }; | 203 }; |
| 200 | 204 |
| 205 class MockHttpTransactionFactory : public net::HttpTransactionFactory { | |
| 206 public: | |
| 207 MockHttpTransactionFactory(scoped_refptr<net::OrderedSocketData>& data) { | |
| 208 data_ = data; | |
| 209 data_->AddRef(); | |
| 210 net::MockConnect connect_data(false, net::OK); | |
| 211 data_->set_connect_data(connect_data); | |
| 212 session_deps_.reset(new net::SpdySessionDependencies); | |
| 213 session_deps_->socket_factory->AddSocketDataProvider(data_.get()); | |
| 214 http_session_ = | |
| 215 net::SpdySessionDependencies::SpdyCreateSession(session_deps_.get()); | |
| 216 host_port_pair_.set_host("example.com"); | |
| 217 host_port_pair_.set_port(80); | |
| 218 host_port_proxy_pair_.first = host_port_pair_; | |
| 219 host_port_proxy_pair_.second = net::ProxyServer::Direct(); | |
| 220 net::SpdySessionPool* spdy_session_pool = | |
| 221 http_session_->spdy_session_pool(); | |
| 222 DCHECK(spdy_session_pool); | |
| 223 EXPECT_FALSE(spdy_session_pool->HasSession(host_port_proxy_pair_)); | |
| 224 session_ = | |
| 225 spdy_session_pool->Get(host_port_proxy_pair_, net::BoundNetLog()); | |
| 226 EXPECT_TRUE(spdy_session_pool->HasSession(host_port_proxy_pair_)); | |
| 227 | |
| 228 transport_params_ = new net::TransportSocketParams(host_port_pair_, | |
| 229 net::MEDIUM, | |
| 230 GURL(), | |
| 231 false, | |
| 232 false); | |
| 233 net::ClientSocketHandle* connection = new net::ClientSocketHandle; | |
| 234 EXPECT_EQ(net::OK, connection->Init(host_port_pair_.ToString(), | |
| 235 transport_params_, | |
| 236 net::MEDIUM, | |
| 237 NULL, | |
| 238 http_session_->transport_socket_pool(), | |
| 239 net::BoundNetLog())); | |
| 240 EXPECT_EQ(net::OK, | |
| 241 session_->InitializeWithSocket(connection, false, net::OK)); | |
| 242 } | |
| 243 virtual int CreateTransaction(scoped_ptr<net::HttpTransaction>* trans) { | |
| 244 NOTREACHED(); | |
| 245 return net::ERR_UNEXPECTED; | |
| 246 } | |
| 247 virtual net::HttpCache* GetCache() { | |
| 248 NOTREACHED(); | |
| 249 return NULL; | |
| 250 } | |
| 251 virtual net::HttpNetworkSession* GetSession() { | |
| 252 return http_session_.get(); | |
| 253 } | |
| 254 private: | |
| 255 scoped_refptr<net::OrderedSocketData> data_; | |
| 256 scoped_ptr<net::SpdySessionDependencies> session_deps_; | |
| 257 scoped_refptr<net::HttpNetworkSession> http_session_; | |
| 258 scoped_refptr<net::TransportSocketParams> transport_params_; | |
| 259 scoped_refptr<net::SpdySession> session_; | |
| 260 net::HostPortPair host_port_pair_; | |
| 261 net::HostPortProxyPair host_port_proxy_pair_; | |
| 262 }; | |
| 263 | |
| 201 } | 264 } |
| 202 | 265 |
| 203 namespace net { | 266 namespace net { |
| 204 | 267 |
| 205 class WebSocketJobTest : public PlatformTest { | 268 class WebSocketJobTest : public PlatformTest { |
| 206 public: | 269 public: |
| 207 virtual void SetUp() { | 270 virtual void SetUp() { |
| 271 spdy::SpdyFramer::set_enable_compression_default(false); | |
| 208 stream_type_ = STREAM_INVALID; | 272 stream_type_ = STREAM_INVALID; |
| 209 cookie_store_ = new MockCookieStore; | 273 cookie_store_ = new MockCookieStore; |
| 210 context_ = new MockURLRequestContext(cookie_store_.get()); | 274 context_ = new MockURLRequestContext(cookie_store_.get()); |
| 211 } | 275 } |
| 212 virtual void TearDown() { | 276 virtual void TearDown() { |
| 213 cookie_store_ = NULL; | 277 cookie_store_ = NULL; |
| 214 context_ = NULL; | 278 context_ = NULL; |
| 215 websocket_ = NULL; | 279 websocket_ = NULL; |
| 216 socket_ = NULL; | 280 socket_ = NULL; |
| 217 } | 281 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 235 STREAM_MOCK_SOCKET, | 299 STREAM_MOCK_SOCKET, |
| 236 STREAM_SOCKET, | 300 STREAM_SOCKET, |
| 237 STREAM_SPDY_WEBSOCKET, | 301 STREAM_SPDY_WEBSOCKET, |
| 238 }; | 302 }; |
| 239 void InitWebSocketJob(const GURL& url, | 303 void InitWebSocketJob(const GURL& url, |
| 240 MockSocketStreamDelegate* delegate, | 304 MockSocketStreamDelegate* delegate, |
| 241 StreamType stream_type) { | 305 StreamType stream_type) { |
| 242 stream_type_ = stream_type; | 306 stream_type_ = stream_type; |
| 243 websocket_ = new WebSocketJob(delegate); | 307 websocket_ = new WebSocketJob(delegate); |
| 244 | 308 |
| 309 if (stream_type == STREAM_MOCK_SOCKET) | |
| 310 socket_ = new MockSocketStream(url, websocket_.get()); | |
| 311 | |
| 312 if (stream_type == STREAM_SPDY_WEBSOCKET) { | |
| 313 http_factory_.reset(new MockHttpTransactionFactory(data_)); | |
| 314 context_->set_http_transaction_factory(http_factory_.get()); | |
| 315 } | |
| 316 | |
| 245 if (stream_type == STREAM_SOCKET || | 317 if (stream_type == STREAM_SOCKET || |
| 246 stream_type == STREAM_SPDY_WEBSOCKET) { | 318 stream_type == STREAM_SPDY_WEBSOCKET) { |
| 247 ssl_config_service_ = new MockSSLConfigService(); | 319 ssl_config_service_ = new MockSSLConfigService(); |
| 248 context_->set_ssl_config_service(ssl_config_service_); | 320 context_->set_ssl_config_service(ssl_config_service_); |
| 249 proxy_service_.reset(net::ProxyService::CreateDirect()); | 321 proxy_service_.reset(net::ProxyService::CreateDirect()); |
| 250 context_->set_proxy_service(proxy_service_.get()); | 322 context_->set_proxy_service(proxy_service_.get()); |
| 251 host_resolver_.reset(new net::MockHostResolver); | 323 host_resolver_.reset(new net::MockHostResolver); |
| 252 context_->set_host_resolver(host_resolver_.get()); | 324 context_->set_host_resolver(host_resolver_.get()); |
| 325 | |
| 326 socket_ = new SocketStream(url, websocket_.get()); | |
| 327 socket_factory_.reset(new MockClientSocketFactory); | |
| 328 DCHECK(data_.get()); | |
| 329 socket_factory_->AddSocketDataProvider(data_.get()); | |
| 330 socket_->SetClientSocketFactory(socket_factory_.get()); | |
| 253 } | 331 } |
|
Yuta Kitamura
2011/07/08 07:40:21
The three blocks above sound a bit confusing...
H
Takashi Toyoshima
2011/07/08 08:35:14
Thanks.
New one looks fine!
| |
| 254 | 332 |
| 255 switch (stream_type) { | |
| 256 case STREAM_INVALID: | |
| 257 NOTREACHED(); | |
| 258 break; | |
| 259 case STREAM_MOCK_SOCKET: | |
| 260 socket_ = new MockSocketStream(url, websocket_.get()); | |
| 261 break; | |
| 262 case STREAM_SOCKET: | |
| 263 socket_ = new SocketStream(url, websocket_.get()); | |
| 264 socket_factory_.reset(new MockClientSocketFactory); | |
| 265 DCHECK(data_.get()); | |
| 266 socket_factory_->AddSocketDataProvider(data_.get()); | |
| 267 socket_->SetClientSocketFactory(socket_factory_.get()); | |
| 268 break; | |
| 269 case STREAM_SPDY_WEBSOCKET: | |
| 270 // TODO(toyoshim): Support SpdyWebSocketStream. | |
| 271 break; | |
| 272 } | |
| 273 websocket_->InitSocketStream(socket_.get()); | 333 websocket_->InitSocketStream(socket_.get()); |
| 274 websocket_->set_context(context_.get()); | 334 websocket_->set_context(context_.get()); |
| 275 struct addrinfo addr; | 335 struct addrinfo addr; |
| 276 memset(&addr, 0, sizeof(struct addrinfo)); | 336 memset(&addr, 0, sizeof(struct addrinfo)); |
| 277 addr.ai_family = AF_INET; | 337 addr.ai_family = AF_INET; |
| 278 addr.ai_addrlen = sizeof(struct sockaddr_in); | 338 addr.ai_addrlen = sizeof(struct sockaddr_in); |
| 279 struct sockaddr_in sa_in; | 339 struct sockaddr_in sa_in; |
| 280 memset(&sa_in, 0, sizeof(struct sockaddr_in)); | 340 memset(&sa_in, 0, sizeof(struct sockaddr_in)); |
| 281 memcpy(&sa_in.sin_addr, "\x7f\0\0\1", 4); | 341 memcpy(&sa_in.sin_addr, "\x7f\0\0\1", 4); |
| 282 addr.ai_addr = reinterpret_cast<sockaddr*>(&sa_in); | 342 addr.ai_addr = reinterpret_cast<sockaddr*>(&sa_in); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 return delegate->received_data(); | 377 return delegate->received_data(); |
| 318 } | 378 } |
| 319 | 379 |
| 320 void TestSimpleHandshake(); | 380 void TestSimpleHandshake(); |
| 321 void TestSlowHandshake(); | 381 void TestSlowHandshake(); |
| 322 void TestHandshakeWithCookie(); | 382 void TestHandshakeWithCookie(); |
| 323 void TestHandshakeWithCookieButNotAllowed(); | 383 void TestHandshakeWithCookieButNotAllowed(); |
| 324 void TestHSTSUpgrade(); | 384 void TestHSTSUpgrade(); |
| 325 void TestInvalidSendData(); | 385 void TestInvalidSendData(); |
| 326 void TestConnectByWebSocket(); | 386 void TestConnectByWebSocket(); |
| 387 void TestConnectBySpdy(bool use_spdy); | |
| 327 | 388 |
| 328 StreamType stream_type_; | 389 StreamType stream_type_; |
| 329 scoped_refptr<MockCookieStore> cookie_store_; | 390 scoped_refptr<MockCookieStore> cookie_store_; |
| 330 scoped_refptr<MockURLRequestContext> context_; | 391 scoped_refptr<MockURLRequestContext> context_; |
| 331 scoped_refptr<WebSocketJob> websocket_; | 392 scoped_refptr<WebSocketJob> websocket_; |
| 332 scoped_refptr<SocketStream> socket_; | 393 scoped_refptr<SocketStream> socket_; |
| 333 scoped_ptr<MockClientSocketFactory> socket_factory_; | 394 scoped_ptr<MockClientSocketFactory> socket_factory_; |
| 334 scoped_refptr<OrderedSocketData> data_; | 395 scoped_refptr<OrderedSocketData> data_; |
| 335 TestCompletionCallback sync_callback_; | 396 TestCompletionCallback sync_callback_; |
| 336 scoped_refptr<MockSSLConfigService> ssl_config_service_; | 397 scoped_refptr<MockSSLConfigService> ssl_config_service_; |
| 337 scoped_ptr<net::ProxyService> proxy_service_; | 398 scoped_ptr<net::ProxyService> proxy_service_; |
| 338 scoped_ptr<net::MockHostResolver> host_resolver_; | 399 scoped_ptr<net::MockHostResolver> host_resolver_; |
| 400 scoped_ptr<MockHttpTransactionFactory> http_factory_; | |
| 339 | 401 |
| 340 static const char kHandshakeRequestWithoutCookie[]; | 402 static const char kHandshakeRequestWithoutCookie[]; |
| 341 static const char kHandshakeRequestWithCookie[]; | 403 static const char kHandshakeRequestWithCookie[]; |
| 342 static const char kHandshakeRequestWithFilteredCookie[]; | 404 static const char kHandshakeRequestWithFilteredCookie[]; |
| 343 static const char kHandshakeResponseWithoutCookie[]; | 405 static const char kHandshakeResponseWithoutCookie[]; |
| 344 static const char kHandshakeResponseWithCookie[]; | 406 static const char kHandshakeResponseWithCookie[]; |
| 345 static const char kDataHello[]; | 407 static const char kDataHello[]; |
| 346 static const char kDataWorld[]; | 408 static const char kDataWorld[]; |
| 409 static const char* const kHandshakeRequestForSpdy[]; | |
| 410 static const char* const kHandshakeResponseForSpdy[]; | |
| 347 static const size_t kHandshakeRequestWithoutCookieLength; | 411 static const size_t kHandshakeRequestWithoutCookieLength; |
| 348 static const size_t kHandshakeRequestWithCookieLength; | 412 static const size_t kHandshakeRequestWithCookieLength; |
| 349 static const size_t kHandshakeRequestWithFilteredCookieLength; | 413 static const size_t kHandshakeRequestWithFilteredCookieLength; |
| 350 static const size_t kHandshakeResponseWithoutCookieLength; | 414 static const size_t kHandshakeResponseWithoutCookieLength; |
| 351 static const size_t kHandshakeResponseWithCookieLength; | 415 static const size_t kHandshakeResponseWithCookieLength; |
| 352 static const size_t kDataHelloLength; | 416 static const size_t kDataHelloLength; |
| 353 static const size_t kDataWorldLength; | 417 static const size_t kDataWorldLength; |
| 354 }; | 418 }; |
| 355 | 419 |
| 356 const char WebSocketJobTest::kHandshakeRequestWithoutCookie[] = | 420 const char WebSocketJobTest::kHandshakeRequestWithoutCookie[] = |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | 473 "Sec-WebSocket-Location: ws://example.com/demo\r\n" |
| 410 "Sec-WebSocket-Protocol: sample\r\n" | 474 "Sec-WebSocket-Protocol: sample\r\n" |
| 411 "Set-Cookie: CR-set-test=1\r\n" | 475 "Set-Cookie: CR-set-test=1\r\n" |
| 412 "\r\n" | 476 "\r\n" |
| 413 "8jKS'y:G*Co,Wxa-"; | 477 "8jKS'y:G*Co,Wxa-"; |
| 414 | 478 |
| 415 const char WebSocketJobTest::kDataHello[] = "Hello, "; | 479 const char WebSocketJobTest::kDataHello[] = "Hello, "; |
| 416 | 480 |
| 417 const char WebSocketJobTest::kDataWorld[] = "World!\n"; | 481 const char WebSocketJobTest::kDataWorld[] = "World!\n"; |
| 418 | 482 |
| 483 // TODO(toyoshim): I should clarify which WebSocket headers for handshake must | |
| 484 // be exported to SPDY SYN_STREAM and SYN_REPLY. | |
| 485 // Because it depends on HyBi versions, just define it as follow for now. | |
| 486 const char* const WebSocketJobTest::kHandshakeRequestForSpdy[] = { | |
| 487 "host", "example.com", | |
| 488 "origin", "http://example.com", | |
| 489 "sec-websocket-protocol", "sample", | |
| 490 "url", "ws://example.com/demo" | |
| 491 }; | |
| 492 | |
| 493 const char* const WebSocketJobTest::kHandshakeResponseForSpdy[] = { | |
| 494 "sec-websocket-origin", "http://example.com", | |
| 495 "sec-websocket-location", "ws://example.com/demo", | |
| 496 "sec-websocket-protocol", "sample", | |
| 497 }; | |
| 498 | |
| 419 const size_t WebSocketJobTest::kHandshakeRequestWithoutCookieLength = | 499 const size_t WebSocketJobTest::kHandshakeRequestWithoutCookieLength = |
| 420 arraysize(kHandshakeRequestWithoutCookie) - 1; | 500 arraysize(kHandshakeRequestWithoutCookie) - 1; |
| 421 const size_t WebSocketJobTest::kHandshakeRequestWithCookieLength = | 501 const size_t WebSocketJobTest::kHandshakeRequestWithCookieLength = |
| 422 arraysize(kHandshakeRequestWithCookie) - 1; | 502 arraysize(kHandshakeRequestWithCookie) - 1; |
| 423 const size_t WebSocketJobTest::kHandshakeRequestWithFilteredCookieLength = | 503 const size_t WebSocketJobTest::kHandshakeRequestWithFilteredCookieLength = |
| 424 arraysize(kHandshakeRequestWithFilteredCookie) - 1; | 504 arraysize(kHandshakeRequestWithFilteredCookie) - 1; |
| 425 const size_t WebSocketJobTest::kHandshakeResponseWithoutCookieLength = | 505 const size_t WebSocketJobTest::kHandshakeResponseWithoutCookieLength = |
| 426 arraysize(kHandshakeResponseWithoutCookie) - 1; | 506 arraysize(kHandshakeResponseWithoutCookie) - 1; |
| 427 const size_t WebSocketJobTest::kHandshakeResponseWithCookieLength = | 507 const size_t WebSocketJobTest::kHandshakeResponseWithCookieLength = |
| 428 arraysize(kHandshakeResponseWithCookie) - 1; | 508 arraysize(kHandshakeResponseWithCookie) - 1; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 617 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); | 697 EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState()); |
| 618 CloseWebSocketJob(); | 698 CloseWebSocketJob(); |
| 619 } | 699 } |
| 620 | 700 |
| 621 // Following tests verify cooperation between WebSocketJob and SocketStream. | 701 // Following tests verify cooperation between WebSocketJob and SocketStream. |
| 622 // Other former tests use MockSocketStream as SocketStream, so we could not | 702 // Other former tests use MockSocketStream as SocketStream, so we could not |
| 623 // check SocketStream behavior. | 703 // check SocketStream behavior. |
| 624 // OrderedSocketData provide socket level verifiation by checking out-going | 704 // OrderedSocketData provide socket level verifiation by checking out-going |
| 625 // packets in comparison with the MockWrite array and emulating in-coming | 705 // packets in comparison with the MockWrite array and emulating in-coming |
| 626 // packets with MockRead array. | 706 // packets with MockRead array. |
| 627 // TODO(toyoshim): Add tests which verify protocol switch and ERR_IO_PENDING. | |
| 628 | 707 |
| 629 void WebSocketJobTest::TestConnectByWebSocket() { | 708 void WebSocketJobTest::TestConnectByWebSocket() { |
| 630 // This is a test for verifying cooperation between WebSocketJob and | 709 // This is a test for verifying cooperation between WebSocketJob and |
| 631 // SocketStream in basic situation. | 710 // SocketStream in basic situation. |
| 632 MockWrite writes[] = { | 711 MockWrite writes[] = { |
| 633 MockWrite(true, | 712 MockWrite(true, |
| 634 kHandshakeRequestWithoutCookie, | 713 kHandshakeRequestWithoutCookie, |
| 635 kHandshakeRequestWithoutCookieLength, | 714 kHandshakeRequestWithoutCookieLength, |
| 636 1), | 715 1), |
| 637 MockWrite(true, | 716 MockWrite(true, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 664 NewCallback(test, &WebSocketJobTest::DoSync)); | 743 NewCallback(test, &WebSocketJobTest::DoSync)); |
| 665 InitWebSocketJob(url, &delegate, STREAM_SOCKET); | 744 InitWebSocketJob(url, &delegate, STREAM_SOCKET); |
| 666 | 745 |
| 667 websocket_->Connect(); | 746 websocket_->Connect(); |
| 668 EXPECT_EQ(OK, WaitForResult()); | 747 EXPECT_EQ(OK, WaitForResult()); |
| 669 EXPECT_TRUE(data_->at_read_eof()); | 748 EXPECT_TRUE(data_->at_read_eof()); |
| 670 EXPECT_TRUE(data_->at_write_eof()); | 749 EXPECT_TRUE(data_->at_write_eof()); |
| 671 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); | 750 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); |
| 672 } | 751 } |
| 673 | 752 |
| 753 void WebSocketJobTest::TestConnectBySpdy(bool use_spdy) { | |
| 754 // This is a test for verifying cooperation between WebSocketJob and | |
| 755 // SocketStream in the situation we have SPDY session to the server. | |
| 756 MockWrite writes_websocket[] = { | |
| 757 MockWrite(true, | |
| 758 kHandshakeRequestWithoutCookie, | |
| 759 kHandshakeRequestWithoutCookieLength, | |
| 760 1), | |
| 761 MockWrite(true, | |
| 762 kDataHello, | |
| 763 kDataHelloLength, | |
| 764 3) | |
| 765 }; | |
| 766 MockRead reads_websocket[] = { | |
| 767 MockRead(true, | |
| 768 kHandshakeResponseWithoutCookie, | |
| 769 kHandshakeResponseWithoutCookieLength, | |
| 770 2), | |
| 771 MockRead(true, | |
| 772 kDataWorld, | |
| 773 kDataWorldLength, | |
| 774 4), | |
| 775 MockRead(false, 0, 5) // EOF | |
| 776 }; | |
| 777 | |
| 778 const spdy::SpdyStreamId kStreamId = 1; | |
| 779 scoped_ptr<spdy::SpdyFrame> request_frame( | |
| 780 ConstructSpdyWebSocketHandshakeRequestFrame( | |
| 781 kHandshakeRequestForSpdy, | |
| 782 arraysize(kHandshakeRequestForSpdy) / 2, | |
| 783 kStreamId, | |
| 784 MEDIUM)); | |
| 785 scoped_ptr<spdy::SpdyFrame> response_frame( | |
| 786 ConstructSpdyWebSocketHandshakeResponseFrame( | |
| 787 kHandshakeResponseForSpdy, | |
| 788 arraysize(kHandshakeResponseForSpdy) / 2, | |
| 789 kStreamId, | |
| 790 MEDIUM)); | |
| 791 scoped_ptr<spdy::SpdyFrame> data_hello_frame( | |
| 792 ConstructSpdyWebSocketDataFrame( | |
| 793 kDataHello, | |
| 794 kDataHelloLength, | |
| 795 kStreamId, | |
| 796 false)); | |
| 797 scoped_ptr<spdy::SpdyFrame> data_world_frame( | |
| 798 ConstructSpdyWebSocketDataFrame( | |
| 799 kDataWorld, | |
| 800 kDataWorldLength, | |
| 801 kStreamId, | |
| 802 false)); | |
| 803 MockWrite writes_spdy[] = { | |
| 804 CreateMockWrite(*request_frame.get(), 1), | |
| 805 CreateMockWrite(*data_hello_frame.get(), 3), | |
| 806 }; | |
| 807 MockRead reads_spdy[] = { | |
| 808 CreateMockRead(*response_frame.get(), 2), | |
| 809 CreateMockRead(*data_world_frame.get(), 4), | |
| 810 MockRead(false, 0, 5) // EOF | |
| 811 }; | |
| 812 | |
| 813 if (use_spdy) | |
| 814 data_ = new OrderedSocketData( | |
| 815 reads_spdy, arraysize(reads_spdy), | |
| 816 writes_spdy, arraysize(writes_spdy)); | |
| 817 else | |
| 818 data_ = new OrderedSocketData( | |
| 819 reads_websocket, arraysize(reads_websocket), | |
| 820 writes_websocket, arraysize(writes_websocket)); | |
| 821 | |
| 822 GURL url("ws://example.com/demo"); | |
| 823 MockSocketStreamDelegate delegate; | |
| 824 WebSocketJobTest* test = this; | |
| 825 delegate.SetOnConnected( | |
| 826 NewCallback(test, &WebSocketJobTest::DoSendRequest)); | |
| 827 delegate.SetOnReceivedData( | |
| 828 NewCallback(test, &WebSocketJobTest::DoSendData)); | |
| 829 delegate.SetOnClose( | |
| 830 NewCallback(test, &WebSocketJobTest::DoSync)); | |
| 831 InitWebSocketJob(url, &delegate, STREAM_SPDY_WEBSOCKET); | |
| 832 | |
| 833 websocket_->Connect(); | |
| 834 EXPECT_EQ(OK, WaitForResult()); | |
| 835 | |
| 836 EXPECT_TRUE(data_->at_read_eof()); | |
| 837 EXPECT_TRUE(data_->at_write_eof()); | |
| 838 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); | |
| 839 } | |
| 840 | |
| 674 // Execute tests in both spdy-disabled mode and spdy-enabled mode. | 841 // Execute tests in both spdy-disabled mode and spdy-enabled mode. |
| 675 TEST_F(WebSocketJobTest, SimpleHandshake) { | 842 TEST_F(WebSocketJobTest, SimpleHandshake) { |
| 676 WebSocketJob::set_websocket_over_spdy_enabled(false); | 843 WebSocketJob::set_websocket_over_spdy_enabled(false); |
| 677 TestSimpleHandshake(); | 844 TestSimpleHandshake(); |
| 678 } | 845 } |
| 679 | 846 |
| 680 TEST_F(WebSocketJobTest, SlowHandshake) { | 847 TEST_F(WebSocketJobTest, SlowHandshake) { |
| 681 WebSocketJob::set_websocket_over_spdy_enabled(false); | 848 WebSocketJob::set_websocket_over_spdy_enabled(false); |
| 682 TestSlowHandshake(); | 849 TestSlowHandshake(); |
| 683 } | 850 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 735 TEST_F(WebSocketJobTest, ConnectByWebSocket) { | 902 TEST_F(WebSocketJobTest, ConnectByWebSocket) { |
| 736 WebSocketJob::set_websocket_over_spdy_enabled(false); | 903 WebSocketJob::set_websocket_over_spdy_enabled(false); |
| 737 TestConnectByWebSocket(); | 904 TestConnectByWebSocket(); |
| 738 } | 905 } |
| 739 | 906 |
| 740 TEST_F(WebSocketJobTest, ConnectByWebSocketSpdyEnabled) { | 907 TEST_F(WebSocketJobTest, ConnectByWebSocketSpdyEnabled) { |
| 741 WebSocketJob::set_websocket_over_spdy_enabled(true); | 908 WebSocketJob::set_websocket_over_spdy_enabled(true); |
| 742 TestConnectByWebSocket(); | 909 TestConnectByWebSocket(); |
| 743 } | 910 } |
| 744 | 911 |
| 912 TEST_F(WebSocketJobTest, ConnectBySpdy) { | |
| 913 WebSocketJob::set_websocket_over_spdy_enabled(false); | |
| 914 TestConnectBySpdy(false); | |
| 915 } | |
| 916 | |
| 917 TEST_F(WebSocketJobTest, ConnectBySpdySpdyEnabled) { | |
| 918 WebSocketJob::set_websocket_over_spdy_enabled(true); | |
| 919 TestConnectBySpdy(true); | |
| 920 } | |
| 921 | |
| 922 // TODO(toyoshim): Add tests to verify throttling, SPDY stream limitation. | |
| 923 // TODO(toyoshim,yutak): Add tests to verify closing handshake. | |
| 924 | |
| 745 } // namespace net | 925 } // namespace net |
| OLD | NEW |