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/http/http_network_transaction.h" 6 7 #include <math.h> // ceil 8 #include <stdarg.h> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/compiler_specific.h" 14 #include "base/files/file_path.h" 15 #include "base/files/file_util.h" 16 #include "base/json/json_writer.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/run_loop.h" 20 #include "base/strings/string_util.h" 21 #include "base/strings/utf_string_conversions.h" 22 #include "base/test/test_file_util.h" 23 #include "net/base/auth.h" 24 #include "net/base/capturing_net_log.h" 25 #include "net/base/completion_callback.h" 26 #include "net/base/load_timing_info.h" 27 #include "net/base/load_timing_info_test_util.h" 28 #include "net/base/net_log.h" 29 #include "net/base/net_log_unittest.h" 30 #include "net/base/request_priority.h" 31 #include "net/base/test_completion_callback.h" 32 #include "net/base/test_data_directory.h" 33 #include "net/base/upload_bytes_element_reader.h" 34 #include "net/base/upload_data_stream.h" 35 #include "net/base/upload_file_element_reader.h" 36 #include "net/cert/mock_cert_verifier.h" 37 #include "net/dns/host_cache.h" 38 #include "net/dns/mock_host_resolver.h" 39 #include "net/http/http_auth_challenge_tokenizer.h" 40 #include "net/http/http_auth_handler_digest.h" 41 #include "net/http/http_auth_handler_mock.h" 42 #include "net/http/http_auth_handler_ntlm.h" 43 #include "net/http/http_basic_stream.h" 44 #include "net/http/http_network_session.h" 45 #include "net/http/http_network_session_peer.h" 46 #include "net/http/http_server_properties_impl.h" 47 #include "net/http/http_stream.h" 48 #include "net/http/http_stream_factory.h" 49 #include "net/http/http_transaction_test_util.h" 50 #include "net/proxy/proxy_config_service_fixed.h" 51 #include "net/proxy/proxy_info.h" 52 #include "net/proxy/proxy_resolver.h" 53 #include "net/proxy/proxy_service.h" 54 #include "net/socket/client_socket_factory.h" 55 #include "net/socket/client_socket_pool_manager.h" 56 #include "net/socket/mock_client_socket_pool_manager.h" 57 #include "net/socket/next_proto.h" 58 #include "net/socket/socket_test_util.h" 59 #include "net/socket/ssl_client_socket.h" 60 #include "net/spdy/spdy_framer.h" 61 #include "net/spdy/spdy_session.h" 62 #include "net/spdy/spdy_session_pool.h" 63 #include "net/spdy/spdy_test_util_common.h" 64 #include "net/ssl/ssl_cert_request_info.h" 65 #include "net/ssl/ssl_config_service.h" 66 #include "net/ssl/ssl_config_service_defaults.h" 67 #include "net/ssl/ssl_info.h" 68 #include "net/test/cert_test_util.h" 69 #include "net/websockets/websocket_handshake_stream_base.h" 70 #include "testing/gtest/include/gtest/gtest.h" 71 #include "testing/platform_test.h" 72 #include "url/gurl.h" 73 74 using base::ASCIIToUTF16; 75 76 //----------------------------------------------------------------------------- 77 78 namespace { 79 80 const base::string16 kBar(ASCIIToUTF16("bar")); 81 const base::string16 kBar2(ASCIIToUTF16("bar2")); 82 const base::string16 kBar3(ASCIIToUTF16("bar3")); 83 const base::string16 kBaz(ASCIIToUTF16("baz")); 84 const base::string16 kFirst(ASCIIToUTF16("first")); 85 const base::string16 kFoo(ASCIIToUTF16("foo")); 86 const base::string16 kFoo2(ASCIIToUTF16("foo2")); 87 const base::string16 kFoo3(ASCIIToUTF16("foo3")); 88 const base::string16 kFou(ASCIIToUTF16("fou")); 89 const base::string16 kSecond(ASCIIToUTF16("second")); 90 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm")); 91 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword")); 92 93 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) { 94 return session->GetTransportSocketPool( 95 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount(); 96 } 97 98 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) { 99 return session->GetSSLSocketPool( 100 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount(); 101 } 102 103 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) { 104 return session->GetTransportSocketPool( 105 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled(); 106 } 107 108 // Takes in a Value created from a NetLogHttpResponseParameter, and returns 109 // a JSONified list of headers as a single string. Uses single quotes instead 110 // of double quotes for easier comparison. Returns false on failure. 111 bool GetHeaders(base::DictionaryValue* params, std::string* headers) { 112 if (!params) 113 return false; 114 base::ListValue* header_list; 115 if (!params->GetList("headers", &header_list)) 116 return false; 117 std::string double_quote_headers; 118 base::JSONWriter::Write(header_list, &double_quote_headers); 119 base::ReplaceChars(double_quote_headers, "\"", "'", headers); 120 return true; 121 } 122 123 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is 124 // used. 125 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) { 126 EXPECT_TRUE(load_timing_info.socket_reused); 127 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 128 129 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 130 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 131 132 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 133 EXPECT_FALSE(load_timing_info.send_start.is_null()); 134 135 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 136 137 // Set at a higher level. 138 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 139 EXPECT_TRUE(load_timing_info.request_start.is_null()); 140 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 141 } 142 143 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is 144 // used. 145 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info, 146 int connect_timing_flags) { 147 EXPECT_FALSE(load_timing_info.socket_reused); 148 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 149 150 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 151 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 152 153 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 154 connect_timing_flags); 155 EXPECT_LE(load_timing_info.connect_timing.connect_end, 156 load_timing_info.send_start); 157 158 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 159 160 // Set at a higher level. 161 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 162 EXPECT_TRUE(load_timing_info.request_start.is_null()); 163 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 164 } 165 166 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is 167 // used. 168 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) { 169 EXPECT_TRUE(load_timing_info.socket_reused); 170 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 171 172 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 173 174 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 175 EXPECT_LE(load_timing_info.proxy_resolve_start, 176 load_timing_info.proxy_resolve_end); 177 EXPECT_LE(load_timing_info.proxy_resolve_end, 178 load_timing_info.send_start); 179 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 180 181 // Set at a higher level. 182 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 183 EXPECT_TRUE(load_timing_info.request_start.is_null()); 184 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 185 } 186 187 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is 188 // used. 189 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info, 190 int connect_timing_flags) { 191 EXPECT_FALSE(load_timing_info.socket_reused); 192 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 193 194 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 195 EXPECT_LE(load_timing_info.proxy_resolve_start, 196 load_timing_info.proxy_resolve_end); 197 EXPECT_LE(load_timing_info.proxy_resolve_end, 198 load_timing_info.connect_timing.connect_start); 199 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 200 connect_timing_flags); 201 EXPECT_LE(load_timing_info.connect_timing.connect_end, 202 load_timing_info.send_start); 203 204 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 205 206 // Set at a higher level. 207 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 208 EXPECT_TRUE(load_timing_info.request_start.is_null()); 209 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 210 } 211 212 } // namespace 213 214 namespace net { 215 216 namespace { 217 218 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) { 219 return SpdySessionDependencies::SpdyCreateSession(session_deps); 220 } 221 222 } // namespace 223 224 class HttpNetworkTransactionTest 225 : public PlatformTest, 226 public ::testing::WithParamInterface<NextProto> { 227 public: 228 virtual ~HttpNetworkTransactionTest() { 229 // Important to restore the per-pool limit first, since the pool limit must 230 // always be greater than group limit, and the tests reduce both limits. 231 ClientSocketPoolManager::set_max_sockets_per_pool( 232 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_); 233 ClientSocketPoolManager::set_max_sockets_per_group( 234 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_); 235 } 236 237 protected: 238 HttpNetworkTransactionTest() 239 : spdy_util_(GetParam()), 240 session_deps_(GetParam()), 241 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group( 242 HttpNetworkSession::NORMAL_SOCKET_POOL)), 243 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool( 244 HttpNetworkSession::NORMAL_SOCKET_POOL)) { 245 } 246 247 struct SimpleGetHelperResult { 248 int rv; 249 std::string status_line; 250 std::string response_data; 251 int64 totalReceivedBytes; 252 LoadTimingInfo load_timing_info; 253 }; 254 255 virtual void SetUp() { 256 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 257 base::MessageLoop::current()->RunUntilIdle(); 258 } 259 260 virtual void TearDown() { 261 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 262 base::MessageLoop::current()->RunUntilIdle(); 263 // Empty the current queue. 264 base::MessageLoop::current()->RunUntilIdle(); 265 PlatformTest::TearDown(); 266 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 267 base::MessageLoop::current()->RunUntilIdle(); 268 } 269 270 // This is the expected return from a current server advertising SPDY. 271 std::string GetAlternateProtocolHttpHeader() { 272 return 273 std::string("Alternate-Protocol: 443:") + 274 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) + 275 "\r\n\r\n"; 276 } 277 278 // Either |write_failure| specifies a write failure or |read_failure| 279 // specifies a read failure when using a reused socket. In either case, the 280 // failure should cause the network transaction to resend the request, and the 281 // other argument should be NULL. 282 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure, 283 const MockRead* read_failure); 284 285 // Either |write_failure| specifies a write failure or |read_failure| 286 // specifies a read failure when using a reused socket. In either case, the 287 // failure should cause the network transaction to resend the request, and the 288 // other argument should be NULL. 289 void PreconnectErrorResendRequestTest(const MockWrite* write_failure, 290 const MockRead* read_failure, 291 bool use_spdy); 292 293 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[], 294 size_t data_count) { 295 SimpleGetHelperResult out; 296 297 HttpRequestInfo request; 298 request.method = "GET"; 299 request.url = GURL("http://www.google.com/"); 300 request.load_flags = 0; 301 302 CapturingBoundNetLog log; 303 session_deps_.net_log = log.bound().net_log(); 304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 305 scoped_ptr<HttpTransaction> trans( 306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 307 308 for (size_t i = 0; i < data_count; ++i) { 309 session_deps_.socket_factory->AddSocketDataProvider(data[i]); 310 } 311 312 TestCompletionCallback callback; 313 314 EXPECT_TRUE(log.bound().IsLogging()); 315 int rv = trans->Start(&request, callback.callback(), log.bound()); 316 EXPECT_EQ(ERR_IO_PENDING, rv); 317 318 out.rv = callback.WaitForResult(); 319 320 // Even in the failure cases that use this function, connections are always 321 // successfully established before the error. 322 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info)); 323 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 324 325 if (out.rv != OK) 326 return out; 327 328 const HttpResponseInfo* response = trans->GetResponseInfo(); 329 // Can't use ASSERT_* inside helper functions like this, so 330 // return an error. 331 if (response == NULL || response->headers.get() == NULL) { 332 out.rv = ERR_UNEXPECTED; 333 return out; 334 } 335 out.status_line = response->headers->GetStatusLine(); 336 337 EXPECT_EQ("127.0.0.1", response->socket_address.host()); 338 EXPECT_EQ(80, response->socket_address.port()); 339 340 rv = ReadTransaction(trans.get(), &out.response_data); 341 EXPECT_EQ(OK, rv); 342 343 net::CapturingNetLog::CapturedEntryList entries; 344 log.GetEntries(&entries); 345 size_t pos = ExpectLogContainsSomewhere( 346 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, 347 NetLog::PHASE_NONE); 348 ExpectLogContainsSomewhere( 349 entries, pos, 350 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, 351 NetLog::PHASE_NONE); 352 353 std::string line; 354 EXPECT_TRUE(entries[pos].GetStringValue("line", &line)); 355 EXPECT_EQ("GET / HTTP/1.1\r\n", line); 356 357 HttpRequestHeaders request_headers; 358 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 359 std::string value; 360 EXPECT_TRUE(request_headers.GetHeader("Host", &value)); 361 EXPECT_EQ("www.google.com", value); 362 EXPECT_TRUE(request_headers.GetHeader("Connection", &value)); 363 EXPECT_EQ("keep-alive", value); 364 365 std::string response_headers; 366 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers)); 367 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']", 368 response_headers); 369 370 out.totalReceivedBytes = trans->GetTotalReceivedBytes(); 371 return out; 372 } 373 374 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[], 375 size_t reads_count) { 376 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0); 377 StaticSocketDataProvider* data[] = { &reads }; 378 return SimpleGetHelperForData(data, 1); 379 } 380 381 int64 ReadsSize(MockRead data_reads[], size_t reads_count) { 382 int64 size = 0; 383 for (size_t i = 0; i < reads_count; ++i) 384 size += data_reads[i].data_len; 385 return size; 386 } 387 388 void ConnectStatusHelperWithExpectedStatus(const MockRead& status, 389 int expected_status); 390 391 void ConnectStatusHelper(const MockRead& status); 392 393 void BypassHostCacheOnRefreshHelper(int load_flags); 394 395 void CheckErrorIsPassedBack(int error, IoMode mode); 396 397 SpdyTestUtil spdy_util_; 398 SpdySessionDependencies session_deps_; 399 400 // Original socket limits. Some tests set these. Safest to always restore 401 // them once each test has been run. 402 int old_max_group_sockets_; 403 int old_max_pool_sockets_; 404 }; 405 406 INSTANTIATE_TEST_CASE_P( 407 NextProto, 408 HttpNetworkTransactionTest, 409 testing::Values(kProtoDeprecatedSPDY2, 410 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4)); 411 412 namespace { 413 414 class BeforeNetworkStartHandler { 415 public: 416 explicit BeforeNetworkStartHandler(bool defer) 417 : defer_on_before_network_start_(defer), 418 observed_before_network_start_(false) {} 419 420 void OnBeforeNetworkStart(bool* defer) { 421 *defer = defer_on_before_network_start_; 422 observed_before_network_start_ = true; 423 } 424 425 bool observed_before_network_start() const { 426 return observed_before_network_start_; 427 } 428 429 private: 430 const bool defer_on_before_network_start_; 431 bool observed_before_network_start_; 432 433 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler); 434 }; 435 436 class BeforeProxyHeadersSentHandler { 437 public: 438 BeforeProxyHeadersSentHandler() 439 : observed_before_proxy_headers_sent_(false) {} 440 441 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info, 442 HttpRequestHeaders* request_headers) { 443 observed_before_proxy_headers_sent_ = true; 444 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI(); 445 } 446 447 bool observed_before_proxy_headers_sent() const { 448 return observed_before_proxy_headers_sent_; 449 } 450 451 std::string observed_proxy_server_uri() const { 452 return observed_proxy_server_uri_; 453 } 454 455 private: 456 bool observed_before_proxy_headers_sent_; 457 std::string observed_proxy_server_uri_; 458 459 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler); 460 }; 461 462 // Fill |str| with a long header list that consumes >= |size| bytes. 463 void FillLargeHeadersString(std::string* str, int size) { 464 const char* row = 465 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; 466 const int sizeof_row = strlen(row); 467 const int num_rows = static_cast<int>( 468 ceil(static_cast<float>(size) / sizeof_row)); 469 const int sizeof_data = num_rows * sizeof_row; 470 DCHECK(sizeof_data >= size); 471 str->reserve(sizeof_data); 472 473 for (int i = 0; i < num_rows; ++i) 474 str->append(row, sizeof_row); 475 } 476 477 // Alternative functions that eliminate randomness and dependency on the local 478 // host name so that the generated NTLM messages are reproducible. 479 void MockGenerateRandom1(uint8* output, size_t n) { 480 static const uint8 bytes[] = { 481 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54 482 }; 483 static size_t current_byte = 0; 484 for (size_t i = 0; i < n; ++i) { 485 output[i] = bytes[current_byte++]; 486 current_byte %= arraysize(bytes); 487 } 488 } 489 490 void MockGenerateRandom2(uint8* output, size_t n) { 491 static const uint8 bytes[] = { 492 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1, 493 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f 494 }; 495 static size_t current_byte = 0; 496 for (size_t i = 0; i < n; ++i) { 497 output[i] = bytes[current_byte++]; 498 current_byte %= arraysize(bytes); 499 } 500 } 501 502 std::string MockGetHostName() { 503 return "WTC-WIN7"; 504 } 505 506 template<typename ParentPool> 507 class CaptureGroupNameSocketPool : public ParentPool { 508 public: 509 CaptureGroupNameSocketPool(HostResolver* host_resolver, 510 CertVerifier* cert_verifier); 511 512 const std::string last_group_name_received() const { 513 return last_group_name_; 514 } 515 516 virtual int RequestSocket(const std::string& group_name, 517 const void* socket_params, 518 RequestPriority priority, 519 ClientSocketHandle* handle, 520 const CompletionCallback& callback, 521 const BoundNetLog& net_log) { 522 last_group_name_ = group_name; 523 return ERR_IO_PENDING; 524 } 525 virtual void CancelRequest(const std::string& group_name, 526 ClientSocketHandle* handle) {} 527 virtual void ReleaseSocket(const std::string& group_name, 528 scoped_ptr<StreamSocket> socket, 529 int id) {} 530 virtual void CloseIdleSockets() {} 531 virtual int IdleSocketCount() const { 532 return 0; 533 } 534 virtual int IdleSocketCountInGroup(const std::string& group_name) const { 535 return 0; 536 } 537 virtual LoadState GetLoadState(const std::string& group_name, 538 const ClientSocketHandle* handle) const { 539 return LOAD_STATE_IDLE; 540 } 541 virtual base::TimeDelta ConnectionTimeout() const { 542 return base::TimeDelta(); 543 } 544 545 private: 546 std::string last_group_name_; 547 }; 548 549 typedef CaptureGroupNameSocketPool<TransportClientSocketPool> 550 CaptureGroupNameTransportSocketPool; 551 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool> 552 CaptureGroupNameHttpProxySocketPool; 553 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool> 554 CaptureGroupNameSOCKSSocketPool; 555 typedef CaptureGroupNameSocketPool<SSLClientSocketPool> 556 CaptureGroupNameSSLSocketPool; 557 558 template<typename ParentPool> 559 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool( 560 HostResolver* host_resolver, 561 CertVerifier* /* cert_verifier */) 562 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {} 563 564 template<> 565 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool( 566 HostResolver* host_resolver, 567 CertVerifier* /* cert_verifier */) 568 : HttpProxyClientSocketPool( 569 0, 0, NULL, host_resolver, NULL, NULL, NULL, NULL) {} 570 571 template <> 572 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool( 573 HostResolver* host_resolver, 574 CertVerifier* cert_verifier) 575 : SSLClientSocketPool(0, 576 0, 577 NULL, 578 host_resolver, 579 cert_verifier, 580 NULL, 581 NULL, 582 NULL, 583 std::string(), 584 NULL, 585 NULL, 586 NULL, 587 NULL, 588 NULL, 589 false, 590 NULL) { 591 } 592 593 //----------------------------------------------------------------------------- 594 595 // Helper functions for validating that AuthChallengeInfo's are correctly 596 // configured for common cases. 597 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) { 598 if (!auth_challenge) 599 return false; 600 EXPECT_FALSE(auth_challenge->is_proxy); 601 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString()); 602 EXPECT_EQ("MyRealm1", auth_challenge->realm); 603 EXPECT_EQ("basic", auth_challenge->scheme); 604 return true; 605 } 606 607 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) { 608 if (!auth_challenge) 609 return false; 610 EXPECT_TRUE(auth_challenge->is_proxy); 611 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString()); 612 EXPECT_EQ("MyRealm1", auth_challenge->realm); 613 EXPECT_EQ("basic", auth_challenge->scheme); 614 return true; 615 } 616 617 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) { 618 if (!auth_challenge) 619 return false; 620 EXPECT_FALSE(auth_challenge->is_proxy); 621 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString()); 622 EXPECT_EQ("digestive", auth_challenge->realm); 623 EXPECT_EQ("digest", auth_challenge->scheme); 624 return true; 625 } 626 627 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) { 628 if (!auth_challenge) 629 return false; 630 EXPECT_FALSE(auth_challenge->is_proxy); 631 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString()); 632 EXPECT_EQ(std::string(), auth_challenge->realm); 633 EXPECT_EQ("ntlm", auth_challenge->scheme); 634 return true; 635 } 636 637 } // namespace 638 639 TEST_P(HttpNetworkTransactionTest, Basic) { 640 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 641 scoped_ptr<HttpTransaction> trans( 642 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 643 } 644 645 TEST_P(HttpNetworkTransactionTest, SimpleGET) { 646 MockRead data_reads[] = { 647 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 648 MockRead("hello world"), 649 MockRead(SYNCHRONOUS, OK), 650 }; 651 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 652 arraysize(data_reads)); 653 EXPECT_EQ(OK, out.rv); 654 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 655 EXPECT_EQ("hello world", out.response_data); 656 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 657 EXPECT_EQ(reads_size, out.totalReceivedBytes); 658 } 659 660 // Response with no status line. 661 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) { 662 MockRead data_reads[] = { 663 MockRead("hello world"), 664 MockRead(SYNCHRONOUS, OK), 665 }; 666 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 667 arraysize(data_reads)); 668 EXPECT_EQ(OK, out.rv); 669 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 670 EXPECT_EQ("hello world", out.response_data); 671 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 672 EXPECT_EQ(reads_size, out.totalReceivedBytes); 673 } 674 675 // Allow up to 4 bytes of junk to precede status line. 676 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) { 677 MockRead data_reads[] = { 678 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 679 MockRead(SYNCHRONOUS, OK), 680 }; 681 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 682 arraysize(data_reads)); 683 EXPECT_EQ(OK, out.rv); 684 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 685 EXPECT_EQ("DATA", out.response_data); 686 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 687 EXPECT_EQ(reads_size, out.totalReceivedBytes); 688 } 689 690 // Allow up to 4 bytes of junk to precede status line. 691 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { 692 MockRead data_reads[] = { 693 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 694 MockRead(SYNCHRONOUS, OK), 695 }; 696 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 697 arraysize(data_reads)); 698 EXPECT_EQ(OK, out.rv); 699 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 700 EXPECT_EQ("DATA", out.response_data); 701 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 702 EXPECT_EQ(reads_size, out.totalReceivedBytes); 703 } 704 705 // Beyond 4 bytes of slop and it should fail to find a status line. 706 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { 707 MockRead data_reads[] = { 708 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"), 709 MockRead(SYNCHRONOUS, OK), 710 }; 711 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 712 arraysize(data_reads)); 713 EXPECT_EQ(OK, out.rv); 714 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 715 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); 716 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 717 EXPECT_EQ(reads_size, out.totalReceivedBytes); 718 } 719 720 // Same as StatusLineJunk4Bytes, except the read chunks are smaller. 721 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { 722 MockRead data_reads[] = { 723 MockRead("\n"), 724 MockRead("\n"), 725 MockRead("Q"), 726 MockRead("J"), 727 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 728 MockRead(SYNCHRONOUS, OK), 729 }; 730 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 731 arraysize(data_reads)); 732 EXPECT_EQ(OK, out.rv); 733 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 734 EXPECT_EQ("DATA", out.response_data); 735 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 736 EXPECT_EQ(reads_size, out.totalReceivedBytes); 737 } 738 739 // Close the connection before enough bytes to have a status line. 740 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) { 741 MockRead data_reads[] = { 742 MockRead("HTT"), 743 MockRead(SYNCHRONOUS, OK), 744 }; 745 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 746 arraysize(data_reads)); 747 EXPECT_EQ(OK, out.rv); 748 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 749 EXPECT_EQ("HTT", out.response_data); 750 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 751 EXPECT_EQ(reads_size, out.totalReceivedBytes); 752 } 753 754 // Simulate a 204 response, lacking a Content-Length header, sent over a 755 // persistent connection. The response should still terminate since a 204 756 // cannot have a response body. 757 TEST_P(HttpNetworkTransactionTest, StopsReading204) { 758 char junk[] = "junk"; 759 MockRead data_reads[] = { 760 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 761 MockRead(junk), // Should not be read!! 762 MockRead(SYNCHRONOUS, OK), 763 }; 764 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 765 arraysize(data_reads)); 766 EXPECT_EQ(OK, out.rv); 767 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); 768 EXPECT_EQ("", out.response_data); 769 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 770 int64 response_size = reads_size - strlen(junk); 771 EXPECT_EQ(response_size, out.totalReceivedBytes); 772 } 773 774 // A simple request using chunked encoding with some extra data after. 775 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) { 776 std::string final_chunk = "0\r\n\r\n"; 777 std::string extra_data = "HTTP/1.1 200 OK\r\n"; 778 std::string last_read = final_chunk + extra_data; 779 MockRead data_reads[] = { 780 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"), 781 MockRead("5\r\nHello\r\n"), 782 MockRead("1\r\n"), 783 MockRead(" \r\n"), 784 MockRead("5\r\nworld\r\n"), 785 MockRead(last_read.data()), 786 MockRead(SYNCHRONOUS, OK), 787 }; 788 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 789 arraysize(data_reads)); 790 EXPECT_EQ(OK, out.rv); 791 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 792 EXPECT_EQ("Hello world", out.response_data); 793 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 794 int64 response_size = reads_size - extra_data.size(); 795 EXPECT_EQ(response_size, out.totalReceivedBytes); 796 } 797 798 // Next tests deal with http://crbug.com/56344. 799 800 TEST_P(HttpNetworkTransactionTest, 801 MultipleContentLengthHeadersNoTransferEncoding) { 802 MockRead data_reads[] = { 803 MockRead("HTTP/1.1 200 OK\r\n"), 804 MockRead("Content-Length: 10\r\n"), 805 MockRead("Content-Length: 5\r\n\r\n"), 806 }; 807 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 808 arraysize(data_reads)); 809 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 810 } 811 812 TEST_P(HttpNetworkTransactionTest, 813 DuplicateContentLengthHeadersNoTransferEncoding) { 814 MockRead data_reads[] = { 815 MockRead("HTTP/1.1 200 OK\r\n"), 816 MockRead("Content-Length: 5\r\n"), 817 MockRead("Content-Length: 5\r\n\r\n"), 818 MockRead("Hello"), 819 }; 820 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 821 arraysize(data_reads)); 822 EXPECT_EQ(OK, out.rv); 823 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 824 EXPECT_EQ("Hello", out.response_data); 825 } 826 827 TEST_P(HttpNetworkTransactionTest, 828 ComplexContentLengthHeadersNoTransferEncoding) { 829 // More than 2 dupes. 830 { 831 MockRead data_reads[] = { 832 MockRead("HTTP/1.1 200 OK\r\n"), 833 MockRead("Content-Length: 5\r\n"), 834 MockRead("Content-Length: 5\r\n"), 835 MockRead("Content-Length: 5\r\n\r\n"), 836 MockRead("Hello"), 837 }; 838 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 839 arraysize(data_reads)); 840 EXPECT_EQ(OK, out.rv); 841 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 842 EXPECT_EQ("Hello", out.response_data); 843 } 844 // HTTP/1.0 845 { 846 MockRead data_reads[] = { 847 MockRead("HTTP/1.0 200 OK\r\n"), 848 MockRead("Content-Length: 5\r\n"), 849 MockRead("Content-Length: 5\r\n"), 850 MockRead("Content-Length: 5\r\n\r\n"), 851 MockRead("Hello"), 852 }; 853 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 854 arraysize(data_reads)); 855 EXPECT_EQ(OK, out.rv); 856 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 857 EXPECT_EQ("Hello", out.response_data); 858 } 859 // 2 dupes and one mismatched. 860 { 861 MockRead data_reads[] = { 862 MockRead("HTTP/1.1 200 OK\r\n"), 863 MockRead("Content-Length: 10\r\n"), 864 MockRead("Content-Length: 10\r\n"), 865 MockRead("Content-Length: 5\r\n\r\n"), 866 }; 867 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 868 arraysize(data_reads)); 869 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 870 } 871 } 872 873 TEST_P(HttpNetworkTransactionTest, 874 MultipleContentLengthHeadersTransferEncoding) { 875 MockRead data_reads[] = { 876 MockRead("HTTP/1.1 200 OK\r\n"), 877 MockRead("Content-Length: 666\r\n"), 878 MockRead("Content-Length: 1337\r\n"), 879 MockRead("Transfer-Encoding: chunked\r\n\r\n"), 880 MockRead("5\r\nHello\r\n"), 881 MockRead("1\r\n"), 882 MockRead(" \r\n"), 883 MockRead("5\r\nworld\r\n"), 884 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"), 885 MockRead(SYNCHRONOUS, OK), 886 }; 887 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 888 arraysize(data_reads)); 889 EXPECT_EQ(OK, out.rv); 890 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 891 EXPECT_EQ("Hello world", out.response_data); 892 } 893 894 // Next tests deal with http://crbug.com/98895. 895 896 // Checks that a single Content-Disposition header results in no error. 897 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) { 898 MockRead data_reads[] = { 899 MockRead("HTTP/1.1 200 OK\r\n"), 900 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"), 901 MockRead("Content-Length: 5\r\n\r\n"), 902 MockRead("Hello"), 903 }; 904 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 905 arraysize(data_reads)); 906 EXPECT_EQ(OK, out.rv); 907 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 908 EXPECT_EQ("Hello", out.response_data); 909 } 910 911 // Checks that two identical Content-Disposition headers result in no error. 912 TEST_P(HttpNetworkTransactionTest, 913 TwoIdenticalContentDispositionHeaders) { 914 MockRead data_reads[] = { 915 MockRead("HTTP/1.1 200 OK\r\n"), 916 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 917 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 918 MockRead("Content-Length: 5\r\n\r\n"), 919 MockRead("Hello"), 920 }; 921 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 922 arraysize(data_reads)); 923 EXPECT_EQ(OK, out.rv); 924 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 925 EXPECT_EQ("Hello", out.response_data); 926 } 927 928 // Checks that two distinct Content-Disposition headers result in an error. 929 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) { 930 MockRead data_reads[] = { 931 MockRead("HTTP/1.1 200 OK\r\n"), 932 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 933 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"), 934 MockRead("Content-Length: 5\r\n\r\n"), 935 MockRead("Hello"), 936 }; 937 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 938 arraysize(data_reads)); 939 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv); 940 } 941 942 // Checks that two identical Location headers result in no error. 943 // Also tests Location header behavior. 944 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) { 945 MockRead data_reads[] = { 946 MockRead("HTTP/1.1 302 Redirect\r\n"), 947 MockRead("Location: http://good.com/\r\n"), 948 MockRead("Location: http://good.com/\r\n"), 949 MockRead("Content-Length: 0\r\n\r\n"), 950 MockRead(SYNCHRONOUS, OK), 951 }; 952 953 HttpRequestInfo request; 954 request.method = "GET"; 955 request.url = GURL("http://redirect.com/"); 956 request.load_flags = 0; 957 958 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 959 scoped_ptr<HttpTransaction> trans( 960 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 961 962 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 963 session_deps_.socket_factory->AddSocketDataProvider(&data); 964 965 TestCompletionCallback callback; 966 967 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 968 EXPECT_EQ(ERR_IO_PENDING, rv); 969 970 EXPECT_EQ(OK, callback.WaitForResult()); 971 972 const HttpResponseInfo* response = trans->GetResponseInfo(); 973 ASSERT_TRUE(response != NULL && response->headers.get() != NULL); 974 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine()); 975 std::string url; 976 EXPECT_TRUE(response->headers->IsRedirect(&url)); 977 EXPECT_EQ("http://good.com/", url); 978 EXPECT_TRUE(response->proxy_server.IsEmpty()); 979 } 980 981 // Checks that two distinct Location headers result in an error. 982 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) { 983 MockRead data_reads[] = { 984 MockRead("HTTP/1.1 302 Redirect\r\n"), 985 MockRead("Location: http://good.com/\r\n"), 986 MockRead("Location: http://evil.com/\r\n"), 987 MockRead("Content-Length: 0\r\n\r\n"), 988 MockRead(SYNCHRONOUS, OK), 989 }; 990 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 991 arraysize(data_reads)); 992 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv); 993 } 994 995 // Do a request using the HEAD method. Verify that we don't try to read the 996 // message body (since HEAD has none). 997 TEST_P(HttpNetworkTransactionTest, Head) { 998 HttpRequestInfo request; 999 request.method = "HEAD"; 1000 request.url = GURL("http://www.google.com/"); 1001 request.load_flags = 0; 1002 1003 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1004 scoped_ptr<HttpTransaction> trans( 1005 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1006 BeforeProxyHeadersSentHandler proxy_headers_handler; 1007 trans->SetBeforeProxyHeadersSentCallback( 1008 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent, 1009 base::Unretained(&proxy_headers_handler))); 1010 1011 MockWrite data_writes1[] = { 1012 MockWrite("HEAD / HTTP/1.1\r\n" 1013 "Host: www.google.com\r\n" 1014 "Connection: keep-alive\r\n" 1015 "Content-Length: 0\r\n\r\n"), 1016 }; 1017 MockRead data_reads1[] = { 1018 MockRead("HTTP/1.1 404 Not Found\r\n"), 1019 MockRead("Server: Blah\r\n"), 1020 MockRead("Content-Length: 1234\r\n\r\n"), 1021 1022 // No response body because the test stops reading here. 1023 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 1024 }; 1025 1026 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1027 data_writes1, arraysize(data_writes1)); 1028 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1029 1030 TestCompletionCallback callback1; 1031 1032 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1033 EXPECT_EQ(ERR_IO_PENDING, rv); 1034 1035 rv = callback1.WaitForResult(); 1036 EXPECT_EQ(OK, rv); 1037 1038 const HttpResponseInfo* response = trans->GetResponseInfo(); 1039 ASSERT_TRUE(response != NULL); 1040 1041 // Check that the headers got parsed. 1042 EXPECT_TRUE(response->headers.get() != NULL); 1043 EXPECT_EQ(1234, response->headers->GetContentLength()); 1044 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine()); 1045 EXPECT_TRUE(response->proxy_server.IsEmpty()); 1046 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent()); 1047 1048 std::string server_header; 1049 void* iter = NULL; 1050 bool has_server_header = response->headers->EnumerateHeader( 1051 &iter, "Server", &server_header); 1052 EXPECT_TRUE(has_server_header); 1053 EXPECT_EQ("Blah", server_header); 1054 1055 // Reading should give EOF right away, since there is no message body 1056 // (despite non-zero content-length). 1057 std::string response_data; 1058 rv = ReadTransaction(trans.get(), &response_data); 1059 EXPECT_EQ(OK, rv); 1060 EXPECT_EQ("", response_data); 1061 } 1062 1063 TEST_P(HttpNetworkTransactionTest, ReuseConnection) { 1064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1065 1066 MockRead data_reads[] = { 1067 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1068 MockRead("hello"), 1069 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1070 MockRead("world"), 1071 MockRead(SYNCHRONOUS, OK), 1072 }; 1073 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1074 session_deps_.socket_factory->AddSocketDataProvider(&data); 1075 1076 const char* const kExpectedResponseData[] = { 1077 "hello", "world" 1078 }; 1079 1080 for (int i = 0; i < 2; ++i) { 1081 HttpRequestInfo request; 1082 request.method = "GET"; 1083 request.url = GURL("http://www.google.com/"); 1084 request.load_flags = 0; 1085 1086 scoped_ptr<HttpTransaction> trans( 1087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1088 1089 TestCompletionCallback callback; 1090 1091 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1092 EXPECT_EQ(ERR_IO_PENDING, rv); 1093 1094 rv = callback.WaitForResult(); 1095 EXPECT_EQ(OK, rv); 1096 1097 const HttpResponseInfo* response = trans->GetResponseInfo(); 1098 ASSERT_TRUE(response != NULL); 1099 1100 EXPECT_TRUE(response->headers.get() != NULL); 1101 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1102 EXPECT_TRUE(response->proxy_server.IsEmpty()); 1103 1104 std::string response_data; 1105 rv = ReadTransaction(trans.get(), &response_data); 1106 EXPECT_EQ(OK, rv); 1107 EXPECT_EQ(kExpectedResponseData[i], response_data); 1108 } 1109 } 1110 1111 TEST_P(HttpNetworkTransactionTest, Ignores100) { 1112 ScopedVector<UploadElementReader> element_readers; 1113 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 1114 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 1115 1116 HttpRequestInfo request; 1117 request.method = "POST"; 1118 request.url = GURL("http://www.foo.com/"); 1119 request.upload_data_stream = &upload_data_stream; 1120 request.load_flags = 0; 1121 1122 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1123 scoped_ptr<HttpTransaction> trans( 1124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1125 1126 MockRead data_reads[] = { 1127 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 1128 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 1129 MockRead("hello world"), 1130 MockRead(SYNCHRONOUS, OK), 1131 }; 1132 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1133 session_deps_.socket_factory->AddSocketDataProvider(&data); 1134 1135 TestCompletionCallback callback; 1136 1137 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1138 EXPECT_EQ(ERR_IO_PENDING, rv); 1139 1140 rv = callback.WaitForResult(); 1141 EXPECT_EQ(OK, rv); 1142 1143 const HttpResponseInfo* response = trans->GetResponseInfo(); 1144 ASSERT_TRUE(response != NULL); 1145 1146 EXPECT_TRUE(response->headers.get() != NULL); 1147 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 1148 1149 std::string response_data; 1150 rv = ReadTransaction(trans.get(), &response_data); 1151 EXPECT_EQ(OK, rv); 1152 EXPECT_EQ("hello world", response_data); 1153 } 1154 1155 // This test is almost the same as Ignores100 above, but the response contains 1156 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is 1157 // HTTP/1.1 and the two status headers are read in one read. 1158 TEST_P(HttpNetworkTransactionTest, Ignores1xx) { 1159 HttpRequestInfo request; 1160 request.method = "GET"; 1161 request.url = GURL("http://www.foo.com/"); 1162 request.load_flags = 0; 1163 1164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1165 scoped_ptr<HttpTransaction> trans( 1166 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1167 1168 MockRead data_reads[] = { 1169 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n" 1170 "HTTP/1.1 200 OK\r\n\r\n"), 1171 MockRead("hello world"), 1172 MockRead(SYNCHRONOUS, OK), 1173 }; 1174 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1175 session_deps_.socket_factory->AddSocketDataProvider(&data); 1176 1177 TestCompletionCallback callback; 1178 1179 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1180 EXPECT_EQ(ERR_IO_PENDING, rv); 1181 1182 rv = callback.WaitForResult(); 1183 EXPECT_EQ(OK, rv); 1184 1185 const HttpResponseInfo* response = trans->GetResponseInfo(); 1186 ASSERT_TRUE(response != NULL); 1187 1188 EXPECT_TRUE(response->headers.get() != NULL); 1189 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1190 1191 std::string response_data; 1192 rv = ReadTransaction(trans.get(), &response_data); 1193 EXPECT_EQ(OK, rv); 1194 EXPECT_EQ("hello world", response_data); 1195 } 1196 1197 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) { 1198 HttpRequestInfo request; 1199 request.method = "POST"; 1200 request.url = GURL("http://www.foo.com/"); 1201 request.load_flags = 0; 1202 1203 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1204 scoped_ptr<HttpTransaction> trans( 1205 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1206 1207 MockRead data_reads[] = { 1208 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"), 1209 MockRead(ASYNC, 0), 1210 }; 1211 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1212 session_deps_.socket_factory->AddSocketDataProvider(&data); 1213 1214 TestCompletionCallback callback; 1215 1216 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1217 EXPECT_EQ(ERR_IO_PENDING, rv); 1218 1219 rv = callback.WaitForResult(); 1220 EXPECT_EQ(OK, rv); 1221 1222 std::string response_data; 1223 rv = ReadTransaction(trans.get(), &response_data); 1224 EXPECT_EQ(OK, rv); 1225 EXPECT_EQ("", response_data); 1226 } 1227 1228 TEST_P(HttpNetworkTransactionTest, EmptyResponse) { 1229 HttpRequestInfo request; 1230 request.method = "POST"; 1231 request.url = GURL("http://www.foo.com/"); 1232 request.load_flags = 0; 1233 1234 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1235 scoped_ptr<HttpTransaction> trans( 1236 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1237 1238 MockRead data_reads[] = { 1239 MockRead(ASYNC, 0), 1240 }; 1241 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1242 session_deps_.socket_factory->AddSocketDataProvider(&data); 1243 1244 TestCompletionCallback callback; 1245 1246 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1247 EXPECT_EQ(ERR_IO_PENDING, rv); 1248 1249 rv = callback.WaitForResult(); 1250 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 1251 } 1252 1253 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest( 1254 const MockWrite* write_failure, 1255 const MockRead* read_failure) { 1256 HttpRequestInfo request; 1257 request.method = "GET"; 1258 request.url = GURL("http://www.foo.com/"); 1259 request.load_flags = 0; 1260 1261 CapturingNetLog net_log; 1262 session_deps_.net_log = &net_log; 1263 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1264 1265 // Written data for successfully sending both requests. 1266 MockWrite data1_writes[] = { 1267 MockWrite("GET / HTTP/1.1\r\n" 1268 "Host: www.foo.com\r\n" 1269 "Connection: keep-alive\r\n\r\n"), 1270 MockWrite("GET / HTTP/1.1\r\n" 1271 "Host: www.foo.com\r\n" 1272 "Connection: keep-alive\r\n\r\n") 1273 }; 1274 1275 // Read results for the first request. 1276 MockRead data1_reads[] = { 1277 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1278 MockRead("hello"), 1279 MockRead(ASYNC, OK), 1280 }; 1281 1282 if (write_failure) { 1283 ASSERT_FALSE(read_failure); 1284 data1_writes[1] = *write_failure; 1285 } else { 1286 ASSERT_TRUE(read_failure); 1287 data1_reads[2] = *read_failure; 1288 } 1289 1290 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), 1291 data1_writes, arraysize(data1_writes)); 1292 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1293 1294 MockRead data2_reads[] = { 1295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1296 MockRead("world"), 1297 MockRead(ASYNC, OK), 1298 }; 1299 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 1300 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1301 1302 const char* kExpectedResponseData[] = { 1303 "hello", "world" 1304 }; 1305 1306 uint32 first_socket_log_id = NetLog::Source::kInvalidId; 1307 for (int i = 0; i < 2; ++i) { 1308 TestCompletionCallback callback; 1309 1310 scoped_ptr<HttpTransaction> trans( 1311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1312 1313 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1314 EXPECT_EQ(ERR_IO_PENDING, rv); 1315 1316 rv = callback.WaitForResult(); 1317 EXPECT_EQ(OK, rv); 1318 1319 LoadTimingInfo load_timing_info; 1320 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1321 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 1322 if (i == 0) { 1323 first_socket_log_id = load_timing_info.socket_log_id; 1324 } else { 1325 // The second request should be using a new socket. 1326 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id); 1327 } 1328 1329 const HttpResponseInfo* response = trans->GetResponseInfo(); 1330 ASSERT_TRUE(response != NULL); 1331 1332 EXPECT_TRUE(response->headers.get() != NULL); 1333 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1334 1335 std::string response_data; 1336 rv = ReadTransaction(trans.get(), &response_data); 1337 EXPECT_EQ(OK, rv); 1338 EXPECT_EQ(kExpectedResponseData[i], response_data); 1339 } 1340 } 1341 1342 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest( 1343 const MockWrite* write_failure, 1344 const MockRead* read_failure, 1345 bool use_spdy) { 1346 HttpRequestInfo request; 1347 request.method = "GET"; 1348 request.url = GURL("https://www.foo.com/"); 1349 request.load_flags = 0; 1350 1351 CapturingNetLog net_log; 1352 session_deps_.net_log = &net_log; 1353 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1354 1355 SSLSocketDataProvider ssl1(ASYNC, OK); 1356 SSLSocketDataProvider ssl2(ASYNC, OK); 1357 if (use_spdy) { 1358 ssl1.SetNextProto(GetParam()); 1359 ssl2.SetNextProto(GetParam()); 1360 } 1361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); 1362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 1363 1364 // SPDY versions of the request and response. 1365 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet( 1366 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY)); 1367 scoped_ptr<SpdyFrame> spdy_response( 1368 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1369 scoped_ptr<SpdyFrame> spdy_data( 1370 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true)); 1371 1372 // HTTP/1.1 versions of the request and response. 1373 const char kHttpRequest[] = "GET / HTTP/1.1\r\n" 1374 "Host: www.foo.com\r\n" 1375 "Connection: keep-alive\r\n\r\n"; 1376 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"; 1377 const char kHttpData[] = "hello"; 1378 1379 std::vector<MockRead> data1_reads; 1380 std::vector<MockWrite> data1_writes; 1381 if (write_failure) { 1382 ASSERT_FALSE(read_failure); 1383 data1_writes.push_back(*write_failure); 1384 data1_reads.push_back(MockRead(ASYNC, OK)); 1385 } else { 1386 ASSERT_TRUE(read_failure); 1387 if (use_spdy) { 1388 data1_writes.push_back(CreateMockWrite(*spdy_request)); 1389 } else { 1390 data1_writes.push_back(MockWrite(kHttpRequest)); 1391 } 1392 data1_reads.push_back(*read_failure); 1393 } 1394 1395 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(), 1396 &data1_writes[0], data1_writes.size()); 1397 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1398 1399 std::vector<MockRead> data2_reads; 1400 std::vector<MockWrite> data2_writes; 1401 1402 if (use_spdy) { 1403 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC)); 1404 1405 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC)); 1406 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC)); 1407 data2_reads.push_back(MockRead(ASYNC, OK, 3)); 1408 } else { 1409 data2_writes.push_back( 1410 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0)); 1411 1412 data2_reads.push_back( 1413 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1)); 1414 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2)); 1415 data2_reads.push_back(MockRead(ASYNC, OK, 3)); 1416 } 1417 OrderedSocketData data2(&data2_reads[0], data2_reads.size(), 1418 &data2_writes[0], data2_writes.size()); 1419 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1420 1421 // Preconnect a socket. 1422 net::SSLConfig ssl_config; 1423 session->ssl_config_service()->GetSSLConfig(&ssl_config); 1424 session->GetNextProtos(&ssl_config.next_protos); 1425 session->http_stream_factory()->PreconnectStreams( 1426 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config); 1427 // Wait for the preconnect to complete. 1428 // TODO(davidben): Some way to wait for an idle socket count might be handy. 1429 base::RunLoop().RunUntilIdle(); 1430 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 1431 1432 // Make the request. 1433 TestCompletionCallback callback; 1434 1435 scoped_ptr<HttpTransaction> trans( 1436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1437 1438 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1439 EXPECT_EQ(ERR_IO_PENDING, rv); 1440 1441 rv = callback.WaitForResult(); 1442 EXPECT_EQ(OK, rv); 1443 1444 LoadTimingInfo load_timing_info; 1445 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1446 TestLoadTimingNotReused( 1447 load_timing_info, 1448 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES); 1449 1450 const HttpResponseInfo* response = trans->GetResponseInfo(); 1451 ASSERT_TRUE(response != NULL); 1452 1453 EXPECT_TRUE(response->headers.get() != NULL); 1454 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1455 1456 std::string response_data; 1457 rv = ReadTransaction(trans.get(), &response_data); 1458 EXPECT_EQ(OK, rv); 1459 EXPECT_EQ(kHttpData, response_data); 1460 } 1461 1462 TEST_P(HttpNetworkTransactionTest, 1463 KeepAliveConnectionNotConnectedOnWrite) { 1464 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1465 KeepAliveConnectionResendRequestTest(&write_failure, NULL); 1466 } 1467 1468 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) { 1469 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1470 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1471 } 1472 1473 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { 1474 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1475 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1476 } 1477 1478 // Make sure that on a 408 response (Request Timeout), the request is retried, 1479 // if the socket was a reused keep alive socket. 1480 TEST_P(HttpNetworkTransactionTest, KeepAlive408) { 1481 MockRead read_failure(SYNCHRONOUS, 1482 "HTTP/1.1 408 Request Timeout\r\n" 1483 "Connection: Keep-Alive\r\n" 1484 "Content-Length: 6\r\n\r\n" 1485 "Pickle"); 1486 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1487 } 1488 1489 TEST_P(HttpNetworkTransactionTest, 1490 PreconnectErrorNotConnectedOnWrite) { 1491 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1492 PreconnectErrorResendRequestTest(&write_failure, NULL, false); 1493 } 1494 1495 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) { 1496 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1497 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1498 } 1499 1500 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) { 1501 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1502 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1503 } 1504 1505 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) { 1506 MockRead read_failure(ASYNC, OK); // EOF 1507 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1508 } 1509 1510 // Make sure that on a 408 response (Request Timeout), the request is retried, 1511 // if the socket was a preconnected (UNUSED_IDLE) socket. 1512 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) { 1513 MockRead read_failure(SYNCHRONOUS, 1514 "HTTP/1.1 408 Request Timeout\r\n" 1515 "Connection: Keep-Alive\r\n" 1516 "Content-Length: 6\r\n\r\n" 1517 "Pickle"); 1518 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1519 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1520 } 1521 1522 TEST_P(HttpNetworkTransactionTest, 1523 SpdyPreconnectErrorNotConnectedOnWrite) { 1524 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1525 PreconnectErrorResendRequestTest(&write_failure, NULL, true); 1526 } 1527 1528 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) { 1529 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1530 PreconnectErrorResendRequestTest(NULL, &read_failure, true); 1531 } 1532 1533 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) { 1534 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1535 PreconnectErrorResendRequestTest(NULL, &read_failure, true); 1536 } 1537 1538 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) { 1539 MockRead read_failure(ASYNC, OK); // EOF 1540 PreconnectErrorResendRequestTest(NULL, &read_failure, true); 1541 } 1542 1543 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { 1544 HttpRequestInfo request; 1545 request.method = "GET"; 1546 request.url = GURL("http://www.google.com/"); 1547 request.load_flags = 0; 1548 1549 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1550 scoped_ptr<HttpTransaction> trans( 1551 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1552 1553 MockRead data_reads[] = { 1554 MockRead(ASYNC, ERR_CONNECTION_RESET), 1555 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 1556 MockRead("hello world"), 1557 MockRead(SYNCHRONOUS, OK), 1558 }; 1559 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1560 session_deps_.socket_factory->AddSocketDataProvider(&data); 1561 1562 TestCompletionCallback callback; 1563 1564 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1565 EXPECT_EQ(ERR_IO_PENDING, rv); 1566 1567 rv = callback.WaitForResult(); 1568 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1569 1570 const HttpResponseInfo* response = trans->GetResponseInfo(); 1571 EXPECT_TRUE(response == NULL); 1572 } 1573 1574 // What do various browsers do when the server closes a non-keepalive 1575 // connection without sending any response header or body? 1576 // 1577 // IE7: error page 1578 // Safari 3.1.2 (Windows): error page 1579 // Firefox 3.0.1: blank page 1580 // Opera 9.52: after five attempts, blank page 1581 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE) 1582 // Us: error page (EMPTY_RESPONSE) 1583 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { 1584 MockRead data_reads[] = { 1585 MockRead(SYNCHRONOUS, OK), // EOF 1586 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 1587 MockRead("hello world"), 1588 MockRead(SYNCHRONOUS, OK), 1589 }; 1590 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 1591 arraysize(data_reads)); 1592 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); 1593 } 1594 1595 // Test that network access can be deferred and resumed. 1596 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) { 1597 HttpRequestInfo request; 1598 request.method = "GET"; 1599 request.url = GURL("http://www.google.com/"); 1600 request.load_flags = 0; 1601 1602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1603 scoped_ptr<HttpTransaction> trans( 1604 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1605 1606 // Defer on OnBeforeNetworkStart. 1607 BeforeNetworkStartHandler net_start_handler(true); // defer 1608 trans->SetBeforeNetworkStartCallback( 1609 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, 1610 base::Unretained(&net_start_handler))); 1611 1612 MockRead data_reads[] = { 1613 MockRead("HTTP/1.0 200 OK\r\n"), 1614 MockRead("Content-Length: 5\r\n\r\n"), 1615 MockRead("hello"), 1616 MockRead(SYNCHRONOUS, 0), 1617 }; 1618 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1619 session_deps_.socket_factory->AddSocketDataProvider(&data); 1620 1621 TestCompletionCallback callback; 1622 1623 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1624 EXPECT_EQ(ERR_IO_PENDING, rv); 1625 base::MessageLoop::current()->RunUntilIdle(); 1626 1627 // Should have deferred for network start. 1628 EXPECT_TRUE(net_start_handler.observed_before_network_start()); 1629 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); 1630 EXPECT_TRUE(trans->GetResponseInfo() == NULL); 1631 1632 trans->ResumeNetworkStart(); 1633 rv = callback.WaitForResult(); 1634 EXPECT_EQ(OK, rv); 1635 EXPECT_TRUE(trans->GetResponseInfo() != NULL); 1636 1637 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1638 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1639 if (rv == ERR_IO_PENDING) 1640 rv = callback.WaitForResult(); 1641 EXPECT_EQ(5, rv); 1642 trans.reset(); 1643 } 1644 1645 // Test that network use can be deferred and canceled. 1646 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) { 1647 HttpRequestInfo request; 1648 request.method = "GET"; 1649 request.url = GURL("http://www.google.com/"); 1650 request.load_flags = 0; 1651 1652 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1653 scoped_ptr<HttpTransaction> trans( 1654 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1655 1656 // Defer on OnBeforeNetworkStart. 1657 BeforeNetworkStartHandler net_start_handler(true); // defer 1658 trans->SetBeforeNetworkStartCallback( 1659 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, 1660 base::Unretained(&net_start_handler))); 1661 1662 TestCompletionCallback callback; 1663 1664 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1665 EXPECT_EQ(ERR_IO_PENDING, rv); 1666 base::MessageLoop::current()->RunUntilIdle(); 1667 1668 // Should have deferred for network start. 1669 EXPECT_TRUE(net_start_handler.observed_before_network_start()); 1670 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); 1671 EXPECT_TRUE(trans->GetResponseInfo() == NULL); 1672 } 1673 1674 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression 1675 // tests. There was a bug causing HttpNetworkTransaction to hang in the 1676 // destructor in such situations. 1677 // See http://crbug.com/154712 and http://crbug.com/156609. 1678 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) { 1679 HttpRequestInfo request; 1680 request.method = "GET"; 1681 request.url = GURL("http://www.google.com/"); 1682 request.load_flags = 0; 1683 1684 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1685 scoped_ptr<HttpTransaction> trans( 1686 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1687 1688 MockRead data_reads[] = { 1689 MockRead("HTTP/1.0 200 OK\r\n"), 1690 MockRead("Connection: keep-alive\r\n"), 1691 MockRead("Content-Length: 100\r\n\r\n"), 1692 MockRead("hello"), 1693 MockRead(SYNCHRONOUS, 0), 1694 }; 1695 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1696 session_deps_.socket_factory->AddSocketDataProvider(&data); 1697 1698 TestCompletionCallback callback; 1699 1700 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1701 EXPECT_EQ(ERR_IO_PENDING, rv); 1702 1703 rv = callback.WaitForResult(); 1704 EXPECT_EQ(OK, rv); 1705 1706 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1707 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1708 if (rv == ERR_IO_PENDING) 1709 rv = callback.WaitForResult(); 1710 EXPECT_EQ(5, rv); 1711 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1712 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 1713 1714 trans.reset(); 1715 base::MessageLoop::current()->RunUntilIdle(); 1716 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 1717 } 1718 1719 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) { 1720 HttpRequestInfo request; 1721 request.method = "GET"; 1722 request.url = GURL("http://www.google.com/"); 1723 request.load_flags = 0; 1724 1725 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1726 scoped_ptr<HttpTransaction> trans( 1727 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1728 1729 MockRead data_reads[] = { 1730 MockRead("HTTP/1.0 200 OK\r\n"), 1731 MockRead("Connection: keep-alive\r\n"), 1732 MockRead("Content-Length: 100\r\n\r\n"), 1733 MockRead(SYNCHRONOUS, 0), 1734 }; 1735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1736 session_deps_.socket_factory->AddSocketDataProvider(&data); 1737 1738 TestCompletionCallback callback; 1739 1740 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1741 EXPECT_EQ(ERR_IO_PENDING, rv); 1742 1743 rv = callback.WaitForResult(); 1744 EXPECT_EQ(OK, rv); 1745 1746 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1747 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1748 if (rv == ERR_IO_PENDING) 1749 rv = callback.WaitForResult(); 1750 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 1751 1752 trans.reset(); 1753 base::MessageLoop::current()->RunUntilIdle(); 1754 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 1755 } 1756 1757 // Test that we correctly reuse a keep-alive connection after not explicitly 1758 // reading the body. 1759 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { 1760 HttpRequestInfo request; 1761 request.method = "GET"; 1762 request.url = GURL("http://www.foo.com/"); 1763 request.load_flags = 0; 1764 1765 CapturingNetLog net_log; 1766 session_deps_.net_log = &net_log; 1767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1768 1769 // Note that because all these reads happen in the same 1770 // StaticSocketDataProvider, it shows that the same socket is being reused for 1771 // all transactions. 1772 MockRead data1_reads[] = { 1773 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 1774 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"), 1775 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"), 1776 MockRead("HTTP/1.1 302 Found\r\n" 1777 "Content-Length: 0\r\n\r\n"), 1778 MockRead("HTTP/1.1 302 Found\r\n" 1779 "Content-Length: 5\r\n\r\n" 1780 "hello"), 1781 MockRead("HTTP/1.1 301 Moved Permanently\r\n" 1782 "Content-Length: 0\r\n\r\n"), 1783 MockRead("HTTP/1.1 301 Moved Permanently\r\n" 1784 "Content-Length: 5\r\n\r\n" 1785 "hello"), 1786 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1787 MockRead("hello"), 1788 }; 1789 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0); 1790 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1791 1792 MockRead data2_reads[] = { 1793 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 1794 }; 1795 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 1796 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1797 1798 const int kNumUnreadBodies = arraysize(data1_reads) - 2; 1799 std::string response_lines[kNumUnreadBodies]; 1800 1801 uint32 first_socket_log_id = NetLog::Source::kInvalidId; 1802 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) { 1803 TestCompletionCallback callback; 1804 1805 scoped_ptr<HttpTransaction> trans( 1806 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1807 1808 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1809 EXPECT_EQ(ERR_IO_PENDING, rv); 1810 1811 rv = callback.WaitForResult(); 1812 EXPECT_EQ(OK, rv); 1813 1814 LoadTimingInfo load_timing_info; 1815 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1816 if (i == 0) { 1817 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 1818 first_socket_log_id = load_timing_info.socket_log_id; 1819 } else { 1820 TestLoadTimingReused(load_timing_info); 1821 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id); 1822 } 1823 1824 const HttpResponseInfo* response = trans->GetResponseInfo(); 1825 ASSERT_TRUE(response != NULL); 1826 1827 ASSERT_TRUE(response->headers.get() != NULL); 1828 response_lines[i] = response->headers->GetStatusLine(); 1829 1830 // We intentionally don't read the response bodies. 1831 } 1832 1833 const char* const kStatusLines[] = { 1834 "HTTP/1.1 204 No Content", 1835 "HTTP/1.1 205 Reset Content", 1836 "HTTP/1.1 304 Not Modified", 1837 "HTTP/1.1 302 Found", 1838 "HTTP/1.1 302 Found", 1839 "HTTP/1.1 301 Moved Permanently", 1840 "HTTP/1.1 301 Moved Permanently", 1841 }; 1842 1843 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines), 1844 forgot_to_update_kStatusLines); 1845 1846 for (int i = 0; i < kNumUnreadBodies; ++i) 1847 EXPECT_EQ(kStatusLines[i], response_lines[i]); 1848 1849 TestCompletionCallback callback; 1850 scoped_ptr<HttpTransaction> trans( 1851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1852 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1853 EXPECT_EQ(ERR_IO_PENDING, rv); 1854 rv = callback.WaitForResult(); 1855 EXPECT_EQ(OK, rv); 1856 const HttpResponseInfo* response = trans->GetResponseInfo(); 1857 ASSERT_TRUE(response != NULL); 1858 ASSERT_TRUE(response->headers.get() != NULL); 1859 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1860 std::string response_data; 1861 rv = ReadTransaction(trans.get(), &response_data); 1862 EXPECT_EQ(OK, rv); 1863 EXPECT_EQ("hello", response_data); 1864 } 1865 1866 // Test the request-challenge-retry sequence for basic auth. 1867 // (basic auth is the easiest to mock, because it has no randomness). 1868 TEST_P(HttpNetworkTransactionTest, BasicAuth) { 1869 HttpRequestInfo request; 1870 request.method = "GET"; 1871 request.url = GURL("http://www.google.com/"); 1872 request.load_flags = 0; 1873 1874 CapturingNetLog log; 1875 session_deps_.net_log = &log; 1876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1877 scoped_ptr<HttpTransaction> trans( 1878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1879 1880 MockWrite data_writes1[] = { 1881 MockWrite("GET / HTTP/1.1\r\n" 1882 "Host: www.google.com\r\n" 1883 "Connection: keep-alive\r\n\r\n"), 1884 }; 1885 1886 MockRead data_reads1[] = { 1887 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1888 // Give a couple authenticate options (only the middle one is actually 1889 // supported). 1890 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed. 1891 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1892 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 1893 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1894 // Large content-length -- won't matter, as connection will be reset. 1895 MockRead("Content-Length: 10000\r\n\r\n"), 1896 MockRead(SYNCHRONOUS, ERR_FAILED), 1897 }; 1898 1899 // After calling trans->RestartWithAuth(), this is the request we should 1900 // be issuing -- the final header line contains the credentials. 1901 MockWrite data_writes2[] = { 1902 MockWrite("GET / HTTP/1.1\r\n" 1903 "Host: www.google.com\r\n" 1904 "Connection: keep-alive\r\n" 1905 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1906 }; 1907 1908 // Lastly, the server responds with the actual content. 1909 MockRead data_reads2[] = { 1910 MockRead("HTTP/1.0 200 OK\r\n"), 1911 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1912 MockRead("Content-Length: 100\r\n\r\n"), 1913 MockRead(SYNCHRONOUS, OK), 1914 }; 1915 1916 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1917 data_writes1, arraysize(data_writes1)); 1918 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1919 data_writes2, arraysize(data_writes2)); 1920 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1921 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1922 1923 TestCompletionCallback callback1; 1924 1925 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1926 EXPECT_EQ(ERR_IO_PENDING, rv); 1927 1928 rv = callback1.WaitForResult(); 1929 EXPECT_EQ(OK, rv); 1930 1931 LoadTimingInfo load_timing_info1; 1932 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); 1933 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); 1934 1935 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1)); 1936 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); 1937 1938 const HttpResponseInfo* response = trans->GetResponseInfo(); 1939 ASSERT_TRUE(response != NULL); 1940 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 1941 1942 TestCompletionCallback callback2; 1943 1944 rv = trans->RestartWithAuth( 1945 AuthCredentials(kFoo, kBar), callback2.callback()); 1946 EXPECT_EQ(ERR_IO_PENDING, rv); 1947 1948 rv = callback2.WaitForResult(); 1949 EXPECT_EQ(OK, rv); 1950 1951 LoadTimingInfo load_timing_info2; 1952 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); 1953 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES); 1954 // The load timing after restart should have a new socket ID, and times after 1955 // those of the first load timing. 1956 EXPECT_LE(load_timing_info1.receive_headers_end, 1957 load_timing_info2.connect_timing.connect_start); 1958 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 1959 1960 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2)); 1961 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes()); 1962 1963 response = trans->GetResponseInfo(); 1964 ASSERT_TRUE(response != NULL); 1965 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1966 EXPECT_EQ(100, response->headers->GetContentLength()); 1967 } 1968 1969 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) { 1970 HttpRequestInfo request; 1971 request.method = "GET"; 1972 request.url = GURL("http://www.google.com/"); 1973 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 1974 1975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1976 scoped_ptr<HttpTransaction> trans( 1977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1978 1979 MockWrite data_writes[] = { 1980 MockWrite("GET / HTTP/1.1\r\n" 1981 "Host: www.google.com\r\n" 1982 "Connection: keep-alive\r\n\r\n"), 1983 }; 1984 1985 MockRead data_reads[] = { 1986 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1987 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1988 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1989 // Large content-length -- won't matter, as connection will be reset. 1990 MockRead("Content-Length: 10000\r\n\r\n"), 1991 MockRead(SYNCHRONOUS, ERR_FAILED), 1992 }; 1993 1994 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 1995 data_writes, arraysize(data_writes)); 1996 session_deps_.socket_factory->AddSocketDataProvider(&data); 1997 TestCompletionCallback callback; 1998 1999 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 2000 EXPECT_EQ(ERR_IO_PENDING, rv); 2001 2002 rv = callback.WaitForResult(); 2003 EXPECT_EQ(0, rv); 2004 2005 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 2006 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes()); 2007 2008 const HttpResponseInfo* response = trans->GetResponseInfo(); 2009 ASSERT_TRUE(response != NULL); 2010 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2011 } 2012 2013 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2014 // connection. 2015 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) { 2016 HttpRequestInfo request; 2017 request.method = "GET"; 2018 request.url = GURL("http://www.google.com/"); 2019 request.load_flags = 0; 2020 2021 CapturingNetLog log; 2022 session_deps_.net_log = &log; 2023 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2024 2025 MockWrite data_writes1[] = { 2026 MockWrite("GET / HTTP/1.1\r\n" 2027 "Host: www.google.com\r\n" 2028 "Connection: keep-alive\r\n\r\n"), 2029 2030 // After calling trans->RestartWithAuth(), this is the request we should 2031 // be issuing -- the final header line contains the credentials. 2032 MockWrite("GET / HTTP/1.1\r\n" 2033 "Host: www.google.com\r\n" 2034 "Connection: keep-alive\r\n" 2035 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2036 }; 2037 2038 MockRead data_reads1[] = { 2039 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2040 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2041 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2042 MockRead("Content-Length: 14\r\n\r\n"), 2043 MockRead("Unauthorized\r\n"), 2044 2045 // Lastly, the server responds with the actual content. 2046 MockRead("HTTP/1.1 200 OK\r\n"), 2047 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2048 MockRead("Content-Length: 5\r\n\r\n"), 2049 MockRead("Hello"), 2050 }; 2051 2052 // If there is a regression where we disconnect a Keep-Alive 2053 // connection during an auth roundtrip, we'll end up reading this. 2054 MockRead data_reads2[] = { 2055 MockRead(SYNCHRONOUS, ERR_FAILED), 2056 }; 2057 2058 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2059 data_writes1, arraysize(data_writes1)); 2060 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2061 NULL, 0); 2062 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2063 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2064 2065 TestCompletionCallback callback1; 2066 2067 scoped_ptr<HttpTransaction> trans( 2068 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2069 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2070 EXPECT_EQ(ERR_IO_PENDING, rv); 2071 2072 rv = callback1.WaitForResult(); 2073 EXPECT_EQ(OK, rv); 2074 2075 LoadTimingInfo load_timing_info1; 2076 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); 2077 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); 2078 2079 const HttpResponseInfo* response = trans->GetResponseInfo(); 2080 ASSERT_TRUE(response != NULL); 2081 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2082 2083 TestCompletionCallback callback2; 2084 2085 rv = trans->RestartWithAuth( 2086 AuthCredentials(kFoo, kBar), callback2.callback()); 2087 EXPECT_EQ(ERR_IO_PENDING, rv); 2088 2089 rv = callback2.WaitForResult(); 2090 EXPECT_EQ(OK, rv); 2091 2092 LoadTimingInfo load_timing_info2; 2093 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); 2094 TestLoadTimingReused(load_timing_info2); 2095 // The load timing after restart should have the same socket ID, and times 2096 // those of the first load timing. 2097 EXPECT_LE(load_timing_info1.receive_headers_end, 2098 load_timing_info2.send_start); 2099 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2100 2101 response = trans->GetResponseInfo(); 2102 ASSERT_TRUE(response != NULL); 2103 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2104 EXPECT_EQ(5, response->headers->GetContentLength()); 2105 2106 std::string response_data; 2107 rv = ReadTransaction(trans.get(), &response_data); 2108 EXPECT_EQ(OK, rv); 2109 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1)); 2110 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); 2111 } 2112 2113 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2114 // connection and with no response body to drain. 2115 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { 2116 HttpRequestInfo request; 2117 request.method = "GET"; 2118 request.url = GURL("http://www.google.com/"); 2119 request.load_flags = 0; 2120 2121 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2122 2123 MockWrite data_writes1[] = { 2124 MockWrite("GET / HTTP/1.1\r\n" 2125 "Host: www.google.com\r\n" 2126 "Connection: keep-alive\r\n\r\n"), 2127 2128 // After calling trans->RestartWithAuth(), this is the request we should 2129 // be issuing -- the final header line contains the credentials. 2130 MockWrite("GET / HTTP/1.1\r\n" 2131 "Host: www.google.com\r\n" 2132 "Connection: keep-alive\r\n" 2133 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2134 }; 2135 2136 MockRead data_reads1[] = { 2137 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2139 MockRead("Content-Length: 0\r\n\r\n"), // No response body. 2140 2141 // Lastly, the server responds with the actual content. 2142 MockRead("HTTP/1.1 200 OK\r\n"), 2143 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2144 MockRead("Content-Length: 5\r\n\r\n"), 2145 MockRead("hello"), 2146 }; 2147 2148 // An incorrect reconnect would cause this to be read. 2149 MockRead data_reads2[] = { 2150 MockRead(SYNCHRONOUS, ERR_FAILED), 2151 }; 2152 2153 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2154 data_writes1, arraysize(data_writes1)); 2155 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2156 NULL, 0); 2157 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2158 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2159 2160 TestCompletionCallback callback1; 2161 2162 scoped_ptr<HttpTransaction> trans( 2163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2164 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2165 EXPECT_EQ(ERR_IO_PENDING, rv); 2166 2167 rv = callback1.WaitForResult(); 2168 EXPECT_EQ(OK, rv); 2169 2170 const HttpResponseInfo* response = trans->GetResponseInfo(); 2171 ASSERT_TRUE(response != NULL); 2172 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2173 2174 TestCompletionCallback callback2; 2175 2176 rv = trans->RestartWithAuth( 2177 AuthCredentials(kFoo, kBar), callback2.callback()); 2178 EXPECT_EQ(ERR_IO_PENDING, rv); 2179 2180 rv = callback2.WaitForResult(); 2181 EXPECT_EQ(OK, rv); 2182 2183 response = trans->GetResponseInfo(); 2184 ASSERT_TRUE(response != NULL); 2185 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2186 EXPECT_EQ(5, response->headers->GetContentLength()); 2187 } 2188 2189 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2190 // connection and with a large response body to drain. 2191 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { 2192 HttpRequestInfo request; 2193 request.method = "GET"; 2194 request.url = GURL("http://www.google.com/"); 2195 request.load_flags = 0; 2196 2197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2198 2199 MockWrite data_writes1[] = { 2200 MockWrite("GET / HTTP/1.1\r\n" 2201 "Host: www.google.com\r\n" 2202 "Connection: keep-alive\r\n\r\n"), 2203 2204 // After calling trans->RestartWithAuth(), this is the request we should 2205 // be issuing -- the final header line contains the credentials. 2206 MockWrite("GET / HTTP/1.1\r\n" 2207 "Host: www.google.com\r\n" 2208 "Connection: keep-alive\r\n" 2209 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2210 }; 2211 2212 // Respond with 5 kb of response body. 2213 std::string large_body_string("Unauthorized"); 2214 large_body_string.append(5 * 1024, ' '); 2215 large_body_string.append("\r\n"); 2216 2217 MockRead data_reads1[] = { 2218 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2219 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2220 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2221 // 5134 = 12 + 5 * 1024 + 2 2222 MockRead("Content-Length: 5134\r\n\r\n"), 2223 MockRead(ASYNC, large_body_string.data(), large_body_string.size()), 2224 2225 // Lastly, the server responds with the actual content. 2226 MockRead("HTTP/1.1 200 OK\r\n"), 2227 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2228 MockRead("Content-Length: 5\r\n\r\n"), 2229 MockRead("hello"), 2230 }; 2231 2232 // An incorrect reconnect would cause this to be read. 2233 MockRead data_reads2[] = { 2234 MockRead(SYNCHRONOUS, ERR_FAILED), 2235 }; 2236 2237 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2238 data_writes1, arraysize(data_writes1)); 2239 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2240 NULL, 0); 2241 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2242 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2243 2244 TestCompletionCallback callback1; 2245 2246 scoped_ptr<HttpTransaction> trans( 2247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2248 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2249 EXPECT_EQ(ERR_IO_PENDING, rv); 2250 2251 rv = callback1.WaitForResult(); 2252 EXPECT_EQ(OK, rv); 2253 2254 const HttpResponseInfo* response = trans->GetResponseInfo(); 2255 ASSERT_TRUE(response != NULL); 2256 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2257 2258 TestCompletionCallback callback2; 2259 2260 rv = trans->RestartWithAuth( 2261 AuthCredentials(kFoo, kBar), callback2.callback()); 2262 EXPECT_EQ(ERR_IO_PENDING, rv); 2263 2264 rv = callback2.WaitForResult(); 2265 EXPECT_EQ(OK, rv); 2266 2267 response = trans->GetResponseInfo(); 2268 ASSERT_TRUE(response != NULL); 2269 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2270 EXPECT_EQ(5, response->headers->GetContentLength()); 2271 } 2272 2273 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2274 // connection, but the server gets impatient and closes the connection. 2275 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { 2276 HttpRequestInfo request; 2277 request.method = "GET"; 2278 request.url = GURL("http://www.google.com/"); 2279 request.load_flags = 0; 2280 2281 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2282 2283 MockWrite data_writes1[] = { 2284 MockWrite("GET / HTTP/1.1\r\n" 2285 "Host: www.google.com\r\n" 2286 "Connection: keep-alive\r\n\r\n"), 2287 // This simulates the seemingly successful write to a closed connection 2288 // if the bug is not fixed. 2289 MockWrite("GET / HTTP/1.1\r\n" 2290 "Host: www.google.com\r\n" 2291 "Connection: keep-alive\r\n" 2292 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2293 }; 2294 2295 MockRead data_reads1[] = { 2296 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2297 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2299 MockRead("Content-Length: 14\r\n\r\n"), 2300 // Tell MockTCPClientSocket to simulate the server closing the connection. 2301 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 2302 MockRead("Unauthorized\r\n"), 2303 MockRead(SYNCHRONOUS, OK), // The server closes the connection. 2304 }; 2305 2306 // After calling trans->RestartWithAuth(), this is the request we should 2307 // be issuing -- the final header line contains the credentials. 2308 MockWrite data_writes2[] = { 2309 MockWrite("GET / HTTP/1.1\r\n" 2310 "Host: www.google.com\r\n" 2311 "Connection: keep-alive\r\n" 2312 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2313 }; 2314 2315 // Lastly, the server responds with the actual content. 2316 MockRead data_reads2[] = { 2317 MockRead("HTTP/1.1 200 OK\r\n"), 2318 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2319 MockRead("Content-Length: 5\r\n\r\n"), 2320 MockRead("hello"), 2321 }; 2322 2323 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2324 data_writes1, arraysize(data_writes1)); 2325 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2326 data_writes2, arraysize(data_writes2)); 2327 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2328 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2329 2330 TestCompletionCallback callback1; 2331 2332 scoped_ptr<HttpTransaction> trans( 2333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2334 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2335 EXPECT_EQ(ERR_IO_PENDING, rv); 2336 2337 rv = callback1.WaitForResult(); 2338 EXPECT_EQ(OK, rv); 2339 2340 const HttpResponseInfo* response = trans->GetResponseInfo(); 2341 ASSERT_TRUE(response != NULL); 2342 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2343 2344 TestCompletionCallback callback2; 2345 2346 rv = trans->RestartWithAuth( 2347 AuthCredentials(kFoo, kBar), callback2.callback()); 2348 EXPECT_EQ(ERR_IO_PENDING, rv); 2349 2350 rv = callback2.WaitForResult(); 2351 EXPECT_EQ(OK, rv); 2352 2353 response = trans->GetResponseInfo(); 2354 ASSERT_TRUE(response != NULL); 2355 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2356 EXPECT_EQ(5, response->headers->GetContentLength()); 2357 } 2358 2359 // Test the request-challenge-retry sequence for basic auth, over a connection 2360 // that requires a restart when setting up an SSL tunnel. 2361 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { 2362 HttpRequestInfo request; 2363 request.method = "GET"; 2364 request.url = GURL("https://www.google.com/"); 2365 // when the no authentication data flag is set. 2366 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 2367 2368 // Configure against proxy server "myproxy:70". 2369 session_deps_.proxy_service.reset( 2370 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 2371 CapturingBoundNetLog log; 2372 session_deps_.net_log = log.bound().net_log(); 2373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2374 2375 // Since we have proxy, should try to establish tunnel. 2376 MockWrite data_writes1[] = { 2377 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2378 "Host: www.google.com\r\n" 2379 "Proxy-Connection: keep-alive\r\n\r\n"), 2380 2381 // After calling trans->RestartWithAuth(), this is the request we should 2382 // be issuing -- the final header line contains the credentials. 2383 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2384 "Host: www.google.com\r\n" 2385 "Proxy-Connection: keep-alive\r\n" 2386 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2387 2388 MockWrite("GET / HTTP/1.1\r\n" 2389 "Host: www.google.com\r\n" 2390 "Connection: keep-alive\r\n\r\n"), 2391 }; 2392 2393 // The proxy responds to the connect with a 407, using a persistent 2394 // connection. 2395 MockRead data_reads1[] = { 2396 // No credentials. 2397 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2398 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2399 MockRead("Proxy-Connection: close\r\n\r\n"), 2400 2401 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2402 2403 MockRead("HTTP/1.1 200 OK\r\n"), 2404 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2405 MockRead("Content-Length: 5\r\n\r\n"), 2406 MockRead(SYNCHRONOUS, "hello"), 2407 }; 2408 2409 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2410 data_writes1, arraysize(data_writes1)); 2411 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2412 SSLSocketDataProvider ssl(ASYNC, OK); 2413 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2414 2415 TestCompletionCallback callback1; 2416 2417 scoped_ptr<HttpTransaction> trans( 2418 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2419 2420 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2421 EXPECT_EQ(ERR_IO_PENDING, rv); 2422 2423 rv = callback1.WaitForResult(); 2424 EXPECT_EQ(OK, rv); 2425 net::CapturingNetLog::CapturedEntryList entries; 2426 log.GetEntries(&entries); 2427 size_t pos = ExpectLogContainsSomewhere( 2428 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2429 NetLog::PHASE_NONE); 2430 ExpectLogContainsSomewhere( 2431 entries, pos, 2432 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2433 NetLog::PHASE_NONE); 2434 2435 const HttpResponseInfo* response = trans->GetResponseInfo(); 2436 ASSERT_TRUE(response != NULL); 2437 ASSERT_FALSE(response->headers.get() == NULL); 2438 EXPECT_EQ(407, response->headers->response_code()); 2439 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2440 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2441 2442 LoadTimingInfo load_timing_info; 2443 // CONNECT requests and responses are handled at the connect job level, so 2444 // the transaction does not yet have a connection. 2445 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); 2446 2447 TestCompletionCallback callback2; 2448 2449 rv = trans->RestartWithAuth( 2450 AuthCredentials(kFoo, kBar), callback2.callback()); 2451 EXPECT_EQ(ERR_IO_PENDING, rv); 2452 2453 rv = callback2.WaitForResult(); 2454 EXPECT_EQ(OK, rv); 2455 2456 response = trans->GetResponseInfo(); 2457 ASSERT_TRUE(response != NULL); 2458 2459 EXPECT_TRUE(response->headers->IsKeepAlive()); 2460 EXPECT_EQ(200, response->headers->response_code()); 2461 EXPECT_EQ(5, response->headers->GetContentLength()); 2462 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2463 2464 // The password prompt info should not be set. 2465 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2466 2467 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2468 TestLoadTimingNotReusedWithPac(load_timing_info, 2469 CONNECT_TIMING_HAS_SSL_TIMES); 2470 2471 trans.reset(); 2472 session->CloseAllConnections(); 2473 } 2474 2475 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2476 // proxy connection, when setting up an SSL tunnel. 2477 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { 2478 HttpRequestInfo request; 2479 request.method = "GET"; 2480 request.url = GURL("https://www.google.com/"); 2481 // Ensure that proxy authentication is attempted even 2482 // when the no authentication data flag is set. 2483 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 2484 2485 // Configure against proxy server "myproxy:70". 2486 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2487 CapturingBoundNetLog log; 2488 session_deps_.net_log = log.bound().net_log(); 2489 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2490 2491 scoped_ptr<HttpTransaction> trans( 2492 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2493 2494 // Since we have proxy, should try to establish tunnel. 2495 MockWrite data_writes1[] = { 2496 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2497 "Host: www.google.com\r\n" 2498 "Proxy-Connection: keep-alive\r\n\r\n"), 2499 2500 // After calling trans->RestartWithAuth(), this is the request we should 2501 // be issuing -- the final header line contains the credentials. 2502 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2503 "Host: www.google.com\r\n" 2504 "Proxy-Connection: keep-alive\r\n" 2505 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 2506 }; 2507 2508 // The proxy responds to the connect with a 407, using a persistent 2509 // connection. 2510 MockRead data_reads1[] = { 2511 // No credentials. 2512 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2513 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2514 MockRead("Content-Length: 10\r\n\r\n"), 2515 MockRead("0123456789"), 2516 2517 // Wrong credentials (wrong password). 2518 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2519 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2520 MockRead("Content-Length: 10\r\n\r\n"), 2521 // No response body because the test stops reading here. 2522 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 2523 }; 2524 2525 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2526 data_writes1, arraysize(data_writes1)); 2527 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2528 2529 TestCompletionCallback callback1; 2530 2531 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2532 EXPECT_EQ(ERR_IO_PENDING, rv); 2533 2534 rv = callback1.WaitForResult(); 2535 EXPECT_EQ(OK, rv); 2536 net::CapturingNetLog::CapturedEntryList entries; 2537 log.GetEntries(&entries); 2538 size_t pos = ExpectLogContainsSomewhere( 2539 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2540 NetLog::PHASE_NONE); 2541 ExpectLogContainsSomewhere( 2542 entries, pos, 2543 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2544 NetLog::PHASE_NONE); 2545 2546 const HttpResponseInfo* response = trans->GetResponseInfo(); 2547 ASSERT_TRUE(response != NULL); 2548 ASSERT_FALSE(response->headers.get() == NULL); 2549 EXPECT_TRUE(response->headers->IsKeepAlive()); 2550 EXPECT_EQ(407, response->headers->response_code()); 2551 EXPECT_EQ(10, response->headers->GetContentLength()); 2552 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2553 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2554 2555 TestCompletionCallback callback2; 2556 2557 // Wrong password (should be "bar"). 2558 rv = trans->RestartWithAuth( 2559 AuthCredentials(kFoo, kBaz), callback2.callback()); 2560 EXPECT_EQ(ERR_IO_PENDING, rv); 2561 2562 rv = callback2.WaitForResult(); 2563 EXPECT_EQ(OK, rv); 2564 2565 response = trans->GetResponseInfo(); 2566 ASSERT_TRUE(response != NULL); 2567 ASSERT_FALSE(response->headers.get() == NULL); 2568 EXPECT_TRUE(response->headers->IsKeepAlive()); 2569 EXPECT_EQ(407, response->headers->response_code()); 2570 EXPECT_EQ(10, response->headers->GetContentLength()); 2571 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2572 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2573 2574 // Flush the idle socket before the NetLog and HttpNetworkTransaction go 2575 // out of scope. 2576 session->CloseAllConnections(); 2577 } 2578 2579 // Test that we don't read the response body when we fail to establish a tunnel, 2580 // even if the user cancels the proxy's auth attempt. 2581 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { 2582 HttpRequestInfo request; 2583 request.method = "GET"; 2584 request.url = GURL("https://www.google.com/"); 2585 request.load_flags = 0; 2586 2587 // Configure against proxy server "myproxy:70". 2588 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2589 2590 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2591 2592 scoped_ptr<HttpTransaction> trans( 2593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2594 2595 // Since we have proxy, should try to establish tunnel. 2596 MockWrite data_writes[] = { 2597 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2598 "Host: www.google.com\r\n" 2599 "Proxy-Connection: keep-alive\r\n\r\n"), 2600 }; 2601 2602 // The proxy responds to the connect with a 407. 2603 MockRead data_reads[] = { 2604 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2605 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2606 MockRead("Content-Length: 10\r\n\r\n"), 2607 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 2608 }; 2609 2610 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 2611 data_writes, arraysize(data_writes)); 2612 session_deps_.socket_factory->AddSocketDataProvider(&data); 2613 2614 TestCompletionCallback callback; 2615 2616 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 2617 EXPECT_EQ(ERR_IO_PENDING, rv); 2618 2619 rv = callback.WaitForResult(); 2620 EXPECT_EQ(OK, rv); 2621 2622 const HttpResponseInfo* response = trans->GetResponseInfo(); 2623 ASSERT_TRUE(response != NULL); 2624 2625 EXPECT_TRUE(response->headers->IsKeepAlive()); 2626 EXPECT_EQ(407, response->headers->response_code()); 2627 EXPECT_EQ(10, response->headers->GetContentLength()); 2628 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2629 2630 std::string response_data; 2631 rv = ReadTransaction(trans.get(), &response_data); 2632 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 2633 2634 // Flush the idle socket before the HttpNetworkTransaction goes out of scope. 2635 session->CloseAllConnections(); 2636 } 2637 2638 // Test when a server (non-proxy) returns a 407 (proxy-authenticate). 2639 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH. 2640 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) { 2641 HttpRequestInfo request; 2642 request.method = "GET"; 2643 request.url = GURL("http://www.google.com/"); 2644 request.load_flags = 0; 2645 2646 // We are using a DIRECT connection (i.e. no proxy) for this session. 2647 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2648 scoped_ptr<HttpTransaction> trans( 2649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2650 2651 MockWrite data_writes1[] = { 2652 MockWrite("GET / HTTP/1.1\r\n" 2653 "Host: www.google.com\r\n" 2654 "Connection: keep-alive\r\n\r\n"), 2655 }; 2656 2657 MockRead data_reads1[] = { 2658 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"), 2659 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2660 // Large content-length -- won't matter, as connection will be reset. 2661 MockRead("Content-Length: 10000\r\n\r\n"), 2662 MockRead(SYNCHRONOUS, ERR_FAILED), 2663 }; 2664 2665 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2666 data_writes1, arraysize(data_writes1)); 2667 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2668 2669 TestCompletionCallback callback; 2670 2671 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 2672 EXPECT_EQ(ERR_IO_PENDING, rv); 2673 2674 rv = callback.WaitForResult(); 2675 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 2676 } 2677 2678 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication) 2679 // through a non-authenticating proxy. The request should fail with 2680 // ERR_UNEXPECTED_PROXY_AUTH. 2681 // Note that it is impossible to detect if an HTTP server returns a 407 through 2682 // a non-authenticating proxy - there is nothing to indicate whether the 2683 // response came from the proxy or the server, so it is treated as if the proxy 2684 // issued the challenge. 2685 TEST_P(HttpNetworkTransactionTest, 2686 HttpsServerRequestsProxyAuthThroughProxy) { 2687 HttpRequestInfo request; 2688 request.method = "GET"; 2689 request.url = GURL("https://www.google.com/"); 2690 2691 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2692 CapturingBoundNetLog log; 2693 session_deps_.net_log = log.bound().net_log(); 2694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2695 2696 // Since we have proxy, should try to establish tunnel. 2697 MockWrite data_writes1[] = { 2698 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2699 "Host: www.google.com\r\n" 2700 "Proxy-Connection: keep-alive\r\n\r\n"), 2701 2702 MockWrite("GET / HTTP/1.1\r\n" 2703 "Host: www.google.com\r\n" 2704 "Connection: keep-alive\r\n\r\n"), 2705 }; 2706 2707 MockRead data_reads1[] = { 2708 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2709 2710 MockRead("HTTP/1.1 407 Unauthorized\r\n"), 2711 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2712 MockRead("\r\n"), 2713 MockRead(SYNCHRONOUS, OK), 2714 }; 2715 2716 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2717 data_writes1, arraysize(data_writes1)); 2718 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2719 SSLSocketDataProvider ssl(ASYNC, OK); 2720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2721 2722 TestCompletionCallback callback1; 2723 2724 scoped_ptr<HttpTransaction> trans( 2725 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2726 2727 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2728 EXPECT_EQ(ERR_IO_PENDING, rv); 2729 2730 rv = callback1.WaitForResult(); 2731 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 2732 net::CapturingNetLog::CapturedEntryList entries; 2733 log.GetEntries(&entries); 2734 size_t pos = ExpectLogContainsSomewhere( 2735 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2736 NetLog::PHASE_NONE); 2737 ExpectLogContainsSomewhere( 2738 entries, pos, 2739 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2740 NetLog::PHASE_NONE); 2741 } 2742 2743 // Test the load timing for HTTPS requests with an HTTP proxy. 2744 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) { 2745 HttpRequestInfo request1; 2746 request1.method = "GET"; 2747 request1.url = GURL("https://www.google.com/1"); 2748 2749 HttpRequestInfo request2; 2750 request2.method = "GET"; 2751 request2.url = GURL("https://www.google.com/2"); 2752 2753 // Configure against proxy server "myproxy:70". 2754 session_deps_.proxy_service.reset( 2755 ProxyService::CreateFixed("PROXY myproxy:70")); 2756 CapturingBoundNetLog log; 2757 session_deps_.net_log = log.bound().net_log(); 2758 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2759 2760 // Since we have proxy, should try to establish tunnel. 2761 MockWrite data_writes1[] = { 2762 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2763 "Host: www.google.com\r\n" 2764 "Proxy-Connection: keep-alive\r\n\r\n"), 2765 2766 MockWrite("GET /1 HTTP/1.1\r\n" 2767 "Host: www.google.com\r\n" 2768 "Connection: keep-alive\r\n\r\n"), 2769 2770 MockWrite("GET /2 HTTP/1.1\r\n" 2771 "Host: www.google.com\r\n" 2772 "Connection: keep-alive\r\n\r\n"), 2773 }; 2774 2775 // The proxy responds to the connect with a 407, using a persistent 2776 // connection. 2777 MockRead data_reads1[] = { 2778 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2779 2780 MockRead("HTTP/1.1 200 OK\r\n"), 2781 MockRead("Content-Length: 1\r\n\r\n"), 2782 MockRead(SYNCHRONOUS, "1"), 2783 2784 MockRead("HTTP/1.1 200 OK\r\n"), 2785 MockRead("Content-Length: 2\r\n\r\n"), 2786 MockRead(SYNCHRONOUS, "22"), 2787 }; 2788 2789 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2790 data_writes1, arraysize(data_writes1)); 2791 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2792 SSLSocketDataProvider ssl(ASYNC, OK); 2793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2794 2795 TestCompletionCallback callback1; 2796 scoped_ptr<HttpTransaction> trans1( 2797 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2798 2799 int rv = trans1->Start(&request1, callback1.callback(), log.bound()); 2800 EXPECT_EQ(ERR_IO_PENDING, rv); 2801 2802 rv = callback1.WaitForResult(); 2803 EXPECT_EQ(OK, rv); 2804 2805 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 2806 ASSERT_TRUE(response1 != NULL); 2807 ASSERT_TRUE(response1->headers.get() != NULL); 2808 EXPECT_EQ(1, response1->headers->GetContentLength()); 2809 2810 LoadTimingInfo load_timing_info1; 2811 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1)); 2812 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES); 2813 2814 trans1.reset(); 2815 2816 TestCompletionCallback callback2; 2817 scoped_ptr<HttpTransaction> trans2( 2818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2819 2820 rv = trans2->Start(&request2, callback2.callback(), log.bound()); 2821 EXPECT_EQ(ERR_IO_PENDING, rv); 2822 2823 rv = callback2.WaitForResult(); 2824 EXPECT_EQ(OK, rv); 2825 2826 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 2827 ASSERT_TRUE(response2 != NULL); 2828 ASSERT_TRUE(response2->headers.get() != NULL); 2829 EXPECT_EQ(2, response2->headers->GetContentLength()); 2830 2831 LoadTimingInfo load_timing_info2; 2832 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 2833 TestLoadTimingReused(load_timing_info2); 2834 2835 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2836 2837 trans2.reset(); 2838 session->CloseAllConnections(); 2839 } 2840 2841 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script. 2842 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) { 2843 HttpRequestInfo request1; 2844 request1.method = "GET"; 2845 request1.url = GURL("https://www.google.com/1"); 2846 2847 HttpRequestInfo request2; 2848 request2.method = "GET"; 2849 request2.url = GURL("https://www.google.com/2"); 2850 2851 // Configure against proxy server "myproxy:70". 2852 session_deps_.proxy_service.reset( 2853 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 2854 CapturingBoundNetLog log; 2855 session_deps_.net_log = log.bound().net_log(); 2856 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2857 2858 // Since we have proxy, should try to establish tunnel. 2859 MockWrite data_writes1[] = { 2860 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2861 "Host: www.google.com\r\n" 2862 "Proxy-Connection: keep-alive\r\n\r\n"), 2863 2864 MockWrite("GET /1 HTTP/1.1\r\n" 2865 "Host: www.google.com\r\n" 2866 "Connection: keep-alive\r\n\r\n"), 2867 2868 MockWrite("GET /2 HTTP/1.1\r\n" 2869 "Host: www.google.com\r\n" 2870 "Connection: keep-alive\r\n\r\n"), 2871 }; 2872 2873 // The proxy responds to the connect with a 407, using a persistent 2874 // connection. 2875 MockRead data_reads1[] = { 2876 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2877 2878 MockRead("HTTP/1.1 200 OK\r\n"), 2879 MockRead("Content-Length: 1\r\n\r\n"), 2880 MockRead(SYNCHRONOUS, "1"), 2881 2882 MockRead("HTTP/1.1 200 OK\r\n"), 2883 MockRead("Content-Length: 2\r\n\r\n"), 2884 MockRead(SYNCHRONOUS, "22"), 2885 }; 2886 2887 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2888 data_writes1, arraysize(data_writes1)); 2889 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2890 SSLSocketDataProvider ssl(ASYNC, OK); 2891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2892 2893 TestCompletionCallback callback1; 2894 scoped_ptr<HttpTransaction> trans1( 2895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2896 2897 int rv = trans1->Start(&request1, callback1.callback(), log.bound()); 2898 EXPECT_EQ(ERR_IO_PENDING, rv); 2899 2900 rv = callback1.WaitForResult(); 2901 EXPECT_EQ(OK, rv); 2902 2903 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 2904 ASSERT_TRUE(response1 != NULL); 2905 ASSERT_TRUE(response1->headers.get() != NULL); 2906 EXPECT_EQ(1, response1->headers->GetContentLength()); 2907 2908 LoadTimingInfo load_timing_info1; 2909 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1)); 2910 TestLoadTimingNotReusedWithPac(load_timing_info1, 2911 CONNECT_TIMING_HAS_SSL_TIMES); 2912 2913 trans1.reset(); 2914 2915 TestCompletionCallback callback2; 2916 scoped_ptr<HttpTransaction> trans2( 2917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2918 2919 rv = trans2->Start(&request2, callback2.callback(), log.bound()); 2920 EXPECT_EQ(ERR_IO_PENDING, rv); 2921 2922 rv = callback2.WaitForResult(); 2923 EXPECT_EQ(OK, rv); 2924 2925 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 2926 ASSERT_TRUE(response2 != NULL); 2927 ASSERT_TRUE(response2->headers.get() != NULL); 2928 EXPECT_EQ(2, response2->headers->GetContentLength()); 2929 2930 LoadTimingInfo load_timing_info2; 2931 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 2932 TestLoadTimingReusedWithPac(load_timing_info2); 2933 2934 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2935 2936 trans2.reset(); 2937 session->CloseAllConnections(); 2938 } 2939 2940 // Test a simple get through an HTTPS Proxy. 2941 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) { 2942 HttpRequestInfo request; 2943 request.method = "GET"; 2944 request.url = GURL("http://www.google.com/"); 2945 2946 // Configure against https proxy server "proxy:70". 2947 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2948 "https://proxy:70")); 2949 CapturingBoundNetLog log; 2950 session_deps_.net_log = log.bound().net_log(); 2951 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2952 2953 // Since we have proxy, should use full url 2954 MockWrite data_writes1[] = { 2955 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 2956 "Host: www.google.com\r\n" 2957 "Proxy-Connection: keep-alive\r\n\r\n"), 2958 }; 2959 2960 MockRead data_reads1[] = { 2961 MockRead("HTTP/1.1 200 OK\r\n"), 2962 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2963 MockRead("Content-Length: 100\r\n\r\n"), 2964 MockRead(SYNCHRONOUS, OK), 2965 }; 2966 2967 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2968 data_writes1, arraysize(data_writes1)); 2969 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2970 SSLSocketDataProvider ssl(ASYNC, OK); 2971 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2972 2973 TestCompletionCallback callback1; 2974 2975 scoped_ptr<HttpTransaction> trans( 2976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2977 2978 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2979 EXPECT_EQ(ERR_IO_PENDING, rv); 2980 2981 rv = callback1.WaitForResult(); 2982 EXPECT_EQ(OK, rv); 2983 2984 LoadTimingInfo load_timing_info; 2985 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2986 TestLoadTimingNotReused(load_timing_info, 2987 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 2988 2989 const HttpResponseInfo* response = trans->GetResponseInfo(); 2990 ASSERT_TRUE(response != NULL); 2991 2992 EXPECT_TRUE(response->headers->IsKeepAlive()); 2993 EXPECT_EQ(200, response->headers->response_code()); 2994 EXPECT_EQ(100, response->headers->GetContentLength()); 2995 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2996 2997 // The password prompt info should not be set. 2998 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2999 } 3000 3001 // Test a SPDY get through an HTTPS Proxy. 3002 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) { 3003 HttpRequestInfo request; 3004 request.method = "GET"; 3005 request.url = GURL("http://www.google.com/"); 3006 request.load_flags = 0; 3007 3008 // Configure against https proxy server "proxy:70". 3009 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3010 "https://proxy:70")); 3011 CapturingBoundNetLog log; 3012 session_deps_.net_log = log.bound().net_log(); 3013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3014 3015 // fetch http://www.google.com/ via SPDY 3016 scoped_ptr<SpdyFrame> req( 3017 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 3018 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 3019 3020 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3021 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3022 MockRead spdy_reads[] = { 3023 CreateMockRead(*resp), 3024 CreateMockRead(*data), 3025 MockRead(ASYNC, 0, 0), 3026 }; 3027 3028 DelayedSocketData spdy_data( 3029 1, // wait for one write to finish before reading. 3030 spdy_reads, arraysize(spdy_reads), 3031 spdy_writes, arraysize(spdy_writes)); 3032 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3033 3034 SSLSocketDataProvider ssl(ASYNC, OK); 3035 ssl.SetNextProto(GetParam()); 3036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3037 3038 TestCompletionCallback callback1; 3039 3040 scoped_ptr<HttpTransaction> trans( 3041 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3042 3043 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3044 EXPECT_EQ(ERR_IO_PENDING, rv); 3045 3046 rv = callback1.WaitForResult(); 3047 EXPECT_EQ(OK, rv); 3048 3049 LoadTimingInfo load_timing_info; 3050 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3051 TestLoadTimingNotReused(load_timing_info, 3052 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3053 3054 const HttpResponseInfo* response = trans->GetResponseInfo(); 3055 ASSERT_TRUE(response != NULL); 3056 ASSERT_TRUE(response->headers.get() != NULL); 3057 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3058 3059 std::string response_data; 3060 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3061 EXPECT_EQ(kUploadData, response_data); 3062 } 3063 3064 // Verifies that a session which races and wins against the owning transaction 3065 // (completing prior to host resolution), doesn't fail the transaction. 3066 // Regression test for crbug.com/334413. 3067 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) { 3068 HttpRequestInfo request; 3069 request.method = "GET"; 3070 request.url = GURL("http://www.google.com/"); 3071 request.load_flags = 0; 3072 3073 // Configure SPDY proxy server "proxy:70". 3074 session_deps_.proxy_service.reset( 3075 ProxyService::CreateFixed("https://proxy:70")); 3076 CapturingBoundNetLog log; 3077 session_deps_.net_log = log.bound().net_log(); 3078 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3079 3080 // Fetch http://www.google.com/ through the SPDY proxy. 3081 scoped_ptr<SpdyFrame> req( 3082 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 3083 MockWrite spdy_writes[] = {CreateMockWrite(*req)}; 3084 3085 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3086 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3087 MockRead spdy_reads[] = { 3088 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0), 3089 }; 3090 3091 DelayedSocketData spdy_data( 3092 1, // wait for one write to finish before reading. 3093 spdy_reads, 3094 arraysize(spdy_reads), 3095 spdy_writes, 3096 arraysize(spdy_writes)); 3097 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3098 3099 SSLSocketDataProvider ssl(ASYNC, OK); 3100 ssl.SetNextProto(GetParam()); 3101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3102 3103 TestCompletionCallback callback1; 3104 3105 scoped_ptr<HttpTransaction> trans( 3106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3107 3108 // Stall the hostname resolution begun by the transaction. 3109 session_deps_.host_resolver->set_synchronous_mode(false); 3110 session_deps_.host_resolver->set_ondemand_mode(true); 3111 3112 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3113 EXPECT_EQ(ERR_IO_PENDING, rv); 3114 3115 // Race a session to the proxy, which completes first. 3116 session_deps_.host_resolver->set_ondemand_mode(false); 3117 SpdySessionKey key( 3118 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 3119 base::WeakPtr<SpdySession> spdy_session = 3120 CreateSecureSpdySession(session, key, log.bound()); 3121 3122 // Unstall the resolution begun by the transaction. 3123 session_deps_.host_resolver->set_ondemand_mode(true); 3124 session_deps_.host_resolver->ResolveAllPending(); 3125 3126 EXPECT_FALSE(callback1.have_result()); 3127 rv = callback1.WaitForResult(); 3128 EXPECT_EQ(OK, rv); 3129 3130 const HttpResponseInfo* response = trans->GetResponseInfo(); 3131 ASSERT_TRUE(response != NULL); 3132 ASSERT_TRUE(response->headers.get() != NULL); 3133 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3134 3135 std::string response_data; 3136 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3137 EXPECT_EQ(kUploadData, response_data); 3138 } 3139 3140 // Test a SPDY get through an HTTPS Proxy. 3141 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) { 3142 HttpRequestInfo request; 3143 request.method = "GET"; 3144 request.url = GURL("http://www.google.com/"); 3145 request.load_flags = 0; 3146 3147 // Configure against https proxy server "myproxy:70". 3148 session_deps_.proxy_service.reset( 3149 ProxyService::CreateFixed("https://myproxy:70")); 3150 CapturingBoundNetLog log; 3151 session_deps_.net_log = log.bound().net_log(); 3152 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3153 3154 // The first request will be a bare GET, the second request will be a 3155 // GET with a Proxy-Authorization header. 3156 scoped_ptr<SpdyFrame> req_get( 3157 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 3158 const char* const kExtraAuthorizationHeaders[] = { 3159 "proxy-authorization", "Basic Zm9vOmJhcg==" 3160 }; 3161 scoped_ptr<SpdyFrame> req_get_authorization( 3162 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders, 3163 arraysize(kExtraAuthorizationHeaders) / 2, 3164 false, 3165 3, 3166 LOWEST, 3167 false)); 3168 MockWrite spdy_writes[] = { 3169 CreateMockWrite(*req_get, 1), 3170 CreateMockWrite(*req_get_authorization, 4), 3171 }; 3172 3173 // The first response is a 407 proxy authentication challenge, and the second 3174 // response will be a 200 response since the second request includes a valid 3175 // Authorization header. 3176 const char* const kExtraAuthenticationHeaders[] = { 3177 "proxy-authenticate", "Basic realm=\"MyRealm1\"" 3178 }; 3179 scoped_ptr<SpdyFrame> resp_authentication( 3180 spdy_util_.ConstructSpdySynReplyError( 3181 "407 Proxy Authentication Required", 3182 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2, 3183 1)); 3184 scoped_ptr<SpdyFrame> body_authentication( 3185 spdy_util_.ConstructSpdyBodyFrame(1, true)); 3186 scoped_ptr<SpdyFrame> resp_data( 3187 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3188 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true)); 3189 MockRead spdy_reads[] = { 3190 CreateMockRead(*resp_authentication, 2), 3191 CreateMockRead(*body_authentication, 3), 3192 CreateMockRead(*resp_data, 5), 3193 CreateMockRead(*body_data, 6), 3194 MockRead(ASYNC, 0, 7), 3195 }; 3196 3197 OrderedSocketData data( 3198 spdy_reads, arraysize(spdy_reads), 3199 spdy_writes, arraysize(spdy_writes)); 3200 session_deps_.socket_factory->AddSocketDataProvider(&data); 3201 3202 SSLSocketDataProvider ssl(ASYNC, OK); 3203 ssl.SetNextProto(GetParam()); 3204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3205 3206 TestCompletionCallback callback1; 3207 3208 scoped_ptr<HttpTransaction> trans( 3209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3210 3211 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3212 EXPECT_EQ(ERR_IO_PENDING, rv); 3213 3214 rv = callback1.WaitForResult(); 3215 EXPECT_EQ(OK, rv); 3216 3217 const HttpResponseInfo* const response = trans->GetResponseInfo(); 3218 3219 ASSERT_TRUE(response != NULL); 3220 ASSERT_TRUE(response->headers.get() != NULL); 3221 EXPECT_EQ(407, response->headers->response_code()); 3222 EXPECT_TRUE(response->was_fetched_via_spdy); 3223 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 3224 3225 TestCompletionCallback callback2; 3226 3227 rv = trans->RestartWithAuth( 3228 AuthCredentials(kFoo, kBar), callback2.callback()); 3229 EXPECT_EQ(ERR_IO_PENDING, rv); 3230 3231 rv = callback2.WaitForResult(); 3232 EXPECT_EQ(OK, rv); 3233 3234 const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 3235 3236 ASSERT_TRUE(response_restart != NULL); 3237 ASSERT_TRUE(response_restart->headers.get() != NULL); 3238 EXPECT_EQ(200, response_restart->headers->response_code()); 3239 // The password prompt info should not be set. 3240 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 3241 } 3242 3243 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server. 3244 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) { 3245 HttpRequestInfo request; 3246 request.method = "GET"; 3247 request.url = GURL("https://www.google.com/"); 3248 request.load_flags = 0; 3249 3250 // Configure against https proxy server "proxy:70". 3251 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3252 "https://proxy:70")); 3253 CapturingBoundNetLog log; 3254 session_deps_.net_log = log.bound().net_log(); 3255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3256 3257 scoped_ptr<HttpTransaction> trans( 3258 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3259 3260 // CONNECT to www.google.com:443 via SPDY 3261 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3262 LOWEST)); 3263 // fetch https://www.google.com/ via HTTP 3264 3265 const char get[] = "GET / HTTP/1.1\r\n" 3266 "Host: www.google.com\r\n" 3267 "Connection: keep-alive\r\n\r\n"; 3268 scoped_ptr<SpdyFrame> wrapped_get( 3269 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false)); 3270 scoped_ptr<SpdyFrame> conn_resp( 3271 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3272 const char resp[] = "HTTP/1.1 200 OK\r\n" 3273 "Content-Length: 10\r\n\r\n"; 3274 scoped_ptr<SpdyFrame> wrapped_get_resp( 3275 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false)); 3276 scoped_ptr<SpdyFrame> wrapped_body( 3277 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false)); 3278 scoped_ptr<SpdyFrame> window_update( 3279 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size())); 3280 3281 MockWrite spdy_writes[] = { 3282 CreateMockWrite(*connect, 1), 3283 CreateMockWrite(*wrapped_get, 3), 3284 CreateMockWrite(*window_update, 5), 3285 }; 3286 3287 MockRead spdy_reads[] = { 3288 CreateMockRead(*conn_resp, 2, ASYNC), 3289 CreateMockRead(*wrapped_get_resp, 4, ASYNC), 3290 CreateMockRead(*wrapped_body, 6, ASYNC), 3291 CreateMockRead(*wrapped_body, 7, ASYNC), 3292 MockRead(ASYNC, 0, 8), 3293 }; 3294 3295 OrderedSocketData spdy_data( 3296 spdy_reads, arraysize(spdy_reads), 3297 spdy_writes, arraysize(spdy_writes)); 3298 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3299 3300 SSLSocketDataProvider ssl(ASYNC, OK); 3301 ssl.SetNextProto(GetParam()); 3302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3303 SSLSocketDataProvider ssl2(ASYNC, OK); 3304 ssl2.was_npn_negotiated = false; 3305 ssl2.protocol_negotiated = kProtoUnknown; 3306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 3307 3308 TestCompletionCallback callback1; 3309 3310 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3311 EXPECT_EQ(ERR_IO_PENDING, rv); 3312 3313 rv = callback1.WaitForResult(); 3314 EXPECT_EQ(OK, rv); 3315 3316 LoadTimingInfo load_timing_info; 3317 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3318 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3319 3320 const HttpResponseInfo* response = trans->GetResponseInfo(); 3321 ASSERT_TRUE(response != NULL); 3322 ASSERT_TRUE(response->headers.get() != NULL); 3323 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3324 3325 std::string response_data; 3326 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3327 EXPECT_EQ("1234567890", response_data); 3328 } 3329 3330 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server. 3331 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) { 3332 HttpRequestInfo request; 3333 request.method = "GET"; 3334 request.url = GURL("https://www.google.com/"); 3335 request.load_flags = 0; 3336 3337 // Configure against https proxy server "proxy:70". 3338 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3339 "https://proxy:70")); 3340 CapturingBoundNetLog log; 3341 session_deps_.net_log = log.bound().net_log(); 3342 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3343 3344 scoped_ptr<HttpTransaction> trans( 3345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3346 3347 // CONNECT to www.google.com:443 via SPDY 3348 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3349 LOWEST)); 3350 // fetch https://www.google.com/ via SPDY 3351 const char* const kMyUrl = "https://www.google.com/"; 3352 scoped_ptr<SpdyFrame> get( 3353 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST)); 3354 scoped_ptr<SpdyFrame> wrapped_get( 3355 spdy_util_.ConstructWrappedSpdyFrame(get, 1)); 3356 scoped_ptr<SpdyFrame> conn_resp( 3357 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3358 scoped_ptr<SpdyFrame> get_resp( 3359 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3360 scoped_ptr<SpdyFrame> wrapped_get_resp( 3361 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1)); 3362 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3363 scoped_ptr<SpdyFrame> wrapped_body( 3364 spdy_util_.ConstructWrappedSpdyFrame(body, 1)); 3365 scoped_ptr<SpdyFrame> window_update_get_resp( 3366 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size())); 3367 scoped_ptr<SpdyFrame> window_update_body( 3368 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size())); 3369 3370 MockWrite spdy_writes[] = { 3371 CreateMockWrite(*connect, 1), 3372 CreateMockWrite(*wrapped_get, 3), 3373 CreateMockWrite(*window_update_get_resp, 5), 3374 CreateMockWrite(*window_update_body, 7), 3375 }; 3376 3377 MockRead spdy_reads[] = { 3378 CreateMockRead(*conn_resp, 2, ASYNC), 3379 CreateMockRead(*wrapped_get_resp, 4, ASYNC), 3380 CreateMockRead(*wrapped_body, 6, ASYNC), 3381 MockRead(ASYNC, 0, 8), 3382 }; 3383 3384 OrderedSocketData spdy_data( 3385 spdy_reads, arraysize(spdy_reads), 3386 spdy_writes, arraysize(spdy_writes)); 3387 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3388 3389 SSLSocketDataProvider ssl(ASYNC, OK); 3390 ssl.SetNextProto(GetParam()); 3391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3392 SSLSocketDataProvider ssl2(ASYNC, OK); 3393 ssl2.SetNextProto(GetParam()); 3394 ssl2.protocol_negotiated = GetParam(); 3395 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 3396 3397 TestCompletionCallback callback1; 3398 3399 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3400 EXPECT_EQ(ERR_IO_PENDING, rv); 3401 3402 rv = callback1.WaitForResult(); 3403 EXPECT_EQ(OK, rv); 3404 3405 LoadTimingInfo load_timing_info; 3406 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3407 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3408 3409 const HttpResponseInfo* response = trans->GetResponseInfo(); 3410 ASSERT_TRUE(response != NULL); 3411 ASSERT_TRUE(response->headers.get() != NULL); 3412 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3413 3414 std::string response_data; 3415 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3416 EXPECT_EQ(kUploadData, response_data); 3417 } 3418 3419 // Test a SPDY CONNECT failure through an HTTPS Proxy. 3420 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) { 3421 HttpRequestInfo request; 3422 request.method = "GET"; 3423 request.url = GURL("https://www.google.com/"); 3424 request.load_flags = 0; 3425 3426 // Configure against https proxy server "proxy:70". 3427 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3428 "https://proxy:70")); 3429 CapturingBoundNetLog log; 3430 session_deps_.net_log = log.bound().net_log(); 3431 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3432 3433 scoped_ptr<HttpTransaction> trans( 3434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3435 3436 // CONNECT to www.google.com:443 via SPDY 3437 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3438 LOWEST)); 3439 scoped_ptr<SpdyFrame> get( 3440 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 3441 3442 MockWrite spdy_writes[] = { 3443 CreateMockWrite(*connect, 1), 3444 CreateMockWrite(*get, 3), 3445 }; 3446 3447 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1)); 3448 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3449 MockRead spdy_reads[] = { 3450 CreateMockRead(*resp, 2, ASYNC), 3451 MockRead(ASYNC, 0, 4), 3452 }; 3453 3454 OrderedSocketData spdy_data( 3455 spdy_reads, arraysize(spdy_reads), 3456 spdy_writes, arraysize(spdy_writes)); 3457 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3458 3459 SSLSocketDataProvider ssl(ASYNC, OK); 3460 ssl.SetNextProto(GetParam()); 3461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3462 SSLSocketDataProvider ssl2(ASYNC, OK); 3463 ssl2.SetNextProto(GetParam()); 3464 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 3465 3466 TestCompletionCallback callback1; 3467 3468 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3469 EXPECT_EQ(ERR_IO_PENDING, rv); 3470 3471 rv = callback1.WaitForResult(); 3472 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 3473 3474 // TODO(ttuttle): Anything else to check here? 3475 } 3476 3477 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY 3478 // HTTPS Proxy to different servers. 3479 TEST_P(HttpNetworkTransactionTest, 3480 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) { 3481 // Configure against https proxy server "proxy:70". 3482 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3483 "https://proxy:70")); 3484 CapturingBoundNetLog log; 3485 session_deps_.net_log = log.bound().net_log(); 3486 scoped_refptr<HttpNetworkSession> session( 3487 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3488 3489 HttpRequestInfo request1; 3490 request1.method = "GET"; 3491 request1.url = GURL("https://www.google.com/"); 3492 request1.load_flags = 0; 3493 3494 HttpRequestInfo request2; 3495 request2.method = "GET"; 3496 request2.url = GURL("https://news.google.com/"); 3497 request2.load_flags = 0; 3498 3499 // CONNECT to www.google.com:443 via SPDY. 3500 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3501 LOWEST)); 3502 scoped_ptr<SpdyFrame> conn_resp1( 3503 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3504 3505 // Fetch https://www.google.com/ via HTTP. 3506 const char get1[] = "GET / HTTP/1.1\r\n" 3507 "Host: www.google.com\r\n" 3508 "Connection: keep-alive\r\n\r\n"; 3509 scoped_ptr<SpdyFrame> wrapped_get1( 3510 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false)); 3511 const char resp1[] = "HTTP/1.1 200 OK\r\n" 3512 "Content-Length: 1\r\n\r\n"; 3513 scoped_ptr<SpdyFrame> wrapped_get_resp1( 3514 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false)); 3515 scoped_ptr<SpdyFrame> wrapped_body1( 3516 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false)); 3517 scoped_ptr<SpdyFrame> window_update( 3518 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size())); 3519 3520 // CONNECT to news.google.com:443 via SPDY. 3521 SpdyHeaderBlock connect2_block; 3522 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT"; 3523 connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443"; 3524 connect2_block[spdy_util_.GetHostKey()] = "news.google.com"; 3525 spdy_util_.MaybeAddVersionHeader(&connect2_block); 3526 scoped_ptr<SpdyFrame> connect2( 3527 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false)); 3528 3529 scoped_ptr<SpdyFrame> conn_resp2( 3530 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3531 3532 // Fetch https://news.google.com/ via HTTP. 3533 const char get2[] = "GET / HTTP/1.1\r\n" 3534 "Host: news.google.com\r\n" 3535 "Connection: keep-alive\r\n\r\n"; 3536 scoped_ptr<SpdyFrame> wrapped_get2( 3537 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false)); 3538 const char resp2[] = "HTTP/1.1 200 OK\r\n" 3539 "Content-Length: 2\r\n\r\n"; 3540 scoped_ptr<SpdyFrame> wrapped_get_resp2( 3541 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false)); 3542 scoped_ptr<SpdyFrame> wrapped_body2( 3543 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false)); 3544 3545 MockWrite spdy_writes[] = { 3546 CreateMockWrite(*connect1, 0), 3547 CreateMockWrite(*wrapped_get1, 2), 3548 CreateMockWrite(*connect2, 5), 3549 CreateMockWrite(*wrapped_get2, 7), 3550 }; 3551 3552 MockRead spdy_reads[] = { 3553 CreateMockRead(*conn_resp1, 1, ASYNC), 3554 CreateMockRead(*wrapped_get_resp1, 3, ASYNC), 3555 CreateMockRead(*wrapped_body1, 4, ASYNC), 3556 CreateMockRead(*conn_resp2, 6, ASYNC), 3557 CreateMockRead(*wrapped_get_resp2, 8, ASYNC), 3558 CreateMockRead(*wrapped_body2, 9, ASYNC), 3559 MockRead(ASYNC, 0, 10), 3560 }; 3561 3562 DeterministicSocketData spdy_data( 3563 spdy_reads, arraysize(spdy_reads), 3564 spdy_writes, arraysize(spdy_writes)); 3565 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3566 3567 SSLSocketDataProvider ssl(ASYNC, OK); 3568 ssl.SetNextProto(GetParam()); 3569 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3570 SSLSocketDataProvider ssl2(ASYNC, OK); 3571 ssl2.was_npn_negotiated = false; 3572 ssl2.protocol_negotiated = kProtoUnknown; 3573 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 3574 SSLSocketDataProvider ssl3(ASYNC, OK); 3575 ssl3.was_npn_negotiated = false; 3576 ssl3.protocol_negotiated = kProtoUnknown; 3577 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3); 3578 3579 TestCompletionCallback callback; 3580 3581 scoped_ptr<HttpTransaction> trans( 3582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3583 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3584 EXPECT_EQ(ERR_IO_PENDING, rv); 3585 // The first connect and request, each of their responses, and the body. 3586 spdy_data.RunFor(5); 3587 3588 rv = callback.WaitForResult(); 3589 EXPECT_EQ(OK, rv); 3590 3591 LoadTimingInfo load_timing_info; 3592 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3593 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3594 3595 const HttpResponseInfo* response = trans->GetResponseInfo(); 3596 ASSERT_TRUE(response != NULL); 3597 ASSERT_TRUE(response->headers.get() != NULL); 3598 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3599 3600 std::string response_data; 3601 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3602 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback())); 3603 3604 scoped_ptr<HttpTransaction> trans2( 3605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3606 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3607 EXPECT_EQ(ERR_IO_PENDING, rv); 3608 3609 // The second connect and request, each of their responses, and the body. 3610 spdy_data.RunFor(5); 3611 rv = callback.WaitForResult(); 3612 EXPECT_EQ(OK, rv); 3613 3614 LoadTimingInfo load_timing_info2; 3615 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3616 // Even though the SPDY connection is reused, a new tunnelled connection has 3617 // to be created, so the socket's load timing looks like a fresh connection. 3618 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES); 3619 3620 // The requests should have different IDs, since they each are using their own 3621 // separate stream. 3622 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3623 3624 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback())); 3625 } 3626 3627 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY 3628 // HTTPS Proxy to the same server. 3629 TEST_P(HttpNetworkTransactionTest, 3630 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) { 3631 // Configure against https proxy server "proxy:70". 3632 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3633 "https://proxy:70")); 3634 CapturingBoundNetLog log; 3635 session_deps_.net_log = log.bound().net_log(); 3636 scoped_refptr<HttpNetworkSession> session( 3637 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3638 3639 HttpRequestInfo request1; 3640 request1.method = "GET"; 3641 request1.url = GURL("https://www.google.com/"); 3642 request1.load_flags = 0; 3643 3644 HttpRequestInfo request2; 3645 request2.method = "GET"; 3646 request2.url = GURL("https://www.google.com/2"); 3647 request2.load_flags = 0; 3648 3649 // CONNECT to www.google.com:443 via SPDY. 3650 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3651 LOWEST)); 3652 scoped_ptr<SpdyFrame> conn_resp1( 3653 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3654 3655 // Fetch https://www.google.com/ via HTTP. 3656 const char get1[] = "GET / HTTP/1.1\r\n" 3657 "Host: www.google.com\r\n" 3658 "Connection: keep-alive\r\n\r\n"; 3659 scoped_ptr<SpdyFrame> wrapped_get1( 3660 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false)); 3661 const char resp1[] = "HTTP/1.1 200 OK\r\n" 3662 "Content-Length: 1\r\n\r\n"; 3663 scoped_ptr<SpdyFrame> wrapped_get_resp1( 3664 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false)); 3665 scoped_ptr<SpdyFrame> wrapped_body1( 3666 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false)); 3667 scoped_ptr<SpdyFrame> window_update( 3668 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size())); 3669 3670 // Fetch https://www.google.com/2 via HTTP. 3671 const char get2[] = "GET /2 HTTP/1.1\r\n" 3672 "Host: www.google.com\r\n" 3673 "Connection: keep-alive\r\n\r\n"; 3674 scoped_ptr<SpdyFrame> wrapped_get2( 3675 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false)); 3676 const char resp2[] = "HTTP/1.1 200 OK\r\n" 3677 "Content-Length: 2\r\n\r\n"; 3678 scoped_ptr<SpdyFrame> wrapped_get_resp2( 3679 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false)); 3680 scoped_ptr<SpdyFrame> wrapped_body2( 3681 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false)); 3682 3683 MockWrite spdy_writes[] = { 3684 CreateMockWrite(*connect1, 0), 3685 CreateMockWrite(*wrapped_get1, 2), 3686 CreateMockWrite(*wrapped_get2, 5), 3687 }; 3688 3689 MockRead spdy_reads[] = { 3690 CreateMockRead(*conn_resp1, 1, ASYNC), 3691 CreateMockRead(*wrapped_get_resp1, 3, ASYNC), 3692 CreateMockRead(*wrapped_body1, 4, ASYNC), 3693 CreateMockRead(*wrapped_get_resp2, 6, ASYNC), 3694 CreateMockRead(*wrapped_body2, 7, ASYNC), 3695 MockRead(ASYNC, 0, 8), 3696 }; 3697 3698 DeterministicSocketData spdy_data( 3699 spdy_reads, arraysize(spdy_reads), 3700 spdy_writes, arraysize(spdy_writes)); 3701 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3702 3703 SSLSocketDataProvider ssl(ASYNC, OK); 3704 ssl.SetNextProto(GetParam()); 3705 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3706 SSLSocketDataProvider ssl2(ASYNC, OK); 3707 ssl2.was_npn_negotiated = false; 3708 ssl2.protocol_negotiated = kProtoUnknown; 3709 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 3710 3711 TestCompletionCallback callback; 3712 3713 scoped_ptr<HttpTransaction> trans( 3714 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3715 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3716 EXPECT_EQ(ERR_IO_PENDING, rv); 3717 // The first connect and request, each of their responses, and the body. 3718 spdy_data.RunFor(5); 3719 3720 rv = callback.WaitForResult(); 3721 EXPECT_EQ(OK, rv); 3722 3723 LoadTimingInfo load_timing_info; 3724 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3725 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3726 3727 const HttpResponseInfo* response = trans->GetResponseInfo(); 3728 ASSERT_TRUE(response != NULL); 3729 ASSERT_TRUE(response->headers.get() != NULL); 3730 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3731 3732 std::string response_data; 3733 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3734 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback())); 3735 trans.reset(); 3736 3737 scoped_ptr<HttpTransaction> trans2( 3738 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3739 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3740 EXPECT_EQ(ERR_IO_PENDING, rv); 3741 3742 // The second request, response, and body. There should not be a second 3743 // connect. 3744 spdy_data.RunFor(3); 3745 rv = callback.WaitForResult(); 3746 EXPECT_EQ(OK, rv); 3747 3748 LoadTimingInfo load_timing_info2; 3749 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3750 TestLoadTimingReused(load_timing_info2); 3751 3752 // The requests should have the same ID. 3753 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3754 3755 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback())); 3756 } 3757 3758 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS 3759 // Proxy to different servers. 3760 TEST_P(HttpNetworkTransactionTest, 3761 HttpsProxySpdyLoadTimingTwoHttpRequests) { 3762 // Configure against https proxy server "proxy:70". 3763 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3764 "https://proxy:70")); 3765 CapturingBoundNetLog log; 3766 session_deps_.net_log = log.bound().net_log(); 3767 scoped_refptr<HttpNetworkSession> session( 3768 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3769 3770 HttpRequestInfo request1; 3771 request1.method = "GET"; 3772 request1.url = GURL("http://www.google.com/"); 3773 request1.load_flags = 0; 3774 3775 HttpRequestInfo request2; 3776 request2.method = "GET"; 3777 request2.url = GURL("http://news.google.com/"); 3778 request2.load_flags = 0; 3779 3780 // http://www.google.com/ 3781 scoped_ptr<SpdyHeaderBlock> headers( 3782 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/")); 3783 scoped_ptr<SpdyFrame> get1( 3784 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true)); 3785 scoped_ptr<SpdyFrame> get_resp1( 3786 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3787 scoped_ptr<SpdyFrame> body1( 3788 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true)); 3789 3790 // http://news.google.com/ 3791 scoped_ptr<SpdyHeaderBlock> headers2( 3792 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/")); 3793 scoped_ptr<SpdyFrame> get2( 3794 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true)); 3795 scoped_ptr<SpdyFrame> get_resp2( 3796 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3797 scoped_ptr<SpdyFrame> body2( 3798 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true)); 3799 3800 MockWrite spdy_writes[] = { 3801 CreateMockWrite(*get1, 0), 3802 CreateMockWrite(*get2, 3), 3803 }; 3804 3805 MockRead spdy_reads[] = { 3806 CreateMockRead(*get_resp1, 1, ASYNC), 3807 CreateMockRead(*body1, 2, ASYNC), 3808 CreateMockRead(*get_resp2, 4, ASYNC), 3809 CreateMockRead(*body2, 5, ASYNC), 3810 MockRead(ASYNC, 0, 6), 3811 }; 3812 3813 DeterministicSocketData spdy_data( 3814 spdy_reads, arraysize(spdy_reads), 3815 spdy_writes, arraysize(spdy_writes)); 3816 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3817 3818 SSLSocketDataProvider ssl(ASYNC, OK); 3819 ssl.SetNextProto(GetParam()); 3820 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3821 3822 TestCompletionCallback callback; 3823 3824 scoped_ptr<HttpTransaction> trans( 3825 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3826 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3827 EXPECT_EQ(ERR_IO_PENDING, rv); 3828 spdy_data.RunFor(2); 3829 3830 rv = callback.WaitForResult(); 3831 EXPECT_EQ(OK, rv); 3832 3833 LoadTimingInfo load_timing_info; 3834 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3835 TestLoadTimingNotReused(load_timing_info, 3836 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3837 3838 const HttpResponseInfo* response = trans->GetResponseInfo(); 3839 ASSERT_TRUE(response != NULL); 3840 ASSERT_TRUE(response->headers.get() != NULL); 3841 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3842 3843 std::string response_data; 3844 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3845 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback())); 3846 spdy_data.RunFor(1); 3847 EXPECT_EQ(1, callback.WaitForResult()); 3848 // Delete the first request, so the second one can reuse the socket. 3849 trans.reset(); 3850 3851 scoped_ptr<HttpTransaction> trans2( 3852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3853 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3854 EXPECT_EQ(ERR_IO_PENDING, rv); 3855 3856 spdy_data.RunFor(2); 3857 rv = callback.WaitForResult(); 3858 EXPECT_EQ(OK, rv); 3859 3860 LoadTimingInfo load_timing_info2; 3861 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3862 TestLoadTimingReused(load_timing_info2); 3863 3864 // The requests should have the same ID. 3865 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3866 3867 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback())); 3868 spdy_data.RunFor(1); 3869 EXPECT_EQ(2, callback.WaitForResult()); 3870 } 3871 3872 // Test the challenge-response-retry sequence through an HTTPS Proxy 3873 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { 3874 HttpRequestInfo request; 3875 request.method = "GET"; 3876 request.url = GURL("http://www.google.com/"); 3877 // when the no authentication data flag is set. 3878 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 3879 3880 // Configure against https proxy server "myproxy:70". 3881 session_deps_.proxy_service.reset( 3882 ProxyService::CreateFixed("https://myproxy:70")); 3883 CapturingBoundNetLog log; 3884 session_deps_.net_log = log.bound().net_log(); 3885 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3886 3887 // Since we have proxy, should use full url 3888 MockWrite data_writes1[] = { 3889 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3890 "Host: www.google.com\r\n" 3891 "Proxy-Connection: keep-alive\r\n\r\n"), 3892 3893 // After calling trans->RestartWithAuth(), this is the request we should 3894 // be issuing -- the final header line contains the credentials. 3895 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3896 "Host: www.google.com\r\n" 3897 "Proxy-Connection: keep-alive\r\n" 3898 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3899 }; 3900 3901 // The proxy responds to the GET with a 407, using a persistent 3902 // connection. 3903 MockRead data_reads1[] = { 3904 // No credentials. 3905 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 3906 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3907 MockRead("Proxy-Connection: keep-alive\r\n"), 3908 MockRead("Content-Length: 0\r\n\r\n"), 3909 3910 MockRead("HTTP/1.1 200 OK\r\n"), 3911 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 3912 MockRead("Content-Length: 100\r\n\r\n"), 3913 MockRead(SYNCHRONOUS, OK), 3914 }; 3915 3916 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3917 data_writes1, arraysize(data_writes1)); 3918 session_deps_.socket_factory->AddSocketDataProvider(&data1); 3919 SSLSocketDataProvider ssl(ASYNC, OK); 3920 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3921 3922 TestCompletionCallback callback1; 3923 3924 scoped_ptr<HttpTransaction> trans( 3925 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3926 3927 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3928 EXPECT_EQ(ERR_IO_PENDING, rv); 3929 3930 rv = callback1.WaitForResult(); 3931 EXPECT_EQ(OK, rv); 3932 3933 LoadTimingInfo load_timing_info; 3934 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3935 TestLoadTimingNotReused(load_timing_info, 3936 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3937 3938 const HttpResponseInfo* response = trans->GetResponseInfo(); 3939 ASSERT_TRUE(response != NULL); 3940 ASSERT_FALSE(response->headers.get() == NULL); 3941 EXPECT_EQ(407, response->headers->response_code()); 3942 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 3943 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 3944 3945 TestCompletionCallback callback2; 3946 3947 rv = trans->RestartWithAuth( 3948 AuthCredentials(kFoo, kBar), callback2.callback()); 3949 EXPECT_EQ(ERR_IO_PENDING, rv); 3950 3951 rv = callback2.WaitForResult(); 3952 EXPECT_EQ(OK, rv); 3953 3954 load_timing_info = LoadTimingInfo(); 3955 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3956 // Retrying with HTTP AUTH is considered to be reusing a socket. 3957 TestLoadTimingReused(load_timing_info); 3958 3959 response = trans->GetResponseInfo(); 3960 ASSERT_TRUE(response != NULL); 3961 3962 EXPECT_TRUE(response->headers->IsKeepAlive()); 3963 EXPECT_EQ(200, response->headers->response_code()); 3964 EXPECT_EQ(100, response->headers->GetContentLength()); 3965 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 3966 3967 // The password prompt info should not be set. 3968 EXPECT_TRUE(response->auth_challenge.get() == NULL); 3969 } 3970 3971 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( 3972 const MockRead& status, int expected_status) { 3973 HttpRequestInfo request; 3974 request.method = "GET"; 3975 request.url = GURL("https://www.google.com/"); 3976 request.load_flags = 0; 3977 3978 // Configure against proxy server "myproxy:70". 3979 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 3980 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3981 3982 // Since we have proxy, should try to establish tunnel. 3983 MockWrite data_writes[] = { 3984 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 3985 "Host: www.google.com\r\n" 3986 "Proxy-Connection: keep-alive\r\n\r\n"), 3987 }; 3988 3989 MockRead data_reads[] = { 3990 status, 3991 MockRead("Content-Length: 10\r\n\r\n"), 3992 // No response body because the test stops reading here. 3993 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 3994 }; 3995 3996 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 3997 data_writes, arraysize(data_writes)); 3998 session_deps_.socket_factory->AddSocketDataProvider(&data); 3999 4000 TestCompletionCallback callback; 4001 4002 scoped_ptr<HttpTransaction> trans( 4003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4004 4005 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4006 EXPECT_EQ(ERR_IO_PENDING, rv); 4007 4008 rv = callback.WaitForResult(); 4009 EXPECT_EQ(expected_status, rv); 4010 } 4011 4012 void HttpNetworkTransactionTest::ConnectStatusHelper( 4013 const MockRead& status) { 4014 ConnectStatusHelperWithExpectedStatus( 4015 status, ERR_TUNNEL_CONNECTION_FAILED); 4016 } 4017 4018 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) { 4019 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n")); 4020 } 4021 4022 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) { 4023 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n")); 4024 } 4025 4026 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) { 4027 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n")); 4028 } 4029 4030 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) { 4031 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n")); 4032 } 4033 4034 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) { 4035 ConnectStatusHelper( 4036 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n")); 4037 } 4038 4039 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) { 4040 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n")); 4041 } 4042 4043 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) { 4044 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n")); 4045 } 4046 4047 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) { 4048 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n")); 4049 } 4050 4051 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) { 4052 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n")); 4053 } 4054 4055 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) { 4056 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n")); 4057 } 4058 4059 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) { 4060 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n")); 4061 } 4062 4063 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) { 4064 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n")); 4065 } 4066 4067 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) { 4068 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n")); 4069 } 4070 4071 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) { 4072 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n")); 4073 } 4074 4075 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) { 4076 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n")); 4077 } 4078 4079 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) { 4080 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n")); 4081 } 4082 4083 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) { 4084 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n")); 4085 } 4086 4087 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) { 4088 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n")); 4089 } 4090 4091 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) { 4092 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n")); 4093 } 4094 4095 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) { 4096 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n")); 4097 } 4098 4099 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) { 4100 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n")); 4101 } 4102 4103 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) { 4104 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n")); 4105 } 4106 4107 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) { 4108 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n")); 4109 } 4110 4111 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) { 4112 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n")); 4113 } 4114 4115 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) { 4116 ConnectStatusHelperWithExpectedStatus( 4117 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 4118 ERR_PROXY_AUTH_UNSUPPORTED); 4119 } 4120 4121 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) { 4122 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n")); 4123 } 4124 4125 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) { 4126 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n")); 4127 } 4128 4129 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) { 4130 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n")); 4131 } 4132 4133 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) { 4134 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n")); 4135 } 4136 4137 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) { 4138 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n")); 4139 } 4140 4141 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) { 4142 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n")); 4143 } 4144 4145 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) { 4146 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n")); 4147 } 4148 4149 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) { 4150 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n")); 4151 } 4152 4153 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) { 4154 ConnectStatusHelper( 4155 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n")); 4156 } 4157 4158 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) { 4159 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n")); 4160 } 4161 4162 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) { 4163 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n")); 4164 } 4165 4166 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) { 4167 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n")); 4168 } 4169 4170 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) { 4171 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n")); 4172 } 4173 4174 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) { 4175 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n")); 4176 } 4177 4178 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) { 4179 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n")); 4180 } 4181 4182 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) { 4183 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n")); 4184 } 4185 4186 // Test the flow when both the proxy server AND origin server require 4187 // authentication. Again, this uses basic auth for both since that is 4188 // the simplest to mock. 4189 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { 4190 HttpRequestInfo request; 4191 request.method = "GET"; 4192 request.url = GURL("http://www.google.com/"); 4193 request.load_flags = 0; 4194 4195 // Configure against proxy server "myproxy:70". 4196 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 4197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4198 4199 scoped_ptr<HttpTransaction> trans( 4200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4201 4202 MockWrite data_writes1[] = { 4203 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 4204 "Host: www.google.com\r\n" 4205 "Proxy-Connection: keep-alive\r\n\r\n"), 4206 }; 4207 4208 MockRead data_reads1[] = { 4209 MockRead("HTTP/1.0 407 Unauthorized\r\n"), 4210 // Give a couple authenticate options (only the middle one is actually 4211 // supported). 4212 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed. 4213 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4214 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 4215 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4216 // Large content-length -- won't matter, as connection will be reset. 4217 MockRead("Content-Length: 10000\r\n\r\n"), 4218 MockRead(SYNCHRONOUS, ERR_FAILED), 4219 }; 4220 4221 // After calling trans->RestartWithAuth() the first time, this is the 4222 // request we should be issuing -- the final header line contains the 4223 // proxy's credentials. 4224 MockWrite data_writes2[] = { 4225 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 4226 "Host: www.google.com\r\n" 4227 "Proxy-Connection: keep-alive\r\n" 4228 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 4229 }; 4230 4231 // Now the proxy server lets the request pass through to origin server. 4232 // The origin server responds with a 401. 4233 MockRead data_reads2[] = { 4234 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4235 // Note: We are using the same realm-name as the proxy server. This is 4236 // completely valid, as realms are unique across hosts. 4237 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4238 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4239 MockRead("Content-Length: 2000\r\n\r\n"), 4240 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached. 4241 }; 4242 4243 // After calling trans->RestartWithAuth() the second time, we should send 4244 // the credentials for both the proxy and origin server. 4245 MockWrite data_writes3[] = { 4246 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 4247 "Host: www.google.com\r\n" 4248 "Proxy-Connection: keep-alive\r\n" 4249 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n" 4250 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 4251 }; 4252 4253 // Lastly we get the desired content. 4254 MockRead data_reads3[] = { 4255 MockRead("HTTP/1.0 200 OK\r\n"), 4256 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4257 MockRead("Content-Length: 100\r\n\r\n"), 4258 MockRead(SYNCHRONOUS, OK), 4259 }; 4260 4261 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4262 data_writes1, arraysize(data_writes1)); 4263 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4264 data_writes2, arraysize(data_writes2)); 4265 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4266 data_writes3, arraysize(data_writes3)); 4267 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4268 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4269 session_deps_.socket_factory->AddSocketDataProvider(&data3); 4270 4271 TestCompletionCallback callback1; 4272 4273 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4274 EXPECT_EQ(ERR_IO_PENDING, rv); 4275 4276 rv = callback1.WaitForResult(); 4277 EXPECT_EQ(OK, rv); 4278 4279 const HttpResponseInfo* response = trans->GetResponseInfo(); 4280 ASSERT_TRUE(response != NULL); 4281 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 4282 4283 TestCompletionCallback callback2; 4284 4285 rv = trans->RestartWithAuth( 4286 AuthCredentials(kFoo, kBar), callback2.callback()); 4287 EXPECT_EQ(ERR_IO_PENDING, rv); 4288 4289 rv = callback2.WaitForResult(); 4290 EXPECT_EQ(OK, rv); 4291 4292 response = trans->GetResponseInfo(); 4293 ASSERT_TRUE(response != NULL); 4294 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 4295 4296 TestCompletionCallback callback3; 4297 4298 rv = trans->RestartWithAuth( 4299 AuthCredentials(kFoo2, kBar2), callback3.callback()); 4300 EXPECT_EQ(ERR_IO_PENDING, rv); 4301 4302 rv = callback3.WaitForResult(); 4303 EXPECT_EQ(OK, rv); 4304 4305 response = trans->GetResponseInfo(); 4306 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4307 EXPECT_EQ(100, response->headers->GetContentLength()); 4308 } 4309 4310 // For the NTLM implementation using SSPI, we skip the NTLM tests since we 4311 // can't hook into its internals to cause it to generate predictable NTLM 4312 // authorization headers. 4313 #if defined(NTLM_PORTABLE) 4314 // The NTLM authentication unit tests were generated by capturing the HTTP 4315 // requests and responses using Fiddler 2 and inspecting the generated random 4316 // bytes in the debugger. 4317 4318 // Enter the correct password and authenticate successfully. 4319 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) { 4320 HttpRequestInfo request; 4321 request.method = "GET"; 4322 request.url = GURL("http://172.22.68.17/kids/login.aspx"); 4323 4324 // Ensure load is not disrupted by flags which suppress behaviour specific 4325 // to other auth schemes. 4326 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; 4327 4328 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, 4329 MockGetHostName); 4330 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4331 4332 MockWrite data_writes1[] = { 4333 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4334 "Host: 172.22.68.17\r\n" 4335 "Connection: keep-alive\r\n\r\n"), 4336 }; 4337 4338 MockRead data_reads1[] = { 4339 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4340 // Negotiate and NTLM are often requested together. However, we only want 4341 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 4342 // the header that requests Negotiate for this test. 4343 MockRead("WWW-Authenticate: NTLM\r\n"), 4344 MockRead("Connection: close\r\n"), 4345 MockRead("Content-Length: 42\r\n"), 4346 MockRead("Content-Type: text/html\r\n\r\n"), 4347 // Missing content -- won't matter, as connection will be reset. 4348 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4349 }; 4350 4351 MockWrite data_writes2[] = { 4352 // After restarting with a null identity, this is the 4353 // request we should be issuing -- the final header line contains a Type 4354 // 1 message. 4355 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4356 "Host: 172.22.68.17\r\n" 4357 "Connection: keep-alive\r\n" 4358 "Authorization: NTLM " 4359 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4360 4361 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4362 // (the credentials for the origin server). The second request continues 4363 // on the same connection. 4364 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4365 "Host: 172.22.68.17\r\n" 4366 "Connection: keep-alive\r\n" 4367 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4368 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4369 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW" 4370 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX" 4371 "ahlhx5I=\r\n\r\n"), 4372 }; 4373 4374 MockRead data_reads2[] = { 4375 // The origin server responds with a Type 2 message. 4376 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4377 MockRead("WWW-Authenticate: NTLM " 4378 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo" 4379 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4380 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4381 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4382 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4383 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4384 "BtAAAAAAA=\r\n"), 4385 MockRead("Content-Length: 42\r\n"), 4386 MockRead("Content-Type: text/html\r\n\r\n"), 4387 MockRead("You are not authorized to view this page\r\n"), 4388 4389 // Lastly we get the desired content. 4390 MockRead("HTTP/1.1 200 OK\r\n"), 4391 MockRead("Content-Type: text/html; charset=utf-8\r\n"), 4392 MockRead("Content-Length: 13\r\n\r\n"), 4393 MockRead("Please Login\r\n"), 4394 MockRead(SYNCHRONOUS, OK), 4395 }; 4396 4397 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4398 data_writes1, arraysize(data_writes1)); 4399 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4400 data_writes2, arraysize(data_writes2)); 4401 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4402 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4403 4404 TestCompletionCallback callback1; 4405 4406 scoped_ptr<HttpTransaction> trans( 4407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4408 4409 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4410 EXPECT_EQ(ERR_IO_PENDING, rv); 4411 4412 rv = callback1.WaitForResult(); 4413 EXPECT_EQ(OK, rv); 4414 4415 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4416 4417 const HttpResponseInfo* response = trans->GetResponseInfo(); 4418 ASSERT_FALSE(response == NULL); 4419 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4420 4421 TestCompletionCallback callback2; 4422 4423 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), 4424 callback2.callback()); 4425 EXPECT_EQ(ERR_IO_PENDING, rv); 4426 4427 rv = callback2.WaitForResult(); 4428 EXPECT_EQ(OK, rv); 4429 4430 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4431 4432 response = trans->GetResponseInfo(); 4433 ASSERT_TRUE(response != NULL); 4434 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4435 4436 TestCompletionCallback callback3; 4437 4438 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); 4439 EXPECT_EQ(ERR_IO_PENDING, rv); 4440 4441 rv = callback3.WaitForResult(); 4442 EXPECT_EQ(OK, rv); 4443 4444 response = trans->GetResponseInfo(); 4445 ASSERT_TRUE(response != NULL); 4446 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4447 EXPECT_EQ(13, response->headers->GetContentLength()); 4448 } 4449 4450 // Enter a wrong password, and then the correct one. 4451 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) { 4452 HttpRequestInfo request; 4453 request.method = "GET"; 4454 request.url = GURL("http://172.22.68.17/kids/login.aspx"); 4455 request.load_flags = 0; 4456 4457 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2, 4458 MockGetHostName); 4459 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4460 4461 MockWrite data_writes1[] = { 4462 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4463 "Host: 172.22.68.17\r\n" 4464 "Connection: keep-alive\r\n\r\n"), 4465 }; 4466 4467 MockRead data_reads1[] = { 4468 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4469 // Negotiate and NTLM are often requested together. However, we only want 4470 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 4471 // the header that requests Negotiate for this test. 4472 MockRead("WWW-Authenticate: NTLM\r\n"), 4473 MockRead("Connection: close\r\n"), 4474 MockRead("Content-Length: 42\r\n"), 4475 MockRead("Content-Type: text/html\r\n\r\n"), 4476 // Missing content -- won't matter, as connection will be reset. 4477 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4478 }; 4479 4480 MockWrite data_writes2[] = { 4481 // After restarting with a null identity, this is the 4482 // request we should be issuing -- the final header line contains a Type 4483 // 1 message. 4484 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4485 "Host: 172.22.68.17\r\n" 4486 "Connection: keep-alive\r\n" 4487 "Authorization: NTLM " 4488 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4489 4490 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4491 // (the credentials for the origin server). The second request continues 4492 // on the same connection. 4493 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4494 "Host: 172.22.68.17\r\n" 4495 "Connection: keep-alive\r\n" 4496 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4497 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4498 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY" 4499 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj" 4500 "4Ww7b7E=\r\n\r\n"), 4501 }; 4502 4503 MockRead data_reads2[] = { 4504 // The origin server responds with a Type 2 message. 4505 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4506 MockRead("WWW-Authenticate: NTLM " 4507 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo" 4508 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4509 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4510 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4511 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4512 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4513 "BtAAAAAAA=\r\n"), 4514 MockRead("Content-Length: 42\r\n"), 4515 MockRead("Content-Type: text/html\r\n\r\n"), 4516 MockRead("You are not authorized to view this page\r\n"), 4517 4518 // Wrong password. 4519 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4520 MockRead("WWW-Authenticate: NTLM\r\n"), 4521 MockRead("Connection: close\r\n"), 4522 MockRead("Content-Length: 42\r\n"), 4523 MockRead("Content-Type: text/html\r\n\r\n"), 4524 // Missing content -- won't matter, as connection will be reset. 4525 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4526 }; 4527 4528 MockWrite data_writes3[] = { 4529 // After restarting with a null identity, this is the 4530 // request we should be issuing -- the final header line contains a Type 4531 // 1 message. 4532 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4533 "Host: 172.22.68.17\r\n" 4534 "Connection: keep-alive\r\n" 4535 "Authorization: NTLM " 4536 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4537 4538 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4539 // (the credentials for the origin server). The second request continues 4540 // on the same connection. 4541 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4542 "Host: 172.22.68.17\r\n" 4543 "Connection: keep-alive\r\n" 4544 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4545 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4546 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54" 4547 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI" 4548 "+4MUm7c=\r\n\r\n"), 4549 }; 4550 4551 MockRead data_reads3[] = { 4552 // The origin server responds with a Type 2 message. 4553 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4554 MockRead("WWW-Authenticate: NTLM " 4555 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo" 4556 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4557 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4558 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4559 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4560 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4561 "BtAAAAAAA=\r\n"), 4562 MockRead("Content-Length: 42\r\n"), 4563 MockRead("Content-Type: text/html\r\n\r\n"), 4564 MockRead("You are not authorized to view this page\r\n"), 4565 4566 // Lastly we get the desired content. 4567 MockRead("HTTP/1.1 200 OK\r\n"), 4568 MockRead("Content-Type: text/html; charset=utf-8\r\n"), 4569 MockRead("Content-Length: 13\r\n\r\n"), 4570 MockRead("Please Login\r\n"), 4571 MockRead(SYNCHRONOUS, OK), 4572 }; 4573 4574 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4575 data_writes1, arraysize(data_writes1)); 4576 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4577 data_writes2, arraysize(data_writes2)); 4578 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4579 data_writes3, arraysize(data_writes3)); 4580 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4581 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4582 session_deps_.socket_factory->AddSocketDataProvider(&data3); 4583 4584 TestCompletionCallback callback1; 4585 4586 scoped_ptr<HttpTransaction> trans( 4587 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4588 4589 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4590 EXPECT_EQ(ERR_IO_PENDING, rv); 4591 4592 rv = callback1.WaitForResult(); 4593 EXPECT_EQ(OK, rv); 4594 4595 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4596 4597 const HttpResponseInfo* response = trans->GetResponseInfo(); 4598 ASSERT_TRUE(response != NULL); 4599 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4600 4601 TestCompletionCallback callback2; 4602 4603 // Enter the wrong password. 4604 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword), 4605 callback2.callback()); 4606 EXPECT_EQ(ERR_IO_PENDING, rv); 4607 4608 rv = callback2.WaitForResult(); 4609 EXPECT_EQ(OK, rv); 4610 4611 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4612 TestCompletionCallback callback3; 4613 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); 4614 EXPECT_EQ(ERR_IO_PENDING, rv); 4615 rv = callback3.WaitForResult(); 4616 EXPECT_EQ(OK, rv); 4617 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4618 4619 response = trans->GetResponseInfo(); 4620 ASSERT_FALSE(response == NULL); 4621 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4622 4623 TestCompletionCallback callback4; 4624 4625 // Now enter the right password. 4626 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), 4627 callback4.callback()); 4628 EXPECT_EQ(ERR_IO_PENDING, rv); 4629 4630 rv = callback4.WaitForResult(); 4631 EXPECT_EQ(OK, rv); 4632 4633 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4634 4635 TestCompletionCallback callback5; 4636 4637 // One more roundtrip 4638 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback()); 4639 EXPECT_EQ(ERR_IO_PENDING, rv); 4640 4641 rv = callback5.WaitForResult(); 4642 EXPECT_EQ(OK, rv); 4643 4644 response = trans->GetResponseInfo(); 4645 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4646 EXPECT_EQ(13, response->headers->GetContentLength()); 4647 } 4648 #endif // NTLM_PORTABLE 4649 4650 // Test reading a server response which has only headers, and no body. 4651 // After some maximum number of bytes is consumed, the transaction should 4652 // fail with ERR_RESPONSE_HEADERS_TOO_BIG. 4653 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) { 4654 HttpRequestInfo request; 4655 request.method = "GET"; 4656 request.url = GURL("http://www.google.com/"); 4657 request.load_flags = 0; 4658 4659 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4660 scoped_ptr<HttpTransaction> trans( 4661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4662 4663 // Respond with 300 kb of headers (we should fail after 256 kb). 4664 std::string large_headers_string; 4665 FillLargeHeadersString(&large_headers_string, 300 * 1024); 4666 4667 MockRead data_reads[] = { 4668 MockRead("HTTP/1.0 200 OK\r\n"), 4669 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()), 4670 MockRead("\r\nBODY"), 4671 MockRead(SYNCHRONOUS, OK), 4672 }; 4673 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4674 session_deps_.socket_factory->AddSocketDataProvider(&data); 4675 4676 TestCompletionCallback callback; 4677 4678 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4679 EXPECT_EQ(ERR_IO_PENDING, rv); 4680 4681 rv = callback.WaitForResult(); 4682 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv); 4683 4684 const HttpResponseInfo* response = trans->GetResponseInfo(); 4685 EXPECT_TRUE(response == NULL); 4686 } 4687 4688 // Make sure that we don't try to reuse a TCPClientSocket when failing to 4689 // establish tunnel. 4690 // http://code.google.com/p/chromium/issues/detail?id=3772 4691 TEST_P(HttpNetworkTransactionTest, 4692 DontRecycleTransportSocketForSSLTunnel) { 4693 HttpRequestInfo request; 4694 request.method = "GET"; 4695 request.url = GURL("https://www.google.com/"); 4696 request.load_flags = 0; 4697 4698 // Configure against proxy server "myproxy:70". 4699 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 4700 4701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4702 4703 scoped_ptr<HttpTransaction> trans( 4704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4705 4706 // Since we have proxy, should try to establish tunnel. 4707 MockWrite data_writes1[] = { 4708 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 4709 "Host: www.google.com\r\n" 4710 "Proxy-Connection: keep-alive\r\n\r\n"), 4711 }; 4712 4713 // The proxy responds to the connect with a 404, using a persistent 4714 // connection. Usually a proxy would return 501 (not implemented), 4715 // or 200 (tunnel established). 4716 MockRead data_reads1[] = { 4717 MockRead("HTTP/1.1 404 Not Found\r\n"), 4718 MockRead("Content-Length: 10\r\n\r\n"), 4719 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 4720 }; 4721 4722 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4723 data_writes1, arraysize(data_writes1)); 4724 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4725 4726 TestCompletionCallback callback1; 4727 4728 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4729 EXPECT_EQ(ERR_IO_PENDING, rv); 4730 4731 rv = callback1.WaitForResult(); 4732 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 4733 4734 const HttpResponseInfo* response = trans->GetResponseInfo(); 4735 EXPECT_TRUE(response == NULL); 4736 4737 // Empty the current queue. This is necessary because idle sockets are 4738 // added to the connection pool asynchronously with a PostTask. 4739 base::MessageLoop::current()->RunUntilIdle(); 4740 4741 // We now check to make sure the TCPClientSocket was not added back to 4742 // the pool. 4743 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4744 trans.reset(); 4745 base::MessageLoop::current()->RunUntilIdle(); 4746 // Make sure that the socket didn't get recycled after calling the destructor. 4747 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4748 } 4749 4750 // Make sure that we recycle a socket after reading all of the response body. 4751 TEST_P(HttpNetworkTransactionTest, RecycleSocket) { 4752 HttpRequestInfo request; 4753 request.method = "GET"; 4754 request.url = GURL("http://www.google.com/"); 4755 request.load_flags = 0; 4756 4757 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4758 4759 scoped_ptr<HttpTransaction> trans( 4760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4761 4762 MockRead data_reads[] = { 4763 // A part of the response body is received with the response headers. 4764 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"), 4765 // The rest of the response body is received in two parts. 4766 MockRead("lo"), 4767 MockRead(" world"), 4768 MockRead("junk"), // Should not be read!! 4769 MockRead(SYNCHRONOUS, OK), 4770 }; 4771 4772 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4773 session_deps_.socket_factory->AddSocketDataProvider(&data); 4774 4775 TestCompletionCallback callback; 4776 4777 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4778 EXPECT_EQ(ERR_IO_PENDING, rv); 4779 4780 rv = callback.WaitForResult(); 4781 EXPECT_EQ(OK, rv); 4782 4783 const HttpResponseInfo* response = trans->GetResponseInfo(); 4784 ASSERT_TRUE(response != NULL); 4785 4786 EXPECT_TRUE(response->headers.get() != NULL); 4787 std::string status_line = response->headers->GetStatusLine(); 4788 EXPECT_EQ("HTTP/1.1 200 OK", status_line); 4789 4790 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4791 4792 std::string response_data; 4793 rv = ReadTransaction(trans.get(), &response_data); 4794 EXPECT_EQ(OK, rv); 4795 EXPECT_EQ("hello world", response_data); 4796 4797 // Empty the current queue. This is necessary because idle sockets are 4798 // added to the connection pool asynchronously with a PostTask. 4799 base::MessageLoop::current()->RunUntilIdle(); 4800 4801 // We now check to make sure the socket was added back to the pool. 4802 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 4803 } 4804 4805 // Make sure that we recycle a SSL socket after reading all of the response 4806 // body. 4807 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) { 4808 HttpRequestInfo request; 4809 request.method = "GET"; 4810 request.url = GURL("https://www.google.com/"); 4811 request.load_flags = 0; 4812 4813 MockWrite data_writes[] = { 4814 MockWrite("GET / HTTP/1.1\r\n" 4815 "Host: www.google.com\r\n" 4816 "Connection: keep-alive\r\n\r\n"), 4817 }; 4818 4819 MockRead data_reads[] = { 4820 MockRead("HTTP/1.1 200 OK\r\n"), 4821 MockRead("Content-Length: 11\r\n\r\n"), 4822 MockRead("hello world"), 4823 MockRead(SYNCHRONOUS, OK), 4824 }; 4825 4826 SSLSocketDataProvider ssl(ASYNC, OK); 4827 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 4828 4829 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4830 data_writes, arraysize(data_writes)); 4831 session_deps_.socket_factory->AddSocketDataProvider(&data); 4832 4833 TestCompletionCallback callback; 4834 4835 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4836 scoped_ptr<HttpTransaction> trans( 4837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4838 4839 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4840 4841 EXPECT_EQ(ERR_IO_PENDING, rv); 4842 EXPECT_EQ(OK, callback.WaitForResult()); 4843 4844 const HttpResponseInfo* response = trans->GetResponseInfo(); 4845 ASSERT_TRUE(response != NULL); 4846 ASSERT_TRUE(response->headers.get() != NULL); 4847 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4848 4849 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4850 4851 std::string response_data; 4852 rv = ReadTransaction(trans.get(), &response_data); 4853 EXPECT_EQ(OK, rv); 4854 EXPECT_EQ("hello world", response_data); 4855 4856 // Empty the current queue. This is necessary because idle sockets are 4857 // added to the connection pool asynchronously with a PostTask. 4858 base::MessageLoop::current()->RunUntilIdle(); 4859 4860 // We now check to make sure the socket was added back to the pool. 4861 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4862 } 4863 4864 // Grab a SSL socket, use it, and put it back into the pool. Then, reuse it 4865 // from the pool and make sure that we recover okay. 4866 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) { 4867 HttpRequestInfo request; 4868 request.method = "GET"; 4869 request.url = GURL("https://www.google.com/"); 4870 request.load_flags = 0; 4871 4872 MockWrite data_writes[] = { 4873 MockWrite("GET / HTTP/1.1\r\n" 4874 "Host: www.google.com\r\n" 4875 "Connection: keep-alive\r\n\r\n"), 4876 MockWrite("GET / HTTP/1.1\r\n" 4877 "Host: www.google.com\r\n" 4878 "Connection: keep-alive\r\n\r\n"), 4879 }; 4880 4881 MockRead data_reads[] = { 4882 MockRead("HTTP/1.1 200 OK\r\n"), 4883 MockRead("Content-Length: 11\r\n\r\n"), 4884 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 4885 MockRead("hello world"), 4886 MockRead(ASYNC, 0, 0) // EOF 4887 }; 4888 4889 SSLSocketDataProvider ssl(ASYNC, OK); 4890 SSLSocketDataProvider ssl2(ASYNC, OK); 4891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 4892 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 4893 4894 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4895 data_writes, arraysize(data_writes)); 4896 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), 4897 data_writes, arraysize(data_writes)); 4898 session_deps_.socket_factory->AddSocketDataProvider(&data); 4899 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4900 4901 TestCompletionCallback callback; 4902 4903 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4904 scoped_ptr<HttpTransaction> trans( 4905 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4906 4907 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4908 4909 EXPECT_EQ(ERR_IO_PENDING, rv); 4910 EXPECT_EQ(OK, callback.WaitForResult()); 4911 4912 const HttpResponseInfo* response = trans->GetResponseInfo(); 4913 ASSERT_TRUE(response != NULL); 4914 ASSERT_TRUE(response->headers.get() != NULL); 4915 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4916 4917 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4918 4919 std::string response_data; 4920 rv = ReadTransaction(trans.get(), &response_data); 4921 EXPECT_EQ(OK, rv); 4922 EXPECT_EQ("hello world", response_data); 4923 4924 // Empty the current queue. This is necessary because idle sockets are 4925 // added to the connection pool asynchronously with a PostTask. 4926 base::MessageLoop::current()->RunUntilIdle(); 4927 4928 // We now check to make sure the socket was added back to the pool. 4929 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4930 4931 // Now start the second transaction, which should reuse the previous socket. 4932 4933 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4934 4935 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4936 4937 EXPECT_EQ(ERR_IO_PENDING, rv); 4938 EXPECT_EQ(OK, callback.WaitForResult()); 4939 4940 response = trans->GetResponseInfo(); 4941 ASSERT_TRUE(response != NULL); 4942 ASSERT_TRUE(response->headers.get() != NULL); 4943 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4944 4945 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4946 4947 rv = ReadTransaction(trans.get(), &response_data); 4948 EXPECT_EQ(OK, rv); 4949 EXPECT_EQ("hello world", response_data); 4950 4951 // Empty the current queue. This is necessary because idle sockets are 4952 // added to the connection pool asynchronously with a PostTask. 4953 base::MessageLoop::current()->RunUntilIdle(); 4954 4955 // We now check to make sure the socket was added back to the pool. 4956 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4957 } 4958 4959 // Make sure that we recycle a socket after a zero-length response. 4960 // http://crbug.com/9880 4961 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { 4962 HttpRequestInfo request; 4963 request.method = "GET"; 4964 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&" 4965 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&" 4966 "e=17259,18167,19592,19773,19981,20133,20173,20233&" 4967 "rt=prt.2642,ol.2649,xjs.2951"); 4968 request.load_flags = 0; 4969 4970 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4971 4972 scoped_ptr<HttpTransaction> trans( 4973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4974 4975 MockRead data_reads[] = { 4976 MockRead("HTTP/1.1 204 No Content\r\n" 4977 "Content-Length: 0\r\n" 4978 "Content-Type: text/html\r\n\r\n"), 4979 MockRead("junk"), // Should not be read!! 4980 MockRead(SYNCHRONOUS, OK), 4981 }; 4982 4983 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4984 session_deps_.socket_factory->AddSocketDataProvider(&data); 4985 4986 TestCompletionCallback callback; 4987 4988 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4989 EXPECT_EQ(ERR_IO_PENDING, rv); 4990 4991 rv = callback.WaitForResult(); 4992 EXPECT_EQ(OK, rv); 4993 4994 const HttpResponseInfo* response = trans->GetResponseInfo(); 4995 ASSERT_TRUE(response != NULL); 4996 4997 EXPECT_TRUE(response->headers.get() != NULL); 4998 std::string status_line = response->headers->GetStatusLine(); 4999 EXPECT_EQ("HTTP/1.1 204 No Content", status_line); 5000 5001 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 5002 5003 std::string response_data; 5004 rv = ReadTransaction(trans.get(), &response_data); 5005 EXPECT_EQ(OK, rv); 5006 EXPECT_EQ("", response_data); 5007 5008 // Empty the current queue. This is necessary because idle sockets are 5009 // added to the connection pool asynchronously with a PostTask. 5010 base::MessageLoop::current()->RunUntilIdle(); 5011 5012 // We now check to make sure the socket was added back to the pool. 5013 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 5014 } 5015 5016 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) { 5017 ScopedVector<UploadElementReader> element_readers; 5018 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 5019 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 5020 5021 HttpRequestInfo request[2]; 5022 // Transaction 1: a GET request that succeeds. The socket is recycled 5023 // after use. 5024 request[0].method = "GET"; 5025 request[0].url = GURL("http://www.google.com/"); 5026 request[0].load_flags = 0; 5027 // Transaction 2: a POST request. Reuses the socket kept alive from 5028 // transaction 1. The first attempts fails when writing the POST data. 5029 // This causes the transaction to retry with a new socket. The second 5030 // attempt succeeds. 5031 request[1].method = "POST"; 5032 request[1].url = GURL("http://www.google.com/login.cgi"); 5033 request[1].upload_data_stream = &upload_data_stream; 5034 request[1].load_flags = 0; 5035 5036 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5037 5038 // The first socket is used for transaction 1 and the first attempt of 5039 // transaction 2. 5040 5041 // The response of transaction 1. 5042 MockRead data_reads1[] = { 5043 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"), 5044 MockRead("hello world"), 5045 MockRead(SYNCHRONOUS, OK), 5046 }; 5047 // The mock write results of transaction 1 and the first attempt of 5048 // transaction 2. 5049 MockWrite data_writes1[] = { 5050 MockWrite(SYNCHRONOUS, 64), // GET 5051 MockWrite(SYNCHRONOUS, 93), // POST 5052 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data 5053 }; 5054 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5055 data_writes1, arraysize(data_writes1)); 5056 5057 // The second socket is used for the second attempt of transaction 2. 5058 5059 // The response of transaction 2. 5060 MockRead data_reads2[] = { 5061 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"), 5062 MockRead("welcome"), 5063 MockRead(SYNCHRONOUS, OK), 5064 }; 5065 // The mock write results of the second attempt of transaction 2. 5066 MockWrite data_writes2[] = { 5067 MockWrite(SYNCHRONOUS, 93), // POST 5068 MockWrite(SYNCHRONOUS, 3), // POST data 5069 }; 5070 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5071 data_writes2, arraysize(data_writes2)); 5072 5073 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5074 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5075 5076 const char* kExpectedResponseData[] = { 5077 "hello world", "welcome" 5078 }; 5079 5080 for (int i = 0; i < 2; ++i) { 5081 scoped_ptr<HttpTransaction> trans( 5082 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5083 5084 TestCompletionCallback callback; 5085 5086 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog()); 5087 EXPECT_EQ(ERR_IO_PENDING, rv); 5088 5089 rv = callback.WaitForResult(); 5090 EXPECT_EQ(OK, rv); 5091 5092 const HttpResponseInfo* response = trans->GetResponseInfo(); 5093 ASSERT_TRUE(response != NULL); 5094 5095 EXPECT_TRUE(response->headers.get() != NULL); 5096 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 5097 5098 std::string response_data; 5099 rv = ReadTransaction(trans.get(), &response_data); 5100 EXPECT_EQ(OK, rv); 5101 EXPECT_EQ(kExpectedResponseData[i], response_data); 5102 } 5103 } 5104 5105 // Test the request-challenge-retry sequence for basic auth when there is 5106 // an identity in the URL. The request should be sent as normal, but when 5107 // it fails the identity from the URL is used to answer the challenge. 5108 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) { 5109 HttpRequestInfo request; 5110 request.method = "GET"; 5111 request.url = GURL("http://foo:b@r@www.google.com/"); 5112 request.load_flags = LOAD_NORMAL; 5113 5114 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5115 scoped_ptr<HttpTransaction> trans( 5116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5117 5118 // The password contains an escaped character -- for this test to pass it 5119 // will need to be unescaped by HttpNetworkTransaction. 5120 EXPECT_EQ("b%40r", request.url.password()); 5121 5122 MockWrite data_writes1[] = { 5123 MockWrite("GET / HTTP/1.1\r\n" 5124 "Host: www.google.com\r\n" 5125 "Connection: keep-alive\r\n\r\n"), 5126 }; 5127 5128 MockRead data_reads1[] = { 5129 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5130 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5131 MockRead("Content-Length: 10\r\n\r\n"), 5132 MockRead(SYNCHRONOUS, ERR_FAILED), 5133 }; 5134 5135 // After the challenge above, the transaction will be restarted using the 5136 // identity from the url (foo, b@r) to answer the challenge. 5137 MockWrite data_writes2[] = { 5138 MockWrite("GET / HTTP/1.1\r\n" 5139 "Host: www.google.com\r\n" 5140 "Connection: keep-alive\r\n" 5141 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"), 5142 }; 5143 5144 MockRead data_reads2[] = { 5145 MockRead("HTTP/1.0 200 OK\r\n"), 5146 MockRead("Content-Length: 100\r\n\r\n"), 5147 MockRead(SYNCHRONOUS, OK), 5148 }; 5149 5150 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5151 data_writes1, arraysize(data_writes1)); 5152 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5153 data_writes2, arraysize(data_writes2)); 5154 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5155 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5156 5157 TestCompletionCallback callback1; 5158 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5159 EXPECT_EQ(ERR_IO_PENDING, rv); 5160 rv = callback1.WaitForResult(); 5161 EXPECT_EQ(OK, rv); 5162 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5163 5164 TestCompletionCallback callback2; 5165 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5166 EXPECT_EQ(ERR_IO_PENDING, rv); 5167 rv = callback2.WaitForResult(); 5168 EXPECT_EQ(OK, rv); 5169 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5170 5171 const HttpResponseInfo* response = trans->GetResponseInfo(); 5172 ASSERT_TRUE(response != NULL); 5173 5174 // There is no challenge info, since the identity in URL worked. 5175 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5176 5177 EXPECT_EQ(100, response->headers->GetContentLength()); 5178 5179 // Empty the current queue. 5180 base::MessageLoop::current()->RunUntilIdle(); 5181 } 5182 5183 // Test the request-challenge-retry sequence for basic auth when there is an 5184 // incorrect identity in the URL. The identity from the URL should be used only 5185 // once. 5186 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) { 5187 HttpRequestInfo request; 5188 request.method = "GET"; 5189 // Note: the URL has a username:password in it. The password "baz" is 5190 // wrong (should be "bar"). 5191 request.url = GURL("http://foo:baz@www.google.com/"); 5192 5193 request.load_flags = LOAD_NORMAL; 5194 5195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5196 scoped_ptr<HttpTransaction> trans( 5197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5198 5199 MockWrite data_writes1[] = { 5200 MockWrite("GET / HTTP/1.1\r\n" 5201 "Host: www.google.com\r\n" 5202 "Connection: keep-alive\r\n\r\n"), 5203 }; 5204 5205 MockRead data_reads1[] = { 5206 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5207 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5208 MockRead("Content-Length: 10\r\n\r\n"), 5209 MockRead(SYNCHRONOUS, ERR_FAILED), 5210 }; 5211 5212 // After the challenge above, the transaction will be restarted using the 5213 // identity from the url (foo, baz) to answer the challenge. 5214 MockWrite data_writes2[] = { 5215 MockWrite("GET / HTTP/1.1\r\n" 5216 "Host: www.google.com\r\n" 5217 "Connection: keep-alive\r\n" 5218 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 5219 }; 5220 5221 MockRead data_reads2[] = { 5222 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5223 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5224 MockRead("Content-Length: 10\r\n\r\n"), 5225 MockRead(SYNCHRONOUS, ERR_FAILED), 5226 }; 5227 5228 // After the challenge above, the transaction will be restarted using the 5229 // identity supplied by the user (foo, bar) to answer the challenge. 5230 MockWrite data_writes3[] = { 5231 MockWrite("GET / HTTP/1.1\r\n" 5232 "Host: www.google.com\r\n" 5233 "Connection: keep-alive\r\n" 5234 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5235 }; 5236 5237 MockRead data_reads3[] = { 5238 MockRead("HTTP/1.0 200 OK\r\n"), 5239 MockRead("Content-Length: 100\r\n\r\n"), 5240 MockRead(SYNCHRONOUS, OK), 5241 }; 5242 5243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5244 data_writes1, arraysize(data_writes1)); 5245 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5246 data_writes2, arraysize(data_writes2)); 5247 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 5248 data_writes3, arraysize(data_writes3)); 5249 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5250 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5251 session_deps_.socket_factory->AddSocketDataProvider(&data3); 5252 5253 TestCompletionCallback callback1; 5254 5255 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5256 EXPECT_EQ(ERR_IO_PENDING, rv); 5257 5258 rv = callback1.WaitForResult(); 5259 EXPECT_EQ(OK, rv); 5260 5261 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5262 TestCompletionCallback callback2; 5263 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5264 EXPECT_EQ(ERR_IO_PENDING, rv); 5265 rv = callback2.WaitForResult(); 5266 EXPECT_EQ(OK, rv); 5267 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5268 5269 const HttpResponseInfo* response = trans->GetResponseInfo(); 5270 ASSERT_TRUE(response != NULL); 5271 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5272 5273 TestCompletionCallback callback3; 5274 rv = trans->RestartWithAuth( 5275 AuthCredentials(kFoo, kBar), callback3.callback()); 5276 EXPECT_EQ(ERR_IO_PENDING, rv); 5277 rv = callback3.WaitForResult(); 5278 EXPECT_EQ(OK, rv); 5279 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5280 5281 response = trans->GetResponseInfo(); 5282 ASSERT_TRUE(response != NULL); 5283 5284 // There is no challenge info, since the identity worked. 5285 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5286 5287 EXPECT_EQ(100, response->headers->GetContentLength()); 5288 5289 // Empty the current queue. 5290 base::MessageLoop::current()->RunUntilIdle(); 5291 } 5292 5293 5294 // Test the request-challenge-retry sequence for basic auth when there is a 5295 // correct identity in the URL, but its use is being suppressed. The identity 5296 // from the URL should never be used. 5297 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) { 5298 HttpRequestInfo request; 5299 request.method = "GET"; 5300 request.url = GURL("http://foo:bar@www.google.com/"); 5301 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; 5302 5303 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5304 scoped_ptr<HttpTransaction> trans( 5305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5306 5307 MockWrite data_writes1[] = { 5308 MockWrite("GET / HTTP/1.1\r\n" 5309 "Host: www.google.com\r\n" 5310 "Connection: keep-alive\r\n\r\n"), 5311 }; 5312 5313 MockRead data_reads1[] = { 5314 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5315 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5316 MockRead("Content-Length: 10\r\n\r\n"), 5317 MockRead(SYNCHRONOUS, ERR_FAILED), 5318 }; 5319 5320 // After the challenge above, the transaction will be restarted using the 5321 // identity supplied by the user, not the one in the URL, to answer the 5322 // challenge. 5323 MockWrite data_writes3[] = { 5324 MockWrite("GET / HTTP/1.1\r\n" 5325 "Host: www.google.com\r\n" 5326 "Connection: keep-alive\r\n" 5327 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5328 }; 5329 5330 MockRead data_reads3[] = { 5331 MockRead("HTTP/1.0 200 OK\r\n"), 5332 MockRead("Content-Length: 100\r\n\r\n"), 5333 MockRead(SYNCHRONOUS, OK), 5334 }; 5335 5336 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5337 data_writes1, arraysize(data_writes1)); 5338 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 5339 data_writes3, arraysize(data_writes3)); 5340 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5341 session_deps_.socket_factory->AddSocketDataProvider(&data3); 5342 5343 TestCompletionCallback callback1; 5344 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5345 EXPECT_EQ(ERR_IO_PENDING, rv); 5346 rv = callback1.WaitForResult(); 5347 EXPECT_EQ(OK, rv); 5348 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5349 5350 const HttpResponseInfo* response = trans->GetResponseInfo(); 5351 ASSERT_TRUE(response != NULL); 5352 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5353 5354 TestCompletionCallback callback3; 5355 rv = trans->RestartWithAuth( 5356 AuthCredentials(kFoo, kBar), callback3.callback()); 5357 EXPECT_EQ(ERR_IO_PENDING, rv); 5358 rv = callback3.WaitForResult(); 5359 EXPECT_EQ(OK, rv); 5360 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5361 5362 response = trans->GetResponseInfo(); 5363 ASSERT_TRUE(response != NULL); 5364 5365 // There is no challenge info, since the identity worked. 5366 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5367 EXPECT_EQ(100, response->headers->GetContentLength()); 5368 5369 // Empty the current queue. 5370 base::MessageLoop::current()->RunUntilIdle(); 5371 } 5372 5373 // Test that previously tried username/passwords for a realm get re-used. 5374 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { 5375 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5376 5377 // Transaction 1: authenticate (foo, bar) on MyRealm1 5378 { 5379 HttpRequestInfo request; 5380 request.method = "GET"; 5381 request.url = GURL("http://www.google.com/x/y/z"); 5382 request.load_flags = 0; 5383 5384 scoped_ptr<HttpTransaction> trans( 5385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5386 5387 MockWrite data_writes1[] = { 5388 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5389 "Host: www.google.com\r\n" 5390 "Connection: keep-alive\r\n\r\n"), 5391 }; 5392 5393 MockRead data_reads1[] = { 5394 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5395 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5396 MockRead("Content-Length: 10000\r\n\r\n"), 5397 MockRead(SYNCHRONOUS, ERR_FAILED), 5398 }; 5399 5400 // Resend with authorization (username=foo, password=bar) 5401 MockWrite data_writes2[] = { 5402 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5403 "Host: www.google.com\r\n" 5404 "Connection: keep-alive\r\n" 5405 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5406 }; 5407 5408 // Sever accepts the authorization. 5409 MockRead data_reads2[] = { 5410 MockRead("HTTP/1.0 200 OK\r\n"), 5411 MockRead("Content-Length: 100\r\n\r\n"), 5412 MockRead(SYNCHRONOUS, OK), 5413 }; 5414 5415 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5416 data_writes1, arraysize(data_writes1)); 5417 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5418 data_writes2, arraysize(data_writes2)); 5419 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5420 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5421 5422 TestCompletionCallback callback1; 5423 5424 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5425 EXPECT_EQ(ERR_IO_PENDING, rv); 5426 5427 rv = callback1.WaitForResult(); 5428 EXPECT_EQ(OK, rv); 5429 5430 const HttpResponseInfo* response = trans->GetResponseInfo(); 5431 ASSERT_TRUE(response != NULL); 5432 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5433 5434 TestCompletionCallback callback2; 5435 5436 rv = trans->RestartWithAuth( 5437 AuthCredentials(kFoo, kBar), callback2.callback()); 5438 EXPECT_EQ(ERR_IO_PENDING, rv); 5439 5440 rv = callback2.WaitForResult(); 5441 EXPECT_EQ(OK, rv); 5442 5443 response = trans->GetResponseInfo(); 5444 ASSERT_TRUE(response != NULL); 5445 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5446 EXPECT_EQ(100, response->headers->GetContentLength()); 5447 } 5448 5449 // ------------------------------------------------------------------------ 5450 5451 // Transaction 2: authenticate (foo2, bar2) on MyRealm2 5452 { 5453 HttpRequestInfo request; 5454 request.method = "GET"; 5455 // Note that Transaction 1 was at /x/y/z, so this is in the same 5456 // protection space as MyRealm1. 5457 request.url = GURL("http://www.google.com/x/y/a/b"); 5458 request.load_flags = 0; 5459 5460 scoped_ptr<HttpTransaction> trans( 5461 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5462 5463 MockWrite data_writes1[] = { 5464 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5465 "Host: www.google.com\r\n" 5466 "Connection: keep-alive\r\n" 5467 // Send preemptive authorization for MyRealm1 5468 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5469 }; 5470 5471 // The server didn't like the preemptive authorization, and 5472 // challenges us for a different realm (MyRealm2). 5473 MockRead data_reads1[] = { 5474 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5475 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"), 5476 MockRead("Content-Length: 10000\r\n\r\n"), 5477 MockRead(SYNCHRONOUS, ERR_FAILED), 5478 }; 5479 5480 // Resend with authorization for MyRealm2 (username=foo2, password=bar2) 5481 MockWrite data_writes2[] = { 5482 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5483 "Host: www.google.com\r\n" 5484 "Connection: keep-alive\r\n" 5485 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 5486 }; 5487 5488 // Sever accepts the authorization. 5489 MockRead data_reads2[] = { 5490 MockRead("HTTP/1.0 200 OK\r\n"), 5491 MockRead("Content-Length: 100\r\n\r\n"), 5492 MockRead(SYNCHRONOUS, OK), 5493 }; 5494 5495 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5496 data_writes1, arraysize(data_writes1)); 5497 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5498 data_writes2, arraysize(data_writes2)); 5499 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5500 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5501 5502 TestCompletionCallback callback1; 5503 5504 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5505 EXPECT_EQ(ERR_IO_PENDING, rv); 5506 5507 rv = callback1.WaitForResult(); 5508 EXPECT_EQ(OK, rv); 5509 5510 const HttpResponseInfo* response = trans->GetResponseInfo(); 5511 ASSERT_TRUE(response != NULL); 5512 ASSERT_TRUE(response->auth_challenge.get()); 5513 EXPECT_FALSE(response->auth_challenge->is_proxy); 5514 EXPECT_EQ("www.google.com:80", 5515 response->auth_challenge->challenger.ToString()); 5516 EXPECT_EQ("MyRealm2", response->auth_challenge->realm); 5517 EXPECT_EQ("basic", response->auth_challenge->scheme); 5518 5519 TestCompletionCallback callback2; 5520 5521 rv = trans->RestartWithAuth( 5522 AuthCredentials(kFoo2, kBar2), callback2.callback()); 5523 EXPECT_EQ(ERR_IO_PENDING, rv); 5524 5525 rv = callback2.WaitForResult(); 5526 EXPECT_EQ(OK, rv); 5527 5528 response = trans->GetResponseInfo(); 5529 ASSERT_TRUE(response != NULL); 5530 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5531 EXPECT_EQ(100, response->headers->GetContentLength()); 5532 } 5533 5534 // ------------------------------------------------------------------------ 5535 5536 // Transaction 3: Resend a request in MyRealm's protection space -- 5537 // succeed with preemptive authorization. 5538 { 5539 HttpRequestInfo request; 5540 request.method = "GET"; 5541 request.url = GURL("http://www.google.com/x/y/z2"); 5542 request.load_flags = 0; 5543 5544 scoped_ptr<HttpTransaction> trans( 5545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5546 5547 MockWrite data_writes1[] = { 5548 MockWrite("GET /x/y/z2 HTTP/1.1\r\n" 5549 "Host: www.google.com\r\n" 5550 "Connection: keep-alive\r\n" 5551 // The authorization for MyRealm1 gets sent preemptively 5552 // (since the url is in the same protection space) 5553 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5554 }; 5555 5556 // Sever accepts the preemptive authorization 5557 MockRead data_reads1[] = { 5558 MockRead("HTTP/1.0 200 OK\r\n"), 5559 MockRead("Content-Length: 100\r\n\r\n"), 5560 MockRead(SYNCHRONOUS, OK), 5561 }; 5562 5563 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5564 data_writes1, arraysize(data_writes1)); 5565 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5566 5567 TestCompletionCallback callback1; 5568 5569 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5570 EXPECT_EQ(ERR_IO_PENDING, rv); 5571 5572 rv = callback1.WaitForResult(); 5573 EXPECT_EQ(OK, rv); 5574 5575 const HttpResponseInfo* response = trans->GetResponseInfo(); 5576 ASSERT_TRUE(response != NULL); 5577 5578 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5579 EXPECT_EQ(100, response->headers->GetContentLength()); 5580 } 5581 5582 // ------------------------------------------------------------------------ 5583 5584 // Transaction 4: request another URL in MyRealm (however the 5585 // url is not known to belong to the protection space, so no pre-auth). 5586 { 5587 HttpRequestInfo request; 5588 request.method = "GET"; 5589 request.url = GURL("http://www.google.com/x/1"); 5590 request.load_flags = 0; 5591 5592 scoped_ptr<HttpTransaction> trans( 5593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5594 5595 MockWrite data_writes1[] = { 5596 MockWrite("GET /x/1 HTTP/1.1\r\n" 5597 "Host: www.google.com\r\n" 5598 "Connection: keep-alive\r\n\r\n"), 5599 }; 5600 5601 MockRead data_reads1[] = { 5602 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5603 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5604 MockRead("Content-Length: 10000\r\n\r\n"), 5605 MockRead(SYNCHRONOUS, ERR_FAILED), 5606 }; 5607 5608 // Resend with authorization from MyRealm's cache. 5609 MockWrite data_writes2[] = { 5610 MockWrite("GET /x/1 HTTP/1.1\r\n" 5611 "Host: www.google.com\r\n" 5612 "Connection: keep-alive\r\n" 5613 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5614 }; 5615 5616 // Sever accepts the authorization. 5617 MockRead data_reads2[] = { 5618 MockRead("HTTP/1.0 200 OK\r\n"), 5619 MockRead("Content-Length: 100\r\n\r\n"), 5620 MockRead(SYNCHRONOUS, OK), 5621 }; 5622 5623 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5624 data_writes1, arraysize(data_writes1)); 5625 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5626 data_writes2, arraysize(data_writes2)); 5627 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5628 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5629 5630 TestCompletionCallback callback1; 5631 5632 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5633 EXPECT_EQ(ERR_IO_PENDING, rv); 5634 5635 rv = callback1.WaitForResult(); 5636 EXPECT_EQ(OK, rv); 5637 5638 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5639 TestCompletionCallback callback2; 5640 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5641 EXPECT_EQ(ERR_IO_PENDING, rv); 5642 rv = callback2.WaitForResult(); 5643 EXPECT_EQ(OK, rv); 5644 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5645 5646 const HttpResponseInfo* response = trans->GetResponseInfo(); 5647 ASSERT_TRUE(response != NULL); 5648 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5649 EXPECT_EQ(100, response->headers->GetContentLength()); 5650 } 5651 5652 // ------------------------------------------------------------------------ 5653 5654 // Transaction 5: request a URL in MyRealm, but the server rejects the 5655 // cached identity. Should invalidate and re-prompt. 5656 { 5657 HttpRequestInfo request; 5658 request.method = "GET"; 5659 request.url = GURL("http://www.google.com/p/q/t"); 5660 request.load_flags = 0; 5661 5662 scoped_ptr<HttpTransaction> trans( 5663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5664 5665 MockWrite data_writes1[] = { 5666 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5667 "Host: www.google.com\r\n" 5668 "Connection: keep-alive\r\n\r\n"), 5669 }; 5670 5671 MockRead data_reads1[] = { 5672 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5673 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5674 MockRead("Content-Length: 10000\r\n\r\n"), 5675 MockRead(SYNCHRONOUS, ERR_FAILED), 5676 }; 5677 5678 // Resend with authorization from cache for MyRealm. 5679 MockWrite data_writes2[] = { 5680 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5681 "Host: www.google.com\r\n" 5682 "Connection: keep-alive\r\n" 5683 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5684 }; 5685 5686 // Sever rejects the authorization. 5687 MockRead data_reads2[] = { 5688 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5689 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5690 MockRead("Content-Length: 10000\r\n\r\n"), 5691 MockRead(SYNCHRONOUS, ERR_FAILED), 5692 }; 5693 5694 // At this point we should prompt for new credentials for MyRealm. 5695 // Restart with username=foo3, password=foo4. 5696 MockWrite data_writes3[] = { 5697 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5698 "Host: www.google.com\r\n" 5699 "Connection: keep-alive\r\n" 5700 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"), 5701 }; 5702 5703 // Sever accepts the authorization. 5704 MockRead data_reads3[] = { 5705 MockRead("HTTP/1.0 200 OK\r\n"), 5706 MockRead("Content-Length: 100\r\n\r\n"), 5707 MockRead(SYNCHRONOUS, OK), 5708 }; 5709 5710 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5711 data_writes1, arraysize(data_writes1)); 5712 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5713 data_writes2, arraysize(data_writes2)); 5714 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 5715 data_writes3, arraysize(data_writes3)); 5716 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5717 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5718 session_deps_.socket_factory->AddSocketDataProvider(&data3); 5719 5720 TestCompletionCallback callback1; 5721 5722 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5723 EXPECT_EQ(ERR_IO_PENDING, rv); 5724 5725 rv = callback1.WaitForResult(); 5726 EXPECT_EQ(OK, rv); 5727 5728 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5729 TestCompletionCallback callback2; 5730 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5731 EXPECT_EQ(ERR_IO_PENDING, rv); 5732 rv = callback2.WaitForResult(); 5733 EXPECT_EQ(OK, rv); 5734 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5735 5736 const HttpResponseInfo* response = trans->GetResponseInfo(); 5737 ASSERT_TRUE(response != NULL); 5738 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5739 5740 TestCompletionCallback callback3; 5741 5742 rv = trans->RestartWithAuth( 5743 AuthCredentials(kFoo3, kBar3), callback3.callback()); 5744 EXPECT_EQ(ERR_IO_PENDING, rv); 5745 5746 rv = callback3.WaitForResult(); 5747 EXPECT_EQ(OK, rv); 5748 5749 response = trans->GetResponseInfo(); 5750 ASSERT_TRUE(response != NULL); 5751 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5752 EXPECT_EQ(100, response->headers->GetContentLength()); 5753 } 5754 } 5755 5756 // Tests that nonce count increments when multiple auth attempts 5757 // are started with the same nonce. 5758 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) { 5759 HttpAuthHandlerDigest::Factory* digest_factory = 5760 new HttpAuthHandlerDigest::Factory(); 5761 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator = 5762 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef"); 5763 digest_factory->set_nonce_generator(nonce_generator); 5764 session_deps_.http_auth_handler_factory.reset(digest_factory); 5765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5766 5767 // Transaction 1: authenticate (foo, bar) on MyRealm1 5768 { 5769 HttpRequestInfo request; 5770 request.method = "GET"; 5771 request.url = GURL("http://www.google.com/x/y/z"); 5772 request.load_flags = 0; 5773 5774 scoped_ptr<HttpTransaction> trans( 5775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5776 5777 MockWrite data_writes1[] = { 5778 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5779 "Host: www.google.com\r\n" 5780 "Connection: keep-alive\r\n\r\n"), 5781 }; 5782 5783 MockRead data_reads1[] = { 5784 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5785 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", " 5786 "algorithm=MD5, qop=\"auth\"\r\n\r\n"), 5787 MockRead(SYNCHRONOUS, OK), 5788 }; 5789 5790 // Resend with authorization (username=foo, password=bar) 5791 MockWrite data_writes2[] = { 5792 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5793 "Host: www.google.com\r\n" 5794 "Connection: keep-alive\r\n" 5795 "Authorization: Digest username=\"foo\", realm=\"digestive\", " 5796 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, " 5797 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, " 5798 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"), 5799 }; 5800 5801 // Sever accepts the authorization. 5802 MockRead data_reads2[] = { 5803 MockRead("HTTP/1.0 200 OK\r\n"), 5804 MockRead(SYNCHRONOUS, OK), 5805 }; 5806 5807 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5808 data_writes1, arraysize(data_writes1)); 5809 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5810 data_writes2, arraysize(data_writes2)); 5811 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5812 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5813 5814 TestCompletionCallback callback1; 5815 5816 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5817 EXPECT_EQ(ERR_IO_PENDING, rv); 5818 5819 rv = callback1.WaitForResult(); 5820 EXPECT_EQ(OK, rv); 5821 5822 const HttpResponseInfo* response = trans->GetResponseInfo(); 5823 ASSERT_TRUE(response != NULL); 5824 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get())); 5825 5826 TestCompletionCallback callback2; 5827 5828 rv = trans->RestartWithAuth( 5829 AuthCredentials(kFoo, kBar), callback2.callback()); 5830 EXPECT_EQ(ERR_IO_PENDING, rv); 5831 5832 rv = callback2.WaitForResult(); 5833 EXPECT_EQ(OK, rv); 5834 5835 response = trans->GetResponseInfo(); 5836 ASSERT_TRUE(response != NULL); 5837 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5838 } 5839 5840 // ------------------------------------------------------------------------ 5841 5842 // Transaction 2: Request another resource in digestive's protection space. 5843 // This will preemptively add an Authorization header which should have an 5844 // "nc" value of 2 (as compared to 1 in the first use. 5845 { 5846 HttpRequestInfo request; 5847 request.method = "GET"; 5848 // Note that Transaction 1 was at /x/y/z, so this is in the same 5849 // protection space as digest. 5850 request.url = GURL("http://www.google.com/x/y/a/b"); 5851 request.load_flags = 0; 5852 5853 scoped_ptr<HttpTransaction> trans( 5854 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5855 5856 MockWrite data_writes1[] = { 5857 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5858 "Host: www.google.com\r\n" 5859 "Connection: keep-alive\r\n" 5860 "Authorization: Digest username=\"foo\", realm=\"digestive\", " 5861 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, " 5862 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, " 5863 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"), 5864 }; 5865 5866 // Sever accepts the authorization. 5867 MockRead data_reads1[] = { 5868 MockRead("HTTP/1.0 200 OK\r\n"), 5869 MockRead("Content-Length: 100\r\n\r\n"), 5870 MockRead(SYNCHRONOUS, OK), 5871 }; 5872 5873 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5874 data_writes1, arraysize(data_writes1)); 5875 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5876 5877 TestCompletionCallback callback1; 5878 5879 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5880 EXPECT_EQ(ERR_IO_PENDING, rv); 5881 5882 rv = callback1.WaitForResult(); 5883 EXPECT_EQ(OK, rv); 5884 5885 const HttpResponseInfo* response = trans->GetResponseInfo(); 5886 ASSERT_TRUE(response != NULL); 5887 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5888 } 5889 } 5890 5891 // Test the ResetStateForRestart() private method. 5892 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) { 5893 // Create a transaction (the dependencies aren't important). 5894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5895 scoped_ptr<HttpNetworkTransaction> trans( 5896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5897 5898 // Setup some state (which we expect ResetStateForRestart() will clear). 5899 trans->read_buf_ = new IOBuffer(15); 5900 trans->read_buf_len_ = 15; 5901 trans->request_headers_.SetHeader("Authorization", "NTLM"); 5902 5903 // Setup state in response_ 5904 HttpResponseInfo* response = &trans->response_; 5905 response->auth_challenge = new AuthChallengeInfo(); 5906 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical. 5907 response->response_time = base::Time::Now(); 5908 response->was_cached = true; // (Wouldn't ever actually be true...) 5909 5910 { // Setup state for response_.vary_data 5911 HttpRequestInfo request; 5912 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n"); 5913 std::replace(temp.begin(), temp.end(), '\n', '\0'); 5914 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp)); 5915 request.extra_headers.SetHeader("Foo", "1"); 5916 request.extra_headers.SetHeader("bar", "23"); 5917 EXPECT_TRUE(response->vary_data.Init(request, *headers.get())); 5918 } 5919 5920 // Cause the above state to be reset. 5921 trans->ResetStateForRestart(); 5922 5923 // Verify that the state that needed to be reset, has been reset. 5924 EXPECT_TRUE(trans->read_buf_.get() == NULL); 5925 EXPECT_EQ(0, trans->read_buf_len_); 5926 EXPECT_TRUE(trans->request_headers_.IsEmpty()); 5927 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5928 EXPECT_TRUE(response->headers.get() == NULL); 5929 EXPECT_FALSE(response->was_cached); 5930 EXPECT_EQ(0U, response->ssl_info.cert_status); 5931 EXPECT_FALSE(response->vary_data.is_valid()); 5932 } 5933 5934 // Test HTTPS connections to a site with a bad certificate 5935 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) { 5936 HttpRequestInfo request; 5937 request.method = "GET"; 5938 request.url = GURL("https://www.google.com/"); 5939 request.load_flags = 0; 5940 5941 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5942 scoped_ptr<HttpTransaction> trans( 5943 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5944 5945 MockWrite data_writes[] = { 5946 MockWrite("GET / HTTP/1.1\r\n" 5947 "Host: www.google.com\r\n" 5948 "Connection: keep-alive\r\n\r\n"), 5949 }; 5950 5951 MockRead data_reads[] = { 5952 MockRead("HTTP/1.0 200 OK\r\n"), 5953 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5954 MockRead("Content-Length: 100\r\n\r\n"), 5955 MockRead(SYNCHRONOUS, OK), 5956 }; 5957 5958 StaticSocketDataProvider ssl_bad_certificate; 5959 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5960 data_writes, arraysize(data_writes)); 5961 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 5962 SSLSocketDataProvider ssl(ASYNC, OK); 5963 5964 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 5965 session_deps_.socket_factory->AddSocketDataProvider(&data); 5966 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 5967 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 5968 5969 TestCompletionCallback callback; 5970 5971 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5972 EXPECT_EQ(ERR_IO_PENDING, rv); 5973 5974 rv = callback.WaitForResult(); 5975 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 5976 5977 rv = trans->RestartIgnoringLastError(callback.callback()); 5978 EXPECT_EQ(ERR_IO_PENDING, rv); 5979 5980 rv = callback.WaitForResult(); 5981 EXPECT_EQ(OK, rv); 5982 5983 const HttpResponseInfo* response = trans->GetResponseInfo(); 5984 5985 ASSERT_TRUE(response != NULL); 5986 EXPECT_EQ(100, response->headers->GetContentLength()); 5987 } 5988 5989 // Test HTTPS connections to a site with a bad certificate, going through a 5990 // proxy 5991 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { 5992 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 5993 5994 HttpRequestInfo request; 5995 request.method = "GET"; 5996 request.url = GURL("https://www.google.com/"); 5997 request.load_flags = 0; 5998 5999 MockWrite proxy_writes[] = { 6000 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6001 "Host: www.google.com\r\n" 6002 "Proxy-Connection: keep-alive\r\n\r\n"), 6003 }; 6004 6005 MockRead proxy_reads[] = { 6006 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6007 MockRead(SYNCHRONOUS, OK) 6008 }; 6009 6010 MockWrite data_writes[] = { 6011 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6012 "Host: www.google.com\r\n" 6013 "Proxy-Connection: keep-alive\r\n\r\n"), 6014 MockWrite("GET / HTTP/1.1\r\n" 6015 "Host: www.google.com\r\n" 6016 "Connection: keep-alive\r\n\r\n"), 6017 }; 6018 6019 MockRead data_reads[] = { 6020 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6021 MockRead("HTTP/1.0 200 OK\r\n"), 6022 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6023 MockRead("Content-Length: 100\r\n\r\n"), 6024 MockRead(SYNCHRONOUS, OK), 6025 }; 6026 6027 StaticSocketDataProvider ssl_bad_certificate( 6028 proxy_reads, arraysize(proxy_reads), 6029 proxy_writes, arraysize(proxy_writes)); 6030 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6031 data_writes, arraysize(data_writes)); 6032 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 6033 SSLSocketDataProvider ssl(ASYNC, OK); 6034 6035 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 6036 session_deps_.socket_factory->AddSocketDataProvider(&data); 6037 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 6038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6039 6040 TestCompletionCallback callback; 6041 6042 for (int i = 0; i < 2; i++) { 6043 session_deps_.socket_factory->ResetNextMockIndexes(); 6044 6045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6046 scoped_ptr<HttpTransaction> trans( 6047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6048 6049 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6050 EXPECT_EQ(ERR_IO_PENDING, rv); 6051 6052 rv = callback.WaitForResult(); 6053 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 6054 6055 rv = trans->RestartIgnoringLastError(callback.callback()); 6056 EXPECT_EQ(ERR_IO_PENDING, rv); 6057 6058 rv = callback.WaitForResult(); 6059 EXPECT_EQ(OK, rv); 6060 6061 const HttpResponseInfo* response = trans->GetResponseInfo(); 6062 6063 ASSERT_TRUE(response != NULL); 6064 EXPECT_EQ(100, response->headers->GetContentLength()); 6065 } 6066 } 6067 6068 6069 // Test HTTPS connections to a site, going through an HTTPS proxy 6070 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { 6071 session_deps_.proxy_service.reset( 6072 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 6073 CapturingNetLog net_log; 6074 session_deps_.net_log = &net_log; 6075 6076 HttpRequestInfo request; 6077 request.method = "GET"; 6078 request.url = GURL("https://www.google.com/"); 6079 request.load_flags = 0; 6080 6081 MockWrite data_writes[] = { 6082 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6083 "Host: www.google.com\r\n" 6084 "Proxy-Connection: keep-alive\r\n\r\n"), 6085 MockWrite("GET / HTTP/1.1\r\n" 6086 "Host: www.google.com\r\n" 6087 "Connection: keep-alive\r\n\r\n"), 6088 }; 6089 6090 MockRead data_reads[] = { 6091 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6092 MockRead("HTTP/1.1 200 OK\r\n"), 6093 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6094 MockRead("Content-Length: 100\r\n\r\n"), 6095 MockRead(SYNCHRONOUS, OK), 6096 }; 6097 6098 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6099 data_writes, arraysize(data_writes)); 6100 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6101 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel 6102 6103 session_deps_.socket_factory->AddSocketDataProvider(&data); 6104 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6105 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl); 6106 6107 TestCompletionCallback callback; 6108 6109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6110 scoped_ptr<HttpTransaction> trans( 6111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6112 6113 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6114 EXPECT_EQ(ERR_IO_PENDING, rv); 6115 6116 rv = callback.WaitForResult(); 6117 EXPECT_EQ(OK, rv); 6118 const HttpResponseInfo* response = trans->GetResponseInfo(); 6119 6120 ASSERT_TRUE(response != NULL); 6121 6122 EXPECT_TRUE(response->headers->IsKeepAlive()); 6123 EXPECT_EQ(200, response->headers->response_code()); 6124 EXPECT_EQ(100, response->headers->GetContentLength()); 6125 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6126 6127 LoadTimingInfo load_timing_info; 6128 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6129 TestLoadTimingNotReusedWithPac(load_timing_info, 6130 CONNECT_TIMING_HAS_SSL_TIMES); 6131 } 6132 6133 // Test an HTTPS Proxy's ability to redirect a CONNECT request 6134 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { 6135 session_deps_.proxy_service.reset( 6136 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 6137 CapturingNetLog net_log; 6138 session_deps_.net_log = &net_log; 6139 6140 HttpRequestInfo request; 6141 request.method = "GET"; 6142 request.url = GURL("https://www.google.com/"); 6143 request.load_flags = 0; 6144 6145 MockWrite data_writes[] = { 6146 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6147 "Host: www.google.com\r\n" 6148 "Proxy-Connection: keep-alive\r\n\r\n"), 6149 }; 6150 6151 MockRead data_reads[] = { 6152 MockRead("HTTP/1.1 302 Redirect\r\n"), 6153 MockRead("Location: http://login.example.com/\r\n"), 6154 MockRead("Content-Length: 0\r\n\r\n"), 6155 MockRead(SYNCHRONOUS, OK), 6156 }; 6157 6158 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6159 data_writes, arraysize(data_writes)); 6160 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6161 6162 session_deps_.socket_factory->AddSocketDataProvider(&data); 6163 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6164 6165 TestCompletionCallback callback; 6166 6167 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6168 scoped_ptr<HttpTransaction> trans( 6169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6170 6171 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6172 EXPECT_EQ(ERR_IO_PENDING, rv); 6173 6174 rv = callback.WaitForResult(); 6175 EXPECT_EQ(OK, rv); 6176 const HttpResponseInfo* response = trans->GetResponseInfo(); 6177 6178 ASSERT_TRUE(response != NULL); 6179 6180 EXPECT_EQ(302, response->headers->response_code()); 6181 std::string url; 6182 EXPECT_TRUE(response->headers->IsRedirect(&url)); 6183 EXPECT_EQ("http://login.example.com/", url); 6184 6185 // In the case of redirects from proxies, HttpNetworkTransaction returns 6186 // timing for the proxy connection instead of the connection to the host, 6187 // and no send / receive times. 6188 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse. 6189 LoadTimingInfo load_timing_info; 6190 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6191 6192 EXPECT_FALSE(load_timing_info.socket_reused); 6193 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 6194 6195 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 6196 EXPECT_LE(load_timing_info.proxy_resolve_start, 6197 load_timing_info.proxy_resolve_end); 6198 EXPECT_LE(load_timing_info.proxy_resolve_end, 6199 load_timing_info.connect_timing.connect_start); 6200 ExpectConnectTimingHasTimes( 6201 load_timing_info.connect_timing, 6202 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES); 6203 6204 EXPECT_TRUE(load_timing_info.send_start.is_null()); 6205 EXPECT_TRUE(load_timing_info.send_end.is_null()); 6206 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 6207 } 6208 6209 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request 6210 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { 6211 session_deps_.proxy_service.reset( 6212 ProxyService::CreateFixed("https://proxy:70")); 6213 6214 HttpRequestInfo request; 6215 request.method = "GET"; 6216 request.url = GURL("https://www.google.com/"); 6217 request.load_flags = 0; 6218 6219 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 6220 LOWEST)); 6221 scoped_ptr<SpdyFrame> goaway( 6222 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 6223 MockWrite data_writes[] = { 6224 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS), 6225 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS), 6226 }; 6227 6228 static const char* const kExtraHeaders[] = { 6229 "location", 6230 "http://login.example.com/", 6231 }; 6232 scoped_ptr<SpdyFrame> resp( 6233 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders, 6234 arraysize(kExtraHeaders)/2, 1)); 6235 MockRead data_reads[] = { 6236 CreateMockRead(*resp.get(), 1, SYNCHRONOUS), 6237 MockRead(ASYNC, 0, 2), // EOF 6238 }; 6239 6240 DelayedSocketData data( 6241 1, // wait for one write to finish before reading. 6242 data_reads, arraysize(data_reads), 6243 data_writes, arraysize(data_writes)); 6244 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6245 proxy_ssl.SetNextProto(GetParam()); 6246 6247 session_deps_.socket_factory->AddSocketDataProvider(&data); 6248 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6249 6250 TestCompletionCallback callback; 6251 6252 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6253 scoped_ptr<HttpTransaction> trans( 6254 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6255 6256 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6257 EXPECT_EQ(ERR_IO_PENDING, rv); 6258 6259 rv = callback.WaitForResult(); 6260 EXPECT_EQ(OK, rv); 6261 const HttpResponseInfo* response = trans->GetResponseInfo(); 6262 6263 ASSERT_TRUE(response != NULL); 6264 6265 EXPECT_EQ(302, response->headers->response_code()); 6266 std::string url; 6267 EXPECT_TRUE(response->headers->IsRedirect(&url)); 6268 EXPECT_EQ("http://login.example.com/", url); 6269 } 6270 6271 // Test that an HTTPS proxy's response to a CONNECT request is filtered. 6272 TEST_P(HttpNetworkTransactionTest, 6273 ErrorResponseToHttpsConnectViaHttpsProxy) { 6274 session_deps_.proxy_service.reset( 6275 ProxyService::CreateFixed("https://proxy:70")); 6276 6277 HttpRequestInfo request; 6278 request.method = "GET"; 6279 request.url = GURL("https://www.google.com/"); 6280 request.load_flags = 0; 6281 6282 MockWrite data_writes[] = { 6283 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6284 "Host: www.google.com\r\n" 6285 "Proxy-Connection: keep-alive\r\n\r\n"), 6286 }; 6287 6288 MockRead data_reads[] = { 6289 MockRead("HTTP/1.1 404 Not Found\r\n"), 6290 MockRead("Content-Length: 23\r\n\r\n"), 6291 MockRead("The host does not exist"), 6292 MockRead(SYNCHRONOUS, OK), 6293 }; 6294 6295 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6296 data_writes, arraysize(data_writes)); 6297 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6298 6299 session_deps_.socket_factory->AddSocketDataProvider(&data); 6300 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6301 6302 TestCompletionCallback callback; 6303 6304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6305 scoped_ptr<HttpTransaction> trans( 6306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6307 6308 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6309 EXPECT_EQ(ERR_IO_PENDING, rv); 6310 6311 rv = callback.WaitForResult(); 6312 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 6313 6314 // TODO(ttuttle): Anything else to check here? 6315 } 6316 6317 // Test that a SPDY proxy's response to a CONNECT request is filtered. 6318 TEST_P(HttpNetworkTransactionTest, 6319 ErrorResponseToHttpsConnectViaSpdyProxy) { 6320 session_deps_.proxy_service.reset( 6321 ProxyService::CreateFixed("https://proxy:70")); 6322 6323 HttpRequestInfo request; 6324 request.method = "GET"; 6325 request.url = GURL("https://www.google.com/"); 6326 request.load_flags = 0; 6327 6328 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 6329 LOWEST)); 6330 scoped_ptr<SpdyFrame> rst( 6331 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 6332 MockWrite data_writes[] = { 6333 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS), 6334 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS), 6335 }; 6336 6337 static const char* const kExtraHeaders[] = { 6338 "location", 6339 "http://login.example.com/", 6340 }; 6341 scoped_ptr<SpdyFrame> resp( 6342 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders, 6343 arraysize(kExtraHeaders)/2, 1)); 6344 scoped_ptr<SpdyFrame> body( 6345 spdy_util_.ConstructSpdyBodyFrame( 6346 1, "The host does not exist", 23, true)); 6347 MockRead data_reads[] = { 6348 CreateMockRead(*resp.get(), 1, SYNCHRONOUS), 6349 CreateMockRead(*body.get(), 2, SYNCHRONOUS), 6350 MockRead(ASYNC, 0, 4), // EOF 6351 }; 6352 6353 DelayedSocketData data( 6354 1, // wait for one write to finish before reading. 6355 data_reads, arraysize(data_reads), 6356 data_writes, arraysize(data_writes)); 6357 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6358 proxy_ssl.SetNextProto(GetParam()); 6359 6360 session_deps_.socket_factory->AddSocketDataProvider(&data); 6361 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6362 6363 TestCompletionCallback callback; 6364 6365 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6366 scoped_ptr<HttpTransaction> trans( 6367 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6368 6369 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6370 EXPECT_EQ(ERR_IO_PENDING, rv); 6371 6372 rv = callback.WaitForResult(); 6373 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 6374 6375 // TODO(ttuttle): Anything else to check here? 6376 } 6377 6378 // Test the request-challenge-retry sequence for basic auth, through 6379 // a SPDY proxy over a single SPDY session. 6380 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) { 6381 HttpRequestInfo request; 6382 request.method = "GET"; 6383 request.url = GURL("https://www.google.com/"); 6384 // when the no authentication data flag is set. 6385 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 6386 6387 // Configure against https proxy server "myproxy:70". 6388 session_deps_.proxy_service.reset( 6389 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); 6390 CapturingBoundNetLog log; 6391 session_deps_.net_log = log.bound().net_log(); 6392 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6393 6394 // Since we have proxy, should try to establish tunnel. 6395 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 6396 LOWEST)); 6397 scoped_ptr<SpdyFrame> rst( 6398 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 6399 6400 // After calling trans->RestartWithAuth(), this is the request we should 6401 // be issuing -- the final header line contains the credentials. 6402 const char* const kAuthCredentials[] = { 6403 "proxy-authorization", "Basic Zm9vOmJhcg==", 6404 }; 6405 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect( 6406 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST)); 6407 // fetch https://www.google.com/ via HTTP 6408 const char get[] = "GET / HTTP/1.1\r\n" 6409 "Host: www.google.com\r\n" 6410 "Connection: keep-alive\r\n\r\n"; 6411 scoped_ptr<SpdyFrame> wrapped_get( 6412 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false)); 6413 6414 MockWrite spdy_writes[] = { 6415 CreateMockWrite(*req, 1, ASYNC), 6416 CreateMockWrite(*rst, 4, ASYNC), 6417 CreateMockWrite(*connect2, 5), 6418 CreateMockWrite(*wrapped_get, 8), 6419 }; 6420 6421 // The proxy responds to the connect with a 407, using a persistent 6422 // connection. 6423 const char* const kAuthStatus = "407"; 6424 const char* const kAuthChallenge[] = { 6425 "proxy-authenticate", "Basic realm=\"MyRealm1\"", 6426 }; 6427 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError( 6428 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1)); 6429 6430 scoped_ptr<SpdyFrame> conn_resp( 6431 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 6432 const char resp[] = "HTTP/1.1 200 OK\r\n" 6433 "Content-Length: 5\r\n\r\n"; 6434 6435 scoped_ptr<SpdyFrame> wrapped_get_resp( 6436 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false)); 6437 scoped_ptr<SpdyFrame> wrapped_body( 6438 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false)); 6439 MockRead spdy_reads[] = { 6440 CreateMockRead(*conn_auth_resp, 2, ASYNC), 6441 CreateMockRead(*conn_resp, 6, ASYNC), 6442 CreateMockRead(*wrapped_get_resp, 9, ASYNC), 6443 CreateMockRead(*wrapped_body, 10, ASYNC), 6444 MockRead(ASYNC, OK, 11), // EOF. May or may not be read. 6445 }; 6446 6447 OrderedSocketData spdy_data( 6448 spdy_reads, arraysize(spdy_reads), 6449 spdy_writes, arraysize(spdy_writes)); 6450 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6451 // Negotiate SPDY to the proxy 6452 SSLSocketDataProvider proxy(ASYNC, OK); 6453 proxy.SetNextProto(GetParam()); 6454 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6455 // Vanilla SSL to the server 6456 SSLSocketDataProvider server(ASYNC, OK); 6457 session_deps_.socket_factory->AddSSLSocketDataProvider(&server); 6458 6459 TestCompletionCallback callback1; 6460 6461 scoped_ptr<HttpTransaction> trans( 6462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6463 6464 int rv = trans->Start(&request, callback1.callback(), log.bound()); 6465 EXPECT_EQ(ERR_IO_PENDING, rv); 6466 6467 rv = callback1.WaitForResult(); 6468 EXPECT_EQ(OK, rv); 6469 net::CapturingNetLog::CapturedEntryList entries; 6470 log.GetEntries(&entries); 6471 size_t pos = ExpectLogContainsSomewhere( 6472 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 6473 NetLog::PHASE_NONE); 6474 ExpectLogContainsSomewhere( 6475 entries, pos, 6476 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 6477 NetLog::PHASE_NONE); 6478 6479 const HttpResponseInfo* response = trans->GetResponseInfo(); 6480 ASSERT_TRUE(response != NULL); 6481 ASSERT_FALSE(response->headers.get() == NULL); 6482 EXPECT_EQ(407, response->headers->response_code()); 6483 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6484 EXPECT_TRUE(response->auth_challenge.get() != NULL); 6485 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 6486 6487 TestCompletionCallback callback2; 6488 6489 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), 6490 callback2.callback()); 6491 EXPECT_EQ(ERR_IO_PENDING, rv); 6492 6493 rv = callback2.WaitForResult(); 6494 EXPECT_EQ(OK, rv); 6495 6496 response = trans->GetResponseInfo(); 6497 ASSERT_TRUE(response != NULL); 6498 6499 EXPECT_TRUE(response->headers->IsKeepAlive()); 6500 EXPECT_EQ(200, response->headers->response_code()); 6501 EXPECT_EQ(5, response->headers->GetContentLength()); 6502 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6503 6504 // The password prompt info should not be set. 6505 EXPECT_TRUE(response->auth_challenge.get() == NULL); 6506 6507 LoadTimingInfo load_timing_info; 6508 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6509 TestLoadTimingNotReusedWithPac(load_timing_info, 6510 CONNECT_TIMING_HAS_SSL_TIMES); 6511 6512 trans.reset(); 6513 session->CloseAllConnections(); 6514 } 6515 6516 // Test that an explicitly trusted SPDY proxy can push a resource from an 6517 // origin that is different from that of its associated resource. 6518 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) { 6519 HttpRequestInfo request; 6520 HttpRequestInfo push_request; 6521 6522 request.method = "GET"; 6523 request.url = GURL("http://www.google.com/"); 6524 push_request.method = "GET"; 6525 push_request.url = GURL("http://www.another-origin.com/foo.dat"); 6526 6527 // Configure against https proxy server "myproxy:70". 6528 session_deps_.proxy_service.reset( 6529 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); 6530 CapturingBoundNetLog log; 6531 session_deps_.net_log = log.bound().net_log(); 6532 6533 // Enable cross-origin push. 6534 session_deps_.trusted_spdy_proxy = "myproxy:70"; 6535 6536 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6537 6538 scoped_ptr<SpdyFrame> stream1_syn( 6539 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 6540 6541 MockWrite spdy_writes[] = { 6542 CreateMockWrite(*stream1_syn, 1, ASYNC), 6543 }; 6544 6545 scoped_ptr<SpdyFrame> 6546 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 6547 6548 scoped_ptr<SpdyFrame> 6549 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6550 6551 scoped_ptr<SpdyFrame> 6552 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 6553 0, 6554 2, 6555 1, 6556 "http://www.another-origin.com/foo.dat")); 6557 const char kPushedData[] = "pushed"; 6558 scoped_ptr<SpdyFrame> stream2_body( 6559 spdy_util_.ConstructSpdyBodyFrame( 6560 2, kPushedData, strlen(kPushedData), true)); 6561 6562 MockRead spdy_reads[] = { 6563 CreateMockRead(*stream1_reply, 2, ASYNC), 6564 CreateMockRead(*stream2_syn, 3, ASYNC), 6565 CreateMockRead(*stream1_body, 4, ASYNC), 6566 CreateMockRead(*stream2_body, 5, ASYNC), 6567 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 6568 }; 6569 6570 OrderedSocketData spdy_data( 6571 spdy_reads, arraysize(spdy_reads), 6572 spdy_writes, arraysize(spdy_writes)); 6573 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6574 // Negotiate SPDY to the proxy 6575 SSLSocketDataProvider proxy(ASYNC, OK); 6576 proxy.SetNextProto(GetParam()); 6577 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6578 6579 scoped_ptr<HttpTransaction> trans( 6580 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6581 TestCompletionCallback callback; 6582 int rv = trans->Start(&request, callback.callback(), log.bound()); 6583 EXPECT_EQ(ERR_IO_PENDING, rv); 6584 6585 rv = callback.WaitForResult(); 6586 EXPECT_EQ(OK, rv); 6587 const HttpResponseInfo* response = trans->GetResponseInfo(); 6588 6589 scoped_ptr<HttpTransaction> push_trans( 6590 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6591 rv = push_trans->Start(&push_request, callback.callback(), log.bound()); 6592 EXPECT_EQ(ERR_IO_PENDING, rv); 6593 6594 rv = callback.WaitForResult(); 6595 EXPECT_EQ(OK, rv); 6596 const HttpResponseInfo* push_response = push_trans->GetResponseInfo(); 6597 6598 ASSERT_TRUE(response != NULL); 6599 EXPECT_TRUE(response->headers->IsKeepAlive()); 6600 6601 EXPECT_EQ(200, response->headers->response_code()); 6602 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6603 6604 std::string response_data; 6605 rv = ReadTransaction(trans.get(), &response_data); 6606 EXPECT_EQ(OK, rv); 6607 EXPECT_EQ("hello!", response_data); 6608 6609 LoadTimingInfo load_timing_info; 6610 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6611 TestLoadTimingNotReusedWithPac(load_timing_info, 6612 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 6613 6614 // Verify the pushed stream. 6615 EXPECT_TRUE(push_response->headers.get() != NULL); 6616 EXPECT_EQ(200, push_response->headers->response_code()); 6617 6618 rv = ReadTransaction(push_trans.get(), &response_data); 6619 EXPECT_EQ(OK, rv); 6620 EXPECT_EQ("pushed", response_data); 6621 6622 LoadTimingInfo push_load_timing_info; 6623 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info)); 6624 TestLoadTimingReusedWithPac(push_load_timing_info); 6625 // The transactions should share a socket ID, despite being for different 6626 // origins. 6627 EXPECT_EQ(load_timing_info.socket_log_id, 6628 push_load_timing_info.socket_log_id); 6629 6630 trans.reset(); 6631 push_trans.reset(); 6632 session->CloseAllConnections(); 6633 } 6634 6635 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content. 6636 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) { 6637 HttpRequestInfo request; 6638 6639 request.method = "GET"; 6640 request.url = GURL("http://www.google.com/"); 6641 6642 // Configure against https proxy server "myproxy:70". 6643 session_deps_.proxy_service.reset( 6644 ProxyService::CreateFixed("https://myproxy:70")); 6645 CapturingBoundNetLog log; 6646 session_deps_.net_log = log.bound().net_log(); 6647 6648 // Enable cross-origin push. 6649 session_deps_.trusted_spdy_proxy = "myproxy:70"; 6650 6651 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6652 6653 scoped_ptr<SpdyFrame> stream1_syn( 6654 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 6655 6656 scoped_ptr<SpdyFrame> push_rst( 6657 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 6658 6659 MockWrite spdy_writes[] = { 6660 CreateMockWrite(*stream1_syn, 1, ASYNC), 6661 CreateMockWrite(*push_rst, 4), 6662 }; 6663 6664 scoped_ptr<SpdyFrame> 6665 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 6666 6667 scoped_ptr<SpdyFrame> 6668 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6669 6670 scoped_ptr<SpdyFrame> 6671 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 6672 0, 6673 2, 6674 1, 6675 "https://www.another-origin.com/foo.dat")); 6676 6677 MockRead spdy_reads[] = { 6678 CreateMockRead(*stream1_reply, 2, ASYNC), 6679 CreateMockRead(*stream2_syn, 3, ASYNC), 6680 CreateMockRead(*stream1_body, 5, ASYNC), 6681 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 6682 }; 6683 6684 OrderedSocketData spdy_data( 6685 spdy_reads, arraysize(spdy_reads), 6686 spdy_writes, arraysize(spdy_writes)); 6687 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6688 // Negotiate SPDY to the proxy 6689 SSLSocketDataProvider proxy(ASYNC, OK); 6690 proxy.SetNextProto(GetParam()); 6691 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6692 6693 scoped_ptr<HttpTransaction> trans( 6694 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6695 TestCompletionCallback callback; 6696 int rv = trans->Start(&request, callback.callback(), log.bound()); 6697 EXPECT_EQ(ERR_IO_PENDING, rv); 6698 6699 rv = callback.WaitForResult(); 6700 EXPECT_EQ(OK, rv); 6701 const HttpResponseInfo* response = trans->GetResponseInfo(); 6702 6703 ASSERT_TRUE(response != NULL); 6704 EXPECT_TRUE(response->headers->IsKeepAlive()); 6705 6706 EXPECT_EQ(200, response->headers->response_code()); 6707 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6708 6709 std::string response_data; 6710 rv = ReadTransaction(trans.get(), &response_data); 6711 EXPECT_EQ(OK, rv); 6712 EXPECT_EQ("hello!", response_data); 6713 6714 trans.reset(); 6715 session->CloseAllConnections(); 6716 } 6717 6718 // Test HTTPS connections to a site with a bad certificate, going through an 6719 // HTTPS proxy 6720 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) { 6721 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 6722 "https://proxy:70")); 6723 6724 HttpRequestInfo request; 6725 request.method = "GET"; 6726 request.url = GURL("https://www.google.com/"); 6727 request.load_flags = 0; 6728 6729 // Attempt to fetch the URL from a server with a bad cert 6730 MockWrite bad_cert_writes[] = { 6731 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6732 "Host: www.google.com\r\n" 6733 "Proxy-Connection: keep-alive\r\n\r\n"), 6734 }; 6735 6736 MockRead bad_cert_reads[] = { 6737 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6738 MockRead(SYNCHRONOUS, OK) 6739 }; 6740 6741 // Attempt to fetch the URL with a good cert 6742 MockWrite good_data_writes[] = { 6743 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6744 "Host: www.google.com\r\n" 6745 "Proxy-Connection: keep-alive\r\n\r\n"), 6746 MockWrite("GET / HTTP/1.1\r\n" 6747 "Host: www.google.com\r\n" 6748 "Connection: keep-alive\r\n\r\n"), 6749 }; 6750 6751 MockRead good_cert_reads[] = { 6752 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6753 MockRead("HTTP/1.0 200 OK\r\n"), 6754 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6755 MockRead("Content-Length: 100\r\n\r\n"), 6756 MockRead(SYNCHRONOUS, OK), 6757 }; 6758 6759 StaticSocketDataProvider ssl_bad_certificate( 6760 bad_cert_reads, arraysize(bad_cert_reads), 6761 bad_cert_writes, arraysize(bad_cert_writes)); 6762 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads), 6763 good_data_writes, arraysize(good_data_writes)); 6764 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 6765 SSLSocketDataProvider ssl(ASYNC, OK); 6766 6767 // SSL to the proxy, then CONNECT request, then SSL with bad certificate 6768 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6769 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 6770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 6771 6772 // SSL to the proxy, then CONNECT request, then valid SSL certificate 6773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6774 session_deps_.socket_factory->AddSocketDataProvider(&data); 6775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6776 6777 TestCompletionCallback callback; 6778 6779 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6780 scoped_ptr<HttpTransaction> trans( 6781 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6782 6783 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6784 EXPECT_EQ(ERR_IO_PENDING, rv); 6785 6786 rv = callback.WaitForResult(); 6787 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 6788 6789 rv = trans->RestartIgnoringLastError(callback.callback()); 6790 EXPECT_EQ(ERR_IO_PENDING, rv); 6791 6792 rv = callback.WaitForResult(); 6793 EXPECT_EQ(OK, rv); 6794 6795 const HttpResponseInfo* response = trans->GetResponseInfo(); 6796 6797 ASSERT_TRUE(response != NULL); 6798 EXPECT_EQ(100, response->headers->GetContentLength()); 6799 } 6800 6801 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) { 6802 HttpRequestInfo request; 6803 request.method = "GET"; 6804 request.url = GURL("http://www.google.com/"); 6805 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 6806 "Chromium Ultra Awesome X Edition"); 6807 6808 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6809 scoped_ptr<HttpTransaction> trans( 6810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6811 6812 MockWrite data_writes[] = { 6813 MockWrite("GET / HTTP/1.1\r\n" 6814 "Host: www.google.com\r\n" 6815 "Connection: keep-alive\r\n" 6816 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 6817 }; 6818 6819 // Lastly, the server responds with the actual content. 6820 MockRead data_reads[] = { 6821 MockRead("HTTP/1.0 200 OK\r\n"), 6822 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6823 MockRead("Content-Length: 100\r\n\r\n"), 6824 MockRead(SYNCHRONOUS, OK), 6825 }; 6826 6827 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6828 data_writes, arraysize(data_writes)); 6829 session_deps_.socket_factory->AddSocketDataProvider(&data); 6830 6831 TestCompletionCallback callback; 6832 6833 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6834 EXPECT_EQ(ERR_IO_PENDING, rv); 6835 6836 rv = callback.WaitForResult(); 6837 EXPECT_EQ(OK, rv); 6838 } 6839 6840 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) { 6841 HttpRequestInfo request; 6842 request.method = "GET"; 6843 request.url = GURL("https://www.google.com/"); 6844 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 6845 "Chromium Ultra Awesome X Edition"); 6846 6847 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 6848 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6849 scoped_ptr<HttpTransaction> trans( 6850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6851 6852 MockWrite data_writes[] = { 6853 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6854 "Host: www.google.com\r\n" 6855 "Proxy-Connection: keep-alive\r\n" 6856 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 6857 }; 6858 MockRead data_reads[] = { 6859 // Return an error, so the transaction stops here (this test isn't 6860 // interested in the rest). 6861 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 6862 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 6863 MockRead("Proxy-Connection: close\r\n\r\n"), 6864 }; 6865 6866 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6867 data_writes, arraysize(data_writes)); 6868 session_deps_.socket_factory->AddSocketDataProvider(&data); 6869 6870 TestCompletionCallback callback; 6871 6872 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6873 EXPECT_EQ(ERR_IO_PENDING, rv); 6874 6875 rv = callback.WaitForResult(); 6876 EXPECT_EQ(OK, rv); 6877 } 6878 6879 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) { 6880 HttpRequestInfo request; 6881 request.method = "GET"; 6882 request.url = GURL("http://www.google.com/"); 6883 request.load_flags = 0; 6884 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer, 6885 "http://the.previous.site.com/"); 6886 6887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6888 scoped_ptr<HttpTransaction> trans( 6889 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6890 6891 MockWrite data_writes[] = { 6892 MockWrite("GET / HTTP/1.1\r\n" 6893 "Host: www.google.com\r\n" 6894 "Connection: keep-alive\r\n" 6895 "Referer: http://the.previous.site.com/\r\n\r\n"), 6896 }; 6897 6898 // Lastly, the server responds with the actual content. 6899 MockRead data_reads[] = { 6900 MockRead("HTTP/1.0 200 OK\r\n"), 6901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6902 MockRead("Content-Length: 100\r\n\r\n"), 6903 MockRead(SYNCHRONOUS, OK), 6904 }; 6905 6906 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6907 data_writes, arraysize(data_writes)); 6908 session_deps_.socket_factory->AddSocketDataProvider(&data); 6909 6910 TestCompletionCallback callback; 6911 6912 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6913 EXPECT_EQ(ERR_IO_PENDING, rv); 6914 6915 rv = callback.WaitForResult(); 6916 EXPECT_EQ(OK, rv); 6917 } 6918 6919 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) { 6920 HttpRequestInfo request; 6921 request.method = "POST"; 6922 request.url = GURL("http://www.google.com/"); 6923 6924 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6925 scoped_ptr<HttpTransaction> trans( 6926 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6927 6928 MockWrite data_writes[] = { 6929 MockWrite("POST / HTTP/1.1\r\n" 6930 "Host: www.google.com\r\n" 6931 "Connection: keep-alive\r\n" 6932 "Content-Length: 0\r\n\r\n"), 6933 }; 6934 6935 // Lastly, the server responds with the actual content. 6936 MockRead data_reads[] = { 6937 MockRead("HTTP/1.0 200 OK\r\n"), 6938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6939 MockRead("Content-Length: 100\r\n\r\n"), 6940 MockRead(SYNCHRONOUS, OK), 6941 }; 6942 6943 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6944 data_writes, arraysize(data_writes)); 6945 session_deps_.socket_factory->AddSocketDataProvider(&data); 6946 6947 TestCompletionCallback callback; 6948 6949 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6950 EXPECT_EQ(ERR_IO_PENDING, rv); 6951 6952 rv = callback.WaitForResult(); 6953 EXPECT_EQ(OK, rv); 6954 } 6955 6956 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) { 6957 HttpRequestInfo request; 6958 request.method = "PUT"; 6959 request.url = GURL("http://www.google.com/"); 6960 6961 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6962 scoped_ptr<HttpTransaction> trans( 6963 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6964 6965 MockWrite data_writes[] = { 6966 MockWrite("PUT / HTTP/1.1\r\n" 6967 "Host: www.google.com\r\n" 6968 "Connection: keep-alive\r\n" 6969 "Content-Length: 0\r\n\r\n"), 6970 }; 6971 6972 // Lastly, the server responds with the actual content. 6973 MockRead data_reads[] = { 6974 MockRead("HTTP/1.0 200 OK\r\n"), 6975 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6976 MockRead("Content-Length: 100\r\n\r\n"), 6977 MockRead(SYNCHRONOUS, OK), 6978 }; 6979 6980 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6981 data_writes, arraysize(data_writes)); 6982 session_deps_.socket_factory->AddSocketDataProvider(&data); 6983 6984 TestCompletionCallback callback; 6985 6986 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6987 EXPECT_EQ(ERR_IO_PENDING, rv); 6988 6989 rv = callback.WaitForResult(); 6990 EXPECT_EQ(OK, rv); 6991 } 6992 6993 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) { 6994 HttpRequestInfo request; 6995 request.method = "HEAD"; 6996 request.url = GURL("http://www.google.com/"); 6997 6998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6999 scoped_ptr<HttpTransaction> trans( 7000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7001 7002 MockWrite data_writes[] = { 7003 MockWrite("HEAD / HTTP/1.1\r\n" 7004 "Host: www.google.com\r\n" 7005 "Connection: keep-alive\r\n" 7006 "Content-Length: 0\r\n\r\n"), 7007 }; 7008 7009 // Lastly, the server responds with the actual content. 7010 MockRead data_reads[] = { 7011 MockRead("HTTP/1.0 200 OK\r\n"), 7012 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7013 MockRead("Content-Length: 100\r\n\r\n"), 7014 MockRead(SYNCHRONOUS, OK), 7015 }; 7016 7017 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7018 data_writes, arraysize(data_writes)); 7019 session_deps_.socket_factory->AddSocketDataProvider(&data); 7020 7021 TestCompletionCallback callback; 7022 7023 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7024 EXPECT_EQ(ERR_IO_PENDING, rv); 7025 7026 rv = callback.WaitForResult(); 7027 EXPECT_EQ(OK, rv); 7028 } 7029 7030 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) { 7031 HttpRequestInfo request; 7032 request.method = "GET"; 7033 request.url = GURL("http://www.google.com/"); 7034 request.load_flags = LOAD_BYPASS_CACHE; 7035 7036 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7037 scoped_ptr<HttpTransaction> trans( 7038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7039 7040 MockWrite data_writes[] = { 7041 MockWrite("GET / HTTP/1.1\r\n" 7042 "Host: www.google.com\r\n" 7043 "Connection: keep-alive\r\n" 7044 "Pragma: no-cache\r\n" 7045 "Cache-Control: no-cache\r\n\r\n"), 7046 }; 7047 7048 // Lastly, the server responds with the actual content. 7049 MockRead data_reads[] = { 7050 MockRead("HTTP/1.0 200 OK\r\n"), 7051 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7052 MockRead("Content-Length: 100\r\n\r\n"), 7053 MockRead(SYNCHRONOUS, OK), 7054 }; 7055 7056 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7057 data_writes, arraysize(data_writes)); 7058 session_deps_.socket_factory->AddSocketDataProvider(&data); 7059 7060 TestCompletionCallback callback; 7061 7062 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7063 EXPECT_EQ(ERR_IO_PENDING, rv); 7064 7065 rv = callback.WaitForResult(); 7066 EXPECT_EQ(OK, rv); 7067 } 7068 7069 TEST_P(HttpNetworkTransactionTest, 7070 BuildRequest_CacheControlValidateCache) { 7071 HttpRequestInfo request; 7072 request.method = "GET"; 7073 request.url = GURL("http://www.google.com/"); 7074 request.load_flags = LOAD_VALIDATE_CACHE; 7075 7076 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7077 scoped_ptr<HttpTransaction> trans( 7078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7079 7080 MockWrite data_writes[] = { 7081 MockWrite("GET / HTTP/1.1\r\n" 7082 "Host: www.google.com\r\n" 7083 "Connection: keep-alive\r\n" 7084 "Cache-Control: max-age=0\r\n\r\n"), 7085 }; 7086 7087 // Lastly, the server responds with the actual content. 7088 MockRead data_reads[] = { 7089 MockRead("HTTP/1.0 200 OK\r\n"), 7090 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7091 MockRead("Content-Length: 100\r\n\r\n"), 7092 MockRead(SYNCHRONOUS, OK), 7093 }; 7094 7095 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7096 data_writes, arraysize(data_writes)); 7097 session_deps_.socket_factory->AddSocketDataProvider(&data); 7098 7099 TestCompletionCallback callback; 7100 7101 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7102 EXPECT_EQ(ERR_IO_PENDING, rv); 7103 7104 rv = callback.WaitForResult(); 7105 EXPECT_EQ(OK, rv); 7106 } 7107 7108 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) { 7109 HttpRequestInfo request; 7110 request.method = "GET"; 7111 request.url = GURL("http://www.google.com/"); 7112 request.extra_headers.SetHeader("FooHeader", "Bar"); 7113 7114 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7115 scoped_ptr<HttpTransaction> trans( 7116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7117 7118 MockWrite data_writes[] = { 7119 MockWrite("GET / HTTP/1.1\r\n" 7120 "Host: www.google.com\r\n" 7121 "Connection: keep-alive\r\n" 7122 "FooHeader: Bar\r\n\r\n"), 7123 }; 7124 7125 // Lastly, the server responds with the actual content. 7126 MockRead data_reads[] = { 7127 MockRead("HTTP/1.0 200 OK\r\n"), 7128 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7129 MockRead("Content-Length: 100\r\n\r\n"), 7130 MockRead(SYNCHRONOUS, OK), 7131 }; 7132 7133 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7134 data_writes, arraysize(data_writes)); 7135 session_deps_.socket_factory->AddSocketDataProvider(&data); 7136 7137 TestCompletionCallback callback; 7138 7139 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7140 EXPECT_EQ(ERR_IO_PENDING, rv); 7141 7142 rv = callback.WaitForResult(); 7143 EXPECT_EQ(OK, rv); 7144 } 7145 7146 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) { 7147 HttpRequestInfo request; 7148 request.method = "GET"; 7149 request.url = GURL("http://www.google.com/"); 7150 request.extra_headers.SetHeader("referer", "www.foo.com"); 7151 request.extra_headers.SetHeader("hEllo", "Kitty"); 7152 request.extra_headers.SetHeader("FoO", "bar"); 7153 7154 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7155 scoped_ptr<HttpTransaction> trans( 7156 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7157 7158 MockWrite data_writes[] = { 7159 MockWrite("GET / HTTP/1.1\r\n" 7160 "Host: www.google.com\r\n" 7161 "Connection: keep-alive\r\n" 7162 "referer: www.foo.com\r\n" 7163 "hEllo: Kitty\r\n" 7164 "FoO: bar\r\n\r\n"), 7165 }; 7166 7167 // Lastly, the server responds with the actual content. 7168 MockRead data_reads[] = { 7169 MockRead("HTTP/1.0 200 OK\r\n"), 7170 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7171 MockRead("Content-Length: 100\r\n\r\n"), 7172 MockRead(SYNCHRONOUS, OK), 7173 }; 7174 7175 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7176 data_writes, arraysize(data_writes)); 7177 session_deps_.socket_factory->AddSocketDataProvider(&data); 7178 7179 TestCompletionCallback callback; 7180 7181 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7182 EXPECT_EQ(ERR_IO_PENDING, rv); 7183 7184 rv = callback.WaitForResult(); 7185 EXPECT_EQ(OK, rv); 7186 } 7187 7188 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) { 7189 HttpRequestInfo request; 7190 request.method = "GET"; 7191 request.url = GURL("http://www.google.com/"); 7192 request.load_flags = 0; 7193 7194 session_deps_.proxy_service.reset( 7195 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080")); 7196 CapturingNetLog net_log; 7197 session_deps_.net_log = &net_log; 7198 7199 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7200 scoped_ptr<HttpTransaction> trans( 7201 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7202 7203 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; 7204 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 7205 7206 MockWrite data_writes[] = { 7207 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)), 7208 MockWrite("GET / HTTP/1.1\r\n" 7209 "Host: www.google.com\r\n" 7210 "Connection: keep-alive\r\n\r\n") 7211 }; 7212 7213 MockRead data_reads[] = { 7214 MockRead(ASYNC, read_buffer, arraysize(read_buffer)), 7215 MockRead("HTTP/1.0 200 OK\r\n"), 7216 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7217 MockRead("Payload"), 7218 MockRead(SYNCHRONOUS, OK) 7219 }; 7220 7221 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7222 data_writes, arraysize(data_writes)); 7223 session_deps_.socket_factory->AddSocketDataProvider(&data); 7224 7225 TestCompletionCallback callback; 7226 7227 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7228 EXPECT_EQ(ERR_IO_PENDING, rv); 7229 7230 rv = callback.WaitForResult(); 7231 EXPECT_EQ(OK, rv); 7232 7233 const HttpResponseInfo* response = trans->GetResponseInfo(); 7234 ASSERT_TRUE(response != NULL); 7235 7236 LoadTimingInfo load_timing_info; 7237 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7238 TestLoadTimingNotReusedWithPac(load_timing_info, 7239 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 7240 7241 std::string response_text; 7242 rv = ReadTransaction(trans.get(), &response_text); 7243 EXPECT_EQ(OK, rv); 7244 EXPECT_EQ("Payload", response_text); 7245 } 7246 7247 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) { 7248 HttpRequestInfo request; 7249 request.method = "GET"; 7250 request.url = GURL("https://www.google.com/"); 7251 request.load_flags = 0; 7252 7253 session_deps_.proxy_service.reset( 7254 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080")); 7255 CapturingNetLog net_log; 7256 session_deps_.net_log = &net_log; 7257 7258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7259 scoped_ptr<HttpTransaction> trans( 7260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7261 7262 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 }; 7263 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 7264 7265 MockWrite data_writes[] = { 7266 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer), 7267 arraysize(write_buffer)), 7268 MockWrite("GET / HTTP/1.1\r\n" 7269 "Host: www.google.com\r\n" 7270 "Connection: keep-alive\r\n\r\n") 7271 }; 7272 7273 MockRead data_reads[] = { 7274 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer), 7275 arraysize(read_buffer)), 7276 MockRead("HTTP/1.0 200 OK\r\n"), 7277 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7278 MockRead("Payload"), 7279 MockRead(SYNCHRONOUS, OK) 7280 }; 7281 7282 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7283 data_writes, arraysize(data_writes)); 7284 session_deps_.socket_factory->AddSocketDataProvider(&data); 7285 7286 SSLSocketDataProvider ssl(ASYNC, OK); 7287 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 7288 7289 TestCompletionCallback callback; 7290 7291 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7292 EXPECT_EQ(ERR_IO_PENDING, rv); 7293 7294 rv = callback.WaitForResult(); 7295 EXPECT_EQ(OK, rv); 7296 7297 LoadTimingInfo load_timing_info; 7298 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7299 TestLoadTimingNotReusedWithPac(load_timing_info, 7300 CONNECT_TIMING_HAS_SSL_TIMES); 7301 7302 const HttpResponseInfo* response = trans->GetResponseInfo(); 7303 ASSERT_TRUE(response != NULL); 7304 7305 std::string response_text; 7306 rv = ReadTransaction(trans.get(), &response_text); 7307 EXPECT_EQ(OK, rv); 7308 EXPECT_EQ("Payload", response_text); 7309 } 7310 7311 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) { 7312 HttpRequestInfo request; 7313 request.method = "GET"; 7314 request.url = GURL("http://www.google.com/"); 7315 request.load_flags = 0; 7316 7317 session_deps_.proxy_service.reset( 7318 ProxyService::CreateFixed("socks4://myproxy:1080")); 7319 CapturingNetLog net_log; 7320 session_deps_.net_log = &net_log; 7321 7322 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7323 scoped_ptr<HttpTransaction> trans( 7324 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7325 7326 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; 7327 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 7328 7329 MockWrite data_writes[] = { 7330 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)), 7331 MockWrite("GET / HTTP/1.1\r\n" 7332 "Host: www.google.com\r\n" 7333 "Connection: keep-alive\r\n\r\n") 7334 }; 7335 7336 MockRead data_reads[] = { 7337 MockRead(ASYNC, read_buffer, arraysize(read_buffer)), 7338 MockRead("HTTP/1.0 200 OK\r\n"), 7339 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7340 MockRead("Payload"), 7341 MockRead(SYNCHRONOUS, OK) 7342 }; 7343 7344 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7345 data_writes, arraysize(data_writes)); 7346 session_deps_.socket_factory->AddSocketDataProvider(&data); 7347 7348 TestCompletionCallback callback; 7349 7350 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7351 EXPECT_EQ(ERR_IO_PENDING, rv); 7352 7353 rv = callback.WaitForResult(); 7354 EXPECT_EQ(OK, rv); 7355 7356 const HttpResponseInfo* response = trans->GetResponseInfo(); 7357 ASSERT_TRUE(response != NULL); 7358 7359 LoadTimingInfo load_timing_info; 7360 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7361 TestLoadTimingNotReused(load_timing_info, 7362 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 7363 7364 std::string response_text; 7365 rv = ReadTransaction(trans.get(), &response_text); 7366 EXPECT_EQ(OK, rv); 7367 EXPECT_EQ("Payload", response_text); 7368 } 7369 7370 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) { 7371 HttpRequestInfo request; 7372 request.method = "GET"; 7373 request.url = GURL("http://www.google.com/"); 7374 request.load_flags = 0; 7375 7376 session_deps_.proxy_service.reset( 7377 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080")); 7378 CapturingNetLog net_log; 7379 session_deps_.net_log = &net_log; 7380 7381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7382 scoped_ptr<HttpTransaction> trans( 7383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7384 7385 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 7386 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 7387 const char kSOCKS5OkRequest[] = { 7388 0x05, // Version 7389 0x01, // Command (CONNECT) 7390 0x00, // Reserved. 7391 0x03, // Address type (DOMAINNAME). 7392 0x0E, // Length of domain (14) 7393 // Domain string: 7394 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 7395 0x00, 0x50, // 16-bit port (80) 7396 }; 7397 const char kSOCKS5OkResponse[] = 7398 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 }; 7399 7400 MockWrite data_writes[] = { 7401 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 7402 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)), 7403 MockWrite("GET / HTTP/1.1\r\n" 7404 "Host: www.google.com\r\n" 7405 "Connection: keep-alive\r\n\r\n") 7406 }; 7407 7408 MockRead data_reads[] = { 7409 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 7410 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 7411 MockRead("HTTP/1.0 200 OK\r\n"), 7412 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7413 MockRead("Payload"), 7414 MockRead(SYNCHRONOUS, OK) 7415 }; 7416 7417 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7418 data_writes, arraysize(data_writes)); 7419 session_deps_.socket_factory->AddSocketDataProvider(&data); 7420 7421 TestCompletionCallback callback; 7422 7423 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7424 EXPECT_EQ(ERR_IO_PENDING, rv); 7425 7426 rv = callback.WaitForResult(); 7427 EXPECT_EQ(OK, rv); 7428 7429 const HttpResponseInfo* response = trans->GetResponseInfo(); 7430 ASSERT_TRUE(response != NULL); 7431 7432 LoadTimingInfo load_timing_info; 7433 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7434 TestLoadTimingNotReusedWithPac(load_timing_info, 7435 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 7436 7437 std::string response_text; 7438 rv = ReadTransaction(trans.get(), &response_text); 7439 EXPECT_EQ(OK, rv); 7440 EXPECT_EQ("Payload", response_text); 7441 } 7442 7443 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) { 7444 HttpRequestInfo request; 7445 request.method = "GET"; 7446 request.url = GURL("https://www.google.com/"); 7447 request.load_flags = 0; 7448 7449 session_deps_.proxy_service.reset( 7450 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080")); 7451 CapturingNetLog net_log; 7452 session_deps_.net_log = &net_log; 7453 7454 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7455 scoped_ptr<HttpTransaction> trans( 7456 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7457 7458 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 7459 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 7460 const unsigned char kSOCKS5OkRequest[] = { 7461 0x05, // Version 7462 0x01, // Command (CONNECT) 7463 0x00, // Reserved. 7464 0x03, // Address type (DOMAINNAME). 7465 0x0E, // Length of domain (14) 7466 // Domain string: 7467 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 7468 0x01, 0xBB, // 16-bit port (443) 7469 }; 7470 7471 const char kSOCKS5OkResponse[] = 7472 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 }; 7473 7474 MockWrite data_writes[] = { 7475 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 7476 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest), 7477 arraysize(kSOCKS5OkRequest)), 7478 MockWrite("GET / HTTP/1.1\r\n" 7479 "Host: www.google.com\r\n" 7480 "Connection: keep-alive\r\n\r\n") 7481 }; 7482 7483 MockRead data_reads[] = { 7484 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 7485 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 7486 MockRead("HTTP/1.0 200 OK\r\n"), 7487 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7488 MockRead("Payload"), 7489 MockRead(SYNCHRONOUS, OK) 7490 }; 7491 7492 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7493 data_writes, arraysize(data_writes)); 7494 session_deps_.socket_factory->AddSocketDataProvider(&data); 7495 7496 SSLSocketDataProvider ssl(ASYNC, OK); 7497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 7498 7499 TestCompletionCallback callback; 7500 7501 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7502 EXPECT_EQ(ERR_IO_PENDING, rv); 7503 7504 rv = callback.WaitForResult(); 7505 EXPECT_EQ(OK, rv); 7506 7507 const HttpResponseInfo* response = trans->GetResponseInfo(); 7508 ASSERT_TRUE(response != NULL); 7509 7510 LoadTimingInfo load_timing_info; 7511 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7512 TestLoadTimingNotReusedWithPac(load_timing_info, 7513 CONNECT_TIMING_HAS_SSL_TIMES); 7514 7515 std::string response_text; 7516 rv = ReadTransaction(trans.get(), &response_text); 7517 EXPECT_EQ(OK, rv); 7518 EXPECT_EQ("Payload", response_text); 7519 } 7520 7521 namespace { 7522 7523 // Tests that for connection endpoints the group names are correctly set. 7524 7525 struct GroupNameTest { 7526 std::string proxy_server; 7527 std::string url; 7528 std::string expected_group_name; 7529 bool ssl; 7530 }; 7531 7532 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests( 7533 NextProto next_proto, 7534 SpdySessionDependencies* session_deps_) { 7535 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_)); 7536 7537 base::WeakPtr<HttpServerProperties> http_server_properties = 7538 session->http_server_properties(); 7539 http_server_properties->SetAlternateProtocol( 7540 HostPortPair("host.with.alternate", 80), 443, 7541 AlternateProtocolFromNextProto(next_proto), 1); 7542 7543 return session; 7544 } 7545 7546 int GroupNameTransactionHelper( 7547 const std::string& url, 7548 const scoped_refptr<HttpNetworkSession>& session) { 7549 HttpRequestInfo request; 7550 request.method = "GET"; 7551 request.url = GURL(url); 7552 request.load_flags = 0; 7553 7554 scoped_ptr<HttpTransaction> trans( 7555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7556 7557 TestCompletionCallback callback; 7558 7559 // We do not complete this request, the dtor will clean the transaction up. 7560 return trans->Start(&request, callback.callback(), BoundNetLog()); 7561 } 7562 7563 } // namespace 7564 7565 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) { 7566 const GroupNameTest tests[] = { 7567 { 7568 "", // unused 7569 "http://www.google.com/direct", 7570 "www.google.com:80", 7571 false, 7572 }, 7573 { 7574 "", // unused 7575 "http://[2001:1418:13:1::25]/direct", 7576 "[2001:1418:13:1::25]:80", 7577 false, 7578 }, 7579 7580 // SSL Tests 7581 { 7582 "", // unused 7583 "https://www.google.com/direct_ssl", 7584 "ssl/www.google.com:443", 7585 true, 7586 }, 7587 { 7588 "", // unused 7589 "https://[2001:1418:13:1::25]/direct", 7590 "ssl/[2001:1418:13:1::25]:443", 7591 true, 7592 }, 7593 { 7594 "", // unused 7595 "http://host.with.alternate/direct", 7596 "ssl/host.with.alternate:443", 7597 true, 7598 }, 7599 }; 7600 7601 session_deps_.use_alternate_protocols = true; 7602 7603 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7604 session_deps_.proxy_service.reset( 7605 ProxyService::CreateFixed(tests[i].proxy_server)); 7606 scoped_refptr<HttpNetworkSession> session( 7607 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7608 7609 HttpNetworkSessionPeer peer(session); 7610 CaptureGroupNameTransportSocketPool* transport_conn_pool = 7611 new CaptureGroupNameTransportSocketPool(NULL, NULL); 7612 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7613 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7614 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7615 new MockClientSocketPoolManager); 7616 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 7617 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); 7618 peer.SetClientSocketPoolManager( 7619 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7620 7621 EXPECT_EQ(ERR_IO_PENDING, 7622 GroupNameTransactionHelper(tests[i].url, session)); 7623 if (tests[i].ssl) 7624 EXPECT_EQ(tests[i].expected_group_name, 7625 ssl_conn_pool->last_group_name_received()); 7626 else 7627 EXPECT_EQ(tests[i].expected_group_name, 7628 transport_conn_pool->last_group_name_received()); 7629 } 7630 7631 } 7632 7633 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) { 7634 const GroupNameTest tests[] = { 7635 { 7636 "http_proxy", 7637 "http://www.google.com/http_proxy_normal", 7638 "www.google.com:80", 7639 false, 7640 }, 7641 7642 // SSL Tests 7643 { 7644 "http_proxy", 7645 "https://www.google.com/http_connect_ssl", 7646 "ssl/www.google.com:443", 7647 true, 7648 }, 7649 7650 { 7651 "http_proxy", 7652 "http://host.with.alternate/direct", 7653 "ssl/host.with.alternate:443", 7654 true, 7655 }, 7656 7657 { 7658 "http_proxy", 7659 "ftp://ftp.google.com/http_proxy_normal", 7660 "ftp/ftp.google.com:21", 7661 false, 7662 }, 7663 }; 7664 7665 session_deps_.use_alternate_protocols = true; 7666 7667 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7668 session_deps_.proxy_service.reset( 7669 ProxyService::CreateFixed(tests[i].proxy_server)); 7670 scoped_refptr<HttpNetworkSession> session( 7671 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7672 7673 HttpNetworkSessionPeer peer(session); 7674 7675 HostPortPair proxy_host("http_proxy", 80); 7676 CaptureGroupNameHttpProxySocketPool* http_proxy_pool = 7677 new CaptureGroupNameHttpProxySocketPool(NULL, NULL); 7678 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7679 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7680 7681 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7682 new MockClientSocketPoolManager); 7683 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); 7684 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 7685 peer.SetClientSocketPoolManager( 7686 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7687 7688 EXPECT_EQ(ERR_IO_PENDING, 7689 GroupNameTransactionHelper(tests[i].url, session)); 7690 if (tests[i].ssl) 7691 EXPECT_EQ(tests[i].expected_group_name, 7692 ssl_conn_pool->last_group_name_received()); 7693 else 7694 EXPECT_EQ(tests[i].expected_group_name, 7695 http_proxy_pool->last_group_name_received()); 7696 } 7697 } 7698 7699 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) { 7700 const GroupNameTest tests[] = { 7701 { 7702 "socks4://socks_proxy:1080", 7703 "http://www.google.com/socks4_direct", 7704 "socks4/www.google.com:80", 7705 false, 7706 }, 7707 { 7708 "socks5://socks_proxy:1080", 7709 "http://www.google.com/socks5_direct", 7710 "socks5/www.google.com:80", 7711 false, 7712 }, 7713 7714 // SSL Tests 7715 { 7716 "socks4://socks_proxy:1080", 7717 "https://www.google.com/socks4_ssl", 7718 "socks4/ssl/www.google.com:443", 7719 true, 7720 }, 7721 { 7722 "socks5://socks_proxy:1080", 7723 "https://www.google.com/socks5_ssl", 7724 "socks5/ssl/www.google.com:443", 7725 true, 7726 }, 7727 7728 { 7729 "socks4://socks_proxy:1080", 7730 "http://host.with.alternate/direct", 7731 "socks4/ssl/host.with.alternate:443", 7732 true, 7733 }, 7734 }; 7735 7736 session_deps_.use_alternate_protocols = true; 7737 7738 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7739 session_deps_.proxy_service.reset( 7740 ProxyService::CreateFixed(tests[i].proxy_server)); 7741 scoped_refptr<HttpNetworkSession> session( 7742 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7743 7744 HttpNetworkSessionPeer peer(session); 7745 7746 HostPortPair proxy_host("socks_proxy", 1080); 7747 CaptureGroupNameSOCKSSocketPool* socks_conn_pool = 7748 new CaptureGroupNameSOCKSSocketPool(NULL, NULL); 7749 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7750 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7751 7752 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7753 new MockClientSocketPoolManager); 7754 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool); 7755 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 7756 peer.SetClientSocketPoolManager( 7757 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7758 7759 scoped_ptr<HttpTransaction> trans( 7760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7761 7762 EXPECT_EQ(ERR_IO_PENDING, 7763 GroupNameTransactionHelper(tests[i].url, session)); 7764 if (tests[i].ssl) 7765 EXPECT_EQ(tests[i].expected_group_name, 7766 ssl_conn_pool->last_group_name_received()); 7767 else 7768 EXPECT_EQ(tests[i].expected_group_name, 7769 socks_conn_pool->last_group_name_received()); 7770 } 7771 } 7772 7773 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) { 7774 HttpRequestInfo request; 7775 request.method = "GET"; 7776 request.url = GURL("http://www.google.com/"); 7777 7778 session_deps_.proxy_service.reset( 7779 ProxyService::CreateFixed("myproxy:70;foobar:80")); 7780 7781 // This simulates failure resolving all hostnames; that means we will fail 7782 // connecting to both proxies (myproxy:70 and foobar:80). 7783 session_deps_.host_resolver->rules()->AddSimulatedFailure("*"); 7784 7785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7786 scoped_ptr<HttpTransaction> trans( 7787 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7788 7789 TestCompletionCallback callback; 7790 7791 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7792 EXPECT_EQ(ERR_IO_PENDING, rv); 7793 7794 rv = callback.WaitForResult(); 7795 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv); 7796 } 7797 7798 // Base test to make sure that when the load flags for a request specify to 7799 // bypass the cache, the DNS cache is not used. 7800 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper( 7801 int load_flags) { 7802 // Issue a request, asking to bypass the cache(s). 7803 HttpRequestInfo request; 7804 request.method = "GET"; 7805 request.load_flags = load_flags; 7806 request.url = GURL("http://www.google.com/"); 7807 7808 // Select a host resolver that does caching. 7809 session_deps_.host_resolver.reset(new MockCachingHostResolver); 7810 7811 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7812 scoped_ptr<HttpTransaction> trans( 7813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7814 7815 // Warm up the host cache so it has an entry for "www.google.com". 7816 AddressList addrlist; 7817 TestCompletionCallback callback; 7818 int rv = session_deps_.host_resolver->Resolve( 7819 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), 7820 DEFAULT_PRIORITY, 7821 &addrlist, 7822 callback.callback(), 7823 NULL, 7824 BoundNetLog()); 7825 EXPECT_EQ(ERR_IO_PENDING, rv); 7826 rv = callback.WaitForResult(); 7827 EXPECT_EQ(OK, rv); 7828 7829 // Verify that it was added to host cache, by doing a subsequent async lookup 7830 // and confirming it completes synchronously. 7831 rv = session_deps_.host_resolver->Resolve( 7832 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), 7833 DEFAULT_PRIORITY, 7834 &addrlist, 7835 callback.callback(), 7836 NULL, 7837 BoundNetLog()); 7838 ASSERT_EQ(OK, rv); 7839 7840 // Inject a failure the next time that "www.google.com" is resolved. This way 7841 // we can tell if the next lookup hit the cache, or the "network". 7842 // (cache --> success, "network" --> failure). 7843 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com"); 7844 7845 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the 7846 // first read -- this won't be reached as the host resolution will fail first. 7847 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) }; 7848 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7849 session_deps_.socket_factory->AddSocketDataProvider(&data); 7850 7851 // Run the request. 7852 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7853 ASSERT_EQ(ERR_IO_PENDING, rv); 7854 rv = callback.WaitForResult(); 7855 7856 // If we bypassed the cache, we would have gotten a failure while resolving 7857 // "www.google.com". 7858 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); 7859 } 7860 7861 // There are multiple load flags that should trigger the host cache bypass. 7862 // Test each in isolation: 7863 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) { 7864 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE); 7865 } 7866 7867 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) { 7868 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE); 7869 } 7870 7871 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) { 7872 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE); 7873 } 7874 7875 // Make sure we can handle an error when writing the request. 7876 TEST_P(HttpNetworkTransactionTest, RequestWriteError) { 7877 HttpRequestInfo request; 7878 request.method = "GET"; 7879 request.url = GURL("http://www.foo.com/"); 7880 request.load_flags = 0; 7881 7882 MockWrite write_failure[] = { 7883 MockWrite(ASYNC, ERR_CONNECTION_RESET), 7884 }; 7885 StaticSocketDataProvider data(NULL, 0, 7886 write_failure, arraysize(write_failure)); 7887 session_deps_.socket_factory->AddSocketDataProvider(&data); 7888 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7889 7890 TestCompletionCallback callback; 7891 7892 scoped_ptr<HttpTransaction> trans( 7893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7894 7895 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7896 EXPECT_EQ(ERR_IO_PENDING, rv); 7897 7898 rv = callback.WaitForResult(); 7899 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 7900 } 7901 7902 // Check that a connection closed after the start of the headers finishes ok. 7903 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) { 7904 HttpRequestInfo request; 7905 request.method = "GET"; 7906 request.url = GURL("http://www.foo.com/"); 7907 request.load_flags = 0; 7908 7909 MockRead data_reads[] = { 7910 MockRead("HTTP/1."), 7911 MockRead(SYNCHRONOUS, OK), 7912 }; 7913 7914 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7915 session_deps_.socket_factory->AddSocketDataProvider(&data); 7916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7917 7918 TestCompletionCallback callback; 7919 7920 scoped_ptr<HttpTransaction> trans( 7921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7922 7923 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7924 EXPECT_EQ(ERR_IO_PENDING, rv); 7925 7926 rv = callback.WaitForResult(); 7927 EXPECT_EQ(OK, rv); 7928 7929 const HttpResponseInfo* response = trans->GetResponseInfo(); 7930 ASSERT_TRUE(response != NULL); 7931 7932 EXPECT_TRUE(response->headers.get() != NULL); 7933 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 7934 7935 std::string response_data; 7936 rv = ReadTransaction(trans.get(), &response_data); 7937 EXPECT_EQ(OK, rv); 7938 EXPECT_EQ("", response_data); 7939 } 7940 7941 // Make sure that a dropped connection while draining the body for auth 7942 // restart does the right thing. 7943 TEST_P(HttpNetworkTransactionTest, DrainResetOK) { 7944 HttpRequestInfo request; 7945 request.method = "GET"; 7946 request.url = GURL("http://www.google.com/"); 7947 request.load_flags = 0; 7948 7949 MockWrite data_writes1[] = { 7950 MockWrite("GET / HTTP/1.1\r\n" 7951 "Host: www.google.com\r\n" 7952 "Connection: keep-alive\r\n\r\n"), 7953 }; 7954 7955 MockRead data_reads1[] = { 7956 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 7957 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 7958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7959 MockRead("Content-Length: 14\r\n\r\n"), 7960 MockRead("Unauth"), 7961 MockRead(ASYNC, ERR_CONNECTION_RESET), 7962 }; 7963 7964 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 7965 data_writes1, arraysize(data_writes1)); 7966 session_deps_.socket_factory->AddSocketDataProvider(&data1); 7967 7968 // After calling trans->RestartWithAuth(), this is the request we should 7969 // be issuing -- the final header line contains the credentials. 7970 MockWrite data_writes2[] = { 7971 MockWrite("GET / HTTP/1.1\r\n" 7972 "Host: www.google.com\r\n" 7973 "Connection: keep-alive\r\n" 7974 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 7975 }; 7976 7977 // Lastly, the server responds with the actual content. 7978 MockRead data_reads2[] = { 7979 MockRead("HTTP/1.1 200 OK\r\n"), 7980 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7981 MockRead("Content-Length: 100\r\n\r\n"), 7982 MockRead(SYNCHRONOUS, OK), 7983 }; 7984 7985 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 7986 data_writes2, arraysize(data_writes2)); 7987 session_deps_.socket_factory->AddSocketDataProvider(&data2); 7988 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7989 7990 TestCompletionCallback callback1; 7991 7992 scoped_ptr<HttpTransaction> trans( 7993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7994 7995 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 7996 EXPECT_EQ(ERR_IO_PENDING, rv); 7997 7998 rv = callback1.WaitForResult(); 7999 EXPECT_EQ(OK, rv); 8000 8001 const HttpResponseInfo* response = trans->GetResponseInfo(); 8002 ASSERT_TRUE(response != NULL); 8003 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 8004 8005 TestCompletionCallback callback2; 8006 8007 rv = trans->RestartWithAuth( 8008 AuthCredentials(kFoo, kBar), callback2.callback()); 8009 EXPECT_EQ(ERR_IO_PENDING, rv); 8010 8011 rv = callback2.WaitForResult(); 8012 EXPECT_EQ(OK, rv); 8013 8014 response = trans->GetResponseInfo(); 8015 ASSERT_TRUE(response != NULL); 8016 EXPECT_TRUE(response->auth_challenge.get() == NULL); 8017 EXPECT_EQ(100, response->headers->GetContentLength()); 8018 } 8019 8020 // Test HTTPS connections going through a proxy that sends extra data. 8021 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) { 8022 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 8023 8024 HttpRequestInfo request; 8025 request.method = "GET"; 8026 request.url = GURL("https://www.google.com/"); 8027 request.load_flags = 0; 8028 8029 MockRead proxy_reads[] = { 8030 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"), 8031 MockRead(SYNCHRONOUS, OK) 8032 }; 8033 8034 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0); 8035 SSLSocketDataProvider ssl(ASYNC, OK); 8036 8037 session_deps_.socket_factory->AddSocketDataProvider(&data); 8038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8039 8040 TestCompletionCallback callback; 8041 8042 session_deps_.socket_factory->ResetNextMockIndexes(); 8043 8044 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8045 scoped_ptr<HttpTransaction> trans( 8046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8047 8048 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8049 EXPECT_EQ(ERR_IO_PENDING, rv); 8050 8051 rv = callback.WaitForResult(); 8052 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 8053 } 8054 8055 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) { 8056 HttpRequestInfo request; 8057 request.method = "GET"; 8058 request.url = GURL("http://www.google.com/"); 8059 request.load_flags = 0; 8060 8061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8062 scoped_ptr<HttpTransaction> trans( 8063 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8064 8065 MockRead data_reads[] = { 8066 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"), 8067 MockRead(SYNCHRONOUS, OK), 8068 }; 8069 8070 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 8071 session_deps_.socket_factory->AddSocketDataProvider(&data); 8072 8073 TestCompletionCallback callback; 8074 8075 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8076 EXPECT_EQ(ERR_IO_PENDING, rv); 8077 8078 EXPECT_EQ(OK, callback.WaitForResult()); 8079 8080 const HttpResponseInfo* response = trans->GetResponseInfo(); 8081 ASSERT_TRUE(response != NULL); 8082 8083 EXPECT_TRUE(response->headers.get() != NULL); 8084 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 8085 8086 std::string response_data; 8087 rv = ReadTransaction(trans.get(), &response_data); 8088 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 8089 } 8090 8091 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) { 8092 base::FilePath temp_file_path; 8093 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path)); 8094 const uint64 kFakeSize = 100000; // file is actually blank 8095 UploadFileElementReader::ScopedOverridingContentLengthForTests 8096 overriding_content_length(kFakeSize); 8097 8098 ScopedVector<UploadElementReader> element_readers; 8099 element_readers.push_back( 8100 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 8101 temp_file_path, 8102 0, 8103 kuint64max, 8104 base::Time())); 8105 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 8106 8107 HttpRequestInfo request; 8108 request.method = "POST"; 8109 request.url = GURL("http://www.google.com/upload"); 8110 request.upload_data_stream = &upload_data_stream; 8111 request.load_flags = 0; 8112 8113 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8114 scoped_ptr<HttpTransaction> trans( 8115 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8116 8117 MockRead data_reads[] = { 8118 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 8119 MockRead("hello world"), 8120 MockRead(SYNCHRONOUS, OK), 8121 }; 8122 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 8123 session_deps_.socket_factory->AddSocketDataProvider(&data); 8124 8125 TestCompletionCallback callback; 8126 8127 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8128 EXPECT_EQ(ERR_IO_PENDING, rv); 8129 8130 rv = callback.WaitForResult(); 8131 EXPECT_EQ(OK, rv); 8132 8133 const HttpResponseInfo* response = trans->GetResponseInfo(); 8134 ASSERT_TRUE(response != NULL); 8135 8136 EXPECT_TRUE(response->headers.get() != NULL); 8137 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 8138 8139 std::string response_data; 8140 rv = ReadTransaction(trans.get(), &response_data); 8141 EXPECT_EQ(OK, rv); 8142 EXPECT_EQ("hello world", response_data); 8143 8144 base::DeleteFile(temp_file_path, false); 8145 } 8146 8147 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) { 8148 base::FilePath temp_file; 8149 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file)); 8150 std::string temp_file_content("Unreadable file."); 8151 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(), 8152 temp_file_content.length())); 8153 ASSERT_TRUE(base::MakeFileUnreadable(temp_file)); 8154 8155 ScopedVector<UploadElementReader> element_readers; 8156 element_readers.push_back( 8157 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 8158 temp_file, 8159 0, 8160 kuint64max, 8161 base::Time())); 8162 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 8163 8164 HttpRequestInfo request; 8165 request.method = "POST"; 8166 request.url = GURL("http://www.google.com/upload"); 8167 request.upload_data_stream = &upload_data_stream; 8168 request.load_flags = 0; 8169 8170 // If we try to upload an unreadable file, the transaction should fail. 8171 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8172 scoped_ptr<HttpTransaction> trans( 8173 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8174 8175 StaticSocketDataProvider data(NULL, 0, NULL, 0); 8176 session_deps_.socket_factory->AddSocketDataProvider(&data); 8177 8178 TestCompletionCallback callback; 8179 8180 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8181 EXPECT_EQ(ERR_IO_PENDING, rv); 8182 8183 rv = callback.WaitForResult(); 8184 EXPECT_EQ(ERR_ACCESS_DENIED, rv); 8185 8186 const HttpResponseInfo* response = trans->GetResponseInfo(); 8187 EXPECT_FALSE(response); 8188 8189 base::DeleteFile(temp_file, false); 8190 } 8191 8192 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) { 8193 class FakeUploadElementReader : public UploadElementReader { 8194 public: 8195 FakeUploadElementReader() {} 8196 virtual ~FakeUploadElementReader() {} 8197 8198 const CompletionCallback& callback() const { return callback_; } 8199 8200 // UploadElementReader overrides: 8201 virtual int Init(const CompletionCallback& callback) OVERRIDE { 8202 callback_ = callback; 8203 return ERR_IO_PENDING; 8204 } 8205 virtual uint64 GetContentLength() const OVERRIDE { return 0; } 8206 virtual uint64 BytesRemaining() const OVERRIDE { return 0; } 8207 virtual int Read(IOBuffer* buf, 8208 int buf_length, 8209 const CompletionCallback& callback) OVERRIDE { 8210 return ERR_FAILED; 8211 } 8212 8213 private: 8214 CompletionCallback callback_; 8215 }; 8216 8217 FakeUploadElementReader* fake_reader = new FakeUploadElementReader; 8218 ScopedVector<UploadElementReader> element_readers; 8219 element_readers.push_back(fake_reader); 8220 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 8221 8222 HttpRequestInfo request; 8223 request.method = "POST"; 8224 request.url = GURL("http://www.google.com/upload"); 8225 request.upload_data_stream = &upload_data_stream; 8226 request.load_flags = 0; 8227 8228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8229 scoped_ptr<HttpTransaction> trans( 8230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8231 8232 StaticSocketDataProvider data; 8233 session_deps_.socket_factory->AddSocketDataProvider(&data); 8234 8235 TestCompletionCallback callback; 8236 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8237 EXPECT_EQ(ERR_IO_PENDING, rv); 8238 base::MessageLoop::current()->RunUntilIdle(); 8239 8240 // Transaction is pending on request body initialization. 8241 ASSERT_FALSE(fake_reader->callback().is_null()); 8242 8243 // Return Init()'s result after the transaction gets destroyed. 8244 trans.reset(); 8245 fake_reader->callback().Run(OK); // Should not crash. 8246 } 8247 8248 // Tests that changes to Auth realms are treated like auth rejections. 8249 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) { 8250 8251 HttpRequestInfo request; 8252 request.method = "GET"; 8253 request.url = GURL("http://www.google.com/"); 8254 request.load_flags = 0; 8255 8256 // First transaction will request a resource and receive a Basic challenge 8257 // with realm="first_realm". 8258 MockWrite data_writes1[] = { 8259 MockWrite("GET / HTTP/1.1\r\n" 8260 "Host: www.google.com\r\n" 8261 "Connection: keep-alive\r\n" 8262 "\r\n"), 8263 }; 8264 MockRead data_reads1[] = { 8265 MockRead("HTTP/1.1 401 Unauthorized\r\n" 8266 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 8267 "\r\n"), 8268 }; 8269 8270 // After calling trans->RestartWithAuth(), provide an Authentication header 8271 // for first_realm. The server will reject and provide a challenge with 8272 // second_realm. 8273 MockWrite data_writes2[] = { 8274 MockWrite("GET / HTTP/1.1\r\n" 8275 "Host: www.google.com\r\n" 8276 "Connection: keep-alive\r\n" 8277 "Authorization: Basic Zmlyc3Q6YmF6\r\n" 8278 "\r\n"), 8279 }; 8280 MockRead data_reads2[] = { 8281 MockRead("HTTP/1.1 401 Unauthorized\r\n" 8282 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n" 8283 "\r\n"), 8284 }; 8285 8286 // This again fails, and goes back to first_realm. Make sure that the 8287 // entry is removed from cache. 8288 MockWrite data_writes3[] = { 8289 MockWrite("GET / HTTP/1.1\r\n" 8290 "Host: www.google.com\r\n" 8291 "Connection: keep-alive\r\n" 8292 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n" 8293 "\r\n"), 8294 }; 8295 MockRead data_reads3[] = { 8296 MockRead("HTTP/1.1 401 Unauthorized\r\n" 8297 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 8298 "\r\n"), 8299 }; 8300 8301 // Try one last time (with the correct password) and get the resource. 8302 MockWrite data_writes4[] = { 8303 MockWrite("GET / HTTP/1.1\r\n" 8304 "Host: www.google.com\r\n" 8305 "Connection: keep-alive\r\n" 8306 "Authorization: Basic Zmlyc3Q6YmFy\r\n" 8307 "\r\n"), 8308 }; 8309 MockRead data_reads4[] = { 8310 MockRead("HTTP/1.1 200 OK\r\n" 8311 "Content-Type: text/html; charset=iso-8859-1\r\n" 8312 "Content-Length: 5\r\n" 8313 "\r\n" 8314 "hello"), 8315 }; 8316 8317 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 8318 data_writes1, arraysize(data_writes1)); 8319 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 8320 data_writes2, arraysize(data_writes2)); 8321 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 8322 data_writes3, arraysize(data_writes3)); 8323 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4), 8324 data_writes4, arraysize(data_writes4)); 8325 session_deps_.socket_factory->AddSocketDataProvider(&data1); 8326 session_deps_.socket_factory->AddSocketDataProvider(&data2); 8327 session_deps_.socket_factory->AddSocketDataProvider(&data3); 8328 session_deps_.socket_factory->AddSocketDataProvider(&data4); 8329 8330 TestCompletionCallback callback1; 8331 8332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8333 scoped_ptr<HttpTransaction> trans( 8334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8335 8336 // Issue the first request with Authorize headers. There should be a 8337 // password prompt for first_realm waiting to be filled in after the 8338 // transaction completes. 8339 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 8340 EXPECT_EQ(ERR_IO_PENDING, rv); 8341 rv = callback1.WaitForResult(); 8342 EXPECT_EQ(OK, rv); 8343 const HttpResponseInfo* response = trans->GetResponseInfo(); 8344 ASSERT_TRUE(response != NULL); 8345 const AuthChallengeInfo* challenge = response->auth_challenge.get(); 8346 ASSERT_FALSE(challenge == NULL); 8347 EXPECT_FALSE(challenge->is_proxy); 8348 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 8349 EXPECT_EQ("first_realm", challenge->realm); 8350 EXPECT_EQ("basic", challenge->scheme); 8351 8352 // Issue the second request with an incorrect password. There should be a 8353 // password prompt for second_realm waiting to be filled in after the 8354 // transaction completes. 8355 TestCompletionCallback callback2; 8356 rv = trans->RestartWithAuth( 8357 AuthCredentials(kFirst, kBaz), callback2.callback()); 8358 EXPECT_EQ(ERR_IO_PENDING, rv); 8359 rv = callback2.WaitForResult(); 8360 EXPECT_EQ(OK, rv); 8361 response = trans->GetResponseInfo(); 8362 ASSERT_TRUE(response != NULL); 8363 challenge = response->auth_challenge.get(); 8364 ASSERT_FALSE(challenge == NULL); 8365 EXPECT_FALSE(challenge->is_proxy); 8366 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 8367 EXPECT_EQ("second_realm", challenge->realm); 8368 EXPECT_EQ("basic", challenge->scheme); 8369 8370 // Issue the third request with another incorrect password. There should be 8371 // a password prompt for first_realm waiting to be filled in. If the password 8372 // prompt is not present, it indicates that the HttpAuthCacheEntry for 8373 // first_realm was not correctly removed. 8374 TestCompletionCallback callback3; 8375 rv = trans->RestartWithAuth( 8376 AuthCredentials(kSecond, kFou), callback3.callback()); 8377 EXPECT_EQ(ERR_IO_PENDING, rv); 8378 rv = callback3.WaitForResult(); 8379 EXPECT_EQ(OK, rv); 8380 response = trans->GetResponseInfo(); 8381 ASSERT_TRUE(response != NULL); 8382 challenge = response->auth_challenge.get(); 8383 ASSERT_FALSE(challenge == NULL); 8384 EXPECT_FALSE(challenge->is_proxy); 8385 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 8386 EXPECT_EQ("first_realm", challenge->realm); 8387 EXPECT_EQ("basic", challenge->scheme); 8388 8389 // Issue the fourth request with the correct password and username. 8390 TestCompletionCallback callback4; 8391 rv = trans->RestartWithAuth( 8392 AuthCredentials(kFirst, kBar), callback4.callback()); 8393 EXPECT_EQ(ERR_IO_PENDING, rv); 8394 rv = callback4.WaitForResult(); 8395 EXPECT_EQ(OK, rv); 8396 response = trans->GetResponseInfo(); 8397 ASSERT_TRUE(response != NULL); 8398 EXPECT_TRUE(response->auth_challenge.get() == NULL); 8399 } 8400 8401 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { 8402 session_deps_.next_protos = SpdyNextProtos(); 8403 session_deps_.use_alternate_protocols = true; 8404 8405 std::string alternate_protocol_http_header = 8406 GetAlternateProtocolHttpHeader(); 8407 8408 MockRead data_reads[] = { 8409 MockRead("HTTP/1.1 200 OK\r\n"), 8410 MockRead(alternate_protocol_http_header.c_str()), 8411 MockRead("hello world"), 8412 MockRead(SYNCHRONOUS, OK), 8413 }; 8414 8415 HttpRequestInfo request; 8416 request.method = "GET"; 8417 request.url = GURL("http://www.google.com/"); 8418 request.load_flags = 0; 8419 8420 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 8421 8422 session_deps_.socket_factory->AddSocketDataProvider(&data); 8423 8424 TestCompletionCallback callback; 8425 8426 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8427 scoped_ptr<HttpTransaction> trans( 8428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8429 8430 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8431 EXPECT_EQ(ERR_IO_PENDING, rv); 8432 8433 HostPortPair http_host_port_pair("www.google.com", 80); 8434 HttpServerProperties& http_server_properties = 8435 *session->http_server_properties(); 8436 EXPECT_FALSE( 8437 http_server_properties.HasAlternateProtocol(http_host_port_pair)); 8438 8439 EXPECT_EQ(OK, callback.WaitForResult()); 8440 8441 const HttpResponseInfo* response = trans->GetResponseInfo(); 8442 ASSERT_TRUE(response != NULL); 8443 ASSERT_TRUE(response->headers.get() != NULL); 8444 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8445 EXPECT_FALSE(response->was_fetched_via_spdy); 8446 EXPECT_FALSE(response->was_npn_negotiated); 8447 8448 std::string response_data; 8449 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8450 EXPECT_EQ("hello world", response_data); 8451 8452 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair)); 8453 const AlternateProtocolInfo alternate = 8454 http_server_properties.GetAlternateProtocol(http_host_port_pair); 8455 AlternateProtocolInfo expected_alternate( 8456 443, AlternateProtocolFromNextProto(GetParam()), 1); 8457 EXPECT_TRUE(expected_alternate.Equals(alternate)); 8458 } 8459 8460 TEST_P(HttpNetworkTransactionTest, 8461 MarkBrokenAlternateProtocolAndFallback) { 8462 session_deps_.use_alternate_protocols = true; 8463 8464 HttpRequestInfo request; 8465 request.method = "GET"; 8466 request.url = GURL("http://www.google.com/"); 8467 request.load_flags = 0; 8468 8469 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8470 StaticSocketDataProvider first_data; 8471 first_data.set_connect_data(mock_connect); 8472 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8473 8474 MockRead data_reads[] = { 8475 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8476 MockRead("hello world"), 8477 MockRead(ASYNC, OK), 8478 }; 8479 StaticSocketDataProvider second_data( 8480 data_reads, arraysize(data_reads), NULL, 0); 8481 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8482 8483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8484 8485 base::WeakPtr<HttpServerProperties> http_server_properties = 8486 session->http_server_properties(); 8487 // Port must be < 1024, or the header will be ignored (since initial port was 8488 // port 80 (another restricted port). 8489 http_server_properties->SetAlternateProtocol( 8490 HostPortPair::FromURL(request.url), 8491 666 /* port is ignored by MockConnect anyway */, 8492 AlternateProtocolFromNextProto(GetParam()), 1); 8493 8494 scoped_ptr<HttpTransaction> trans( 8495 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8496 TestCompletionCallback callback; 8497 8498 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8499 EXPECT_EQ(ERR_IO_PENDING, rv); 8500 EXPECT_EQ(OK, callback.WaitForResult()); 8501 8502 const HttpResponseInfo* response = trans->GetResponseInfo(); 8503 ASSERT_TRUE(response != NULL); 8504 ASSERT_TRUE(response->headers.get() != NULL); 8505 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8506 8507 std::string response_data; 8508 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8509 EXPECT_EQ("hello world", response_data); 8510 8511 ASSERT_TRUE(http_server_properties->HasAlternateProtocol( 8512 HostPortPair::FromURL(request.url))); 8513 const AlternateProtocolInfo alternate = 8514 http_server_properties->GetAlternateProtocol( 8515 HostPortPair::FromURL(request.url)); 8516 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); 8517 } 8518 8519 TEST_P(HttpNetworkTransactionTest, 8520 AlternateProtocolPortRestrictedBlocked) { 8521 // Ensure that we're not allowed to redirect traffic via an alternate 8522 // protocol to an unrestricted (port >= 1024) when the original traffic was 8523 // on a restricted port (port < 1024). Ensure that we can redirect in all 8524 // other cases. 8525 session_deps_.use_alternate_protocols = true; 8526 8527 HttpRequestInfo restricted_port_request; 8528 restricted_port_request.method = "GET"; 8529 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8530 restricted_port_request.load_flags = 0; 8531 8532 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8533 StaticSocketDataProvider first_data; 8534 first_data.set_connect_data(mock_connect); 8535 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8536 8537 MockRead data_reads[] = { 8538 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8539 MockRead("hello world"), 8540 MockRead(ASYNC, OK), 8541 }; 8542 StaticSocketDataProvider second_data( 8543 data_reads, arraysize(data_reads), NULL, 0); 8544 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8545 8546 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8547 8548 base::WeakPtr<HttpServerProperties> http_server_properties = 8549 session->http_server_properties(); 8550 const int kUnrestrictedAlternatePort = 1024; 8551 http_server_properties->SetAlternateProtocol( 8552 HostPortPair::FromURL(restricted_port_request.url), 8553 kUnrestrictedAlternatePort, 8554 AlternateProtocolFromNextProto(GetParam()), 1); 8555 8556 scoped_ptr<HttpTransaction> trans( 8557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8558 TestCompletionCallback callback; 8559 8560 int rv = trans->Start( 8561 &restricted_port_request, 8562 callback.callback(), BoundNetLog()); 8563 EXPECT_EQ(ERR_IO_PENDING, rv); 8564 // Invalid change to unrestricted port should fail. 8565 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult()); 8566 } 8567 8568 TEST_P(HttpNetworkTransactionTest, 8569 AlternateProtocolPortRestrictedPermitted) { 8570 // Ensure that we're allowed to redirect traffic via an alternate 8571 // protocol to an unrestricted (port >= 1024) when the original traffic was 8572 // on a restricted port (port < 1024) if we set 8573 // enable_user_alternate_protocol_ports. 8574 8575 session_deps_.use_alternate_protocols = true; 8576 session_deps_.enable_user_alternate_protocol_ports = true; 8577 8578 HttpRequestInfo restricted_port_request; 8579 restricted_port_request.method = "GET"; 8580 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8581 restricted_port_request.load_flags = 0; 8582 8583 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8584 StaticSocketDataProvider first_data; 8585 first_data.set_connect_data(mock_connect); 8586 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8587 8588 MockRead data_reads[] = { 8589 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8590 MockRead("hello world"), 8591 MockRead(ASYNC, OK), 8592 }; 8593 StaticSocketDataProvider second_data( 8594 data_reads, arraysize(data_reads), NULL, 0); 8595 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8596 8597 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8598 8599 base::WeakPtr<HttpServerProperties> http_server_properties = 8600 session->http_server_properties(); 8601 const int kUnrestrictedAlternatePort = 1024; 8602 http_server_properties->SetAlternateProtocol( 8603 HostPortPair::FromURL(restricted_port_request.url), 8604 kUnrestrictedAlternatePort, 8605 AlternateProtocolFromNextProto(GetParam()), 1); 8606 8607 scoped_ptr<HttpTransaction> trans( 8608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8609 TestCompletionCallback callback; 8610 8611 EXPECT_EQ(ERR_IO_PENDING, trans->Start( 8612 &restricted_port_request, 8613 callback.callback(), BoundNetLog())); 8614 // Change to unrestricted port should succeed. 8615 EXPECT_EQ(OK, callback.WaitForResult()); 8616 } 8617 8618 TEST_P(HttpNetworkTransactionTest, 8619 AlternateProtocolPortRestrictedAllowed) { 8620 // Ensure that we're not allowed to redirect traffic via an alternate 8621 // protocol to an unrestricted (port >= 1024) when the original traffic was 8622 // on a restricted port (port < 1024). Ensure that we can redirect in all 8623 // other cases. 8624 session_deps_.use_alternate_protocols = true; 8625 8626 HttpRequestInfo restricted_port_request; 8627 restricted_port_request.method = "GET"; 8628 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8629 restricted_port_request.load_flags = 0; 8630 8631 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8632 StaticSocketDataProvider first_data; 8633 first_data.set_connect_data(mock_connect); 8634 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8635 8636 MockRead data_reads[] = { 8637 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8638 MockRead("hello world"), 8639 MockRead(ASYNC, OK), 8640 }; 8641 StaticSocketDataProvider second_data( 8642 data_reads, arraysize(data_reads), NULL, 0); 8643 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8644 8645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8646 8647 base::WeakPtr<HttpServerProperties> http_server_properties = 8648 session->http_server_properties(); 8649 const int kRestrictedAlternatePort = 80; 8650 http_server_properties->SetAlternateProtocol( 8651 HostPortPair::FromURL(restricted_port_request.url), 8652 kRestrictedAlternatePort, 8653 AlternateProtocolFromNextProto(GetParam()), 1); 8654 8655 scoped_ptr<HttpTransaction> trans( 8656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8657 TestCompletionCallback callback; 8658 8659 int rv = trans->Start( 8660 &restricted_port_request, 8661 callback.callback(), BoundNetLog()); 8662 EXPECT_EQ(ERR_IO_PENDING, rv); 8663 // Valid change to restricted port should pass. 8664 EXPECT_EQ(OK, callback.WaitForResult()); 8665 } 8666 8667 TEST_P(HttpNetworkTransactionTest, 8668 AlternateProtocolPortUnrestrictedAllowed1) { 8669 // Ensure that we're not allowed to redirect traffic via an alternate 8670 // protocol to an unrestricted (port >= 1024) when the original traffic was 8671 // on a restricted port (port < 1024). Ensure that we can redirect in all 8672 // other cases. 8673 session_deps_.use_alternate_protocols = true; 8674 8675 HttpRequestInfo unrestricted_port_request; 8676 unrestricted_port_request.method = "GET"; 8677 unrestricted_port_request.url = GURL("http://www.google.com:1024/"); 8678 unrestricted_port_request.load_flags = 0; 8679 8680 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8681 StaticSocketDataProvider first_data; 8682 first_data.set_connect_data(mock_connect); 8683 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8684 8685 MockRead data_reads[] = { 8686 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8687 MockRead("hello world"), 8688 MockRead(ASYNC, OK), 8689 }; 8690 StaticSocketDataProvider second_data( 8691 data_reads, arraysize(data_reads), NULL, 0); 8692 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8693 8694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8695 8696 base::WeakPtr<HttpServerProperties> http_server_properties = 8697 session->http_server_properties(); 8698 const int kRestrictedAlternatePort = 80; 8699 http_server_properties->SetAlternateProtocol( 8700 HostPortPair::FromURL(unrestricted_port_request.url), 8701 kRestrictedAlternatePort, 8702 AlternateProtocolFromNextProto(GetParam()), 1); 8703 8704 scoped_ptr<HttpTransaction> trans( 8705 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8706 TestCompletionCallback callback; 8707 8708 int rv = trans->Start( 8709 &unrestricted_port_request, callback.callback(), BoundNetLog()); 8710 EXPECT_EQ(ERR_IO_PENDING, rv); 8711 // Valid change to restricted port should pass. 8712 EXPECT_EQ(OK, callback.WaitForResult()); 8713 } 8714 8715 TEST_P(HttpNetworkTransactionTest, 8716 AlternateProtocolPortUnrestrictedAllowed2) { 8717 // Ensure that we're not allowed to redirect traffic via an alternate 8718 // protocol to an unrestricted (port >= 1024) when the original traffic was 8719 // on a restricted port (port < 1024). Ensure that we can redirect in all 8720 // other cases. 8721 session_deps_.use_alternate_protocols = true; 8722 8723 HttpRequestInfo unrestricted_port_request; 8724 unrestricted_port_request.method = "GET"; 8725 unrestricted_port_request.url = GURL("http://www.google.com:1024/"); 8726 unrestricted_port_request.load_flags = 0; 8727 8728 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8729 StaticSocketDataProvider first_data; 8730 first_data.set_connect_data(mock_connect); 8731 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8732 8733 MockRead data_reads[] = { 8734 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8735 MockRead("hello world"), 8736 MockRead(ASYNC, OK), 8737 }; 8738 StaticSocketDataProvider second_data( 8739 data_reads, arraysize(data_reads), NULL, 0); 8740 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8741 8742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8743 8744 base::WeakPtr<HttpServerProperties> http_server_properties = 8745 session->http_server_properties(); 8746 const int kUnrestrictedAlternatePort = 1024; 8747 http_server_properties->SetAlternateProtocol( 8748 HostPortPair::FromURL(unrestricted_port_request.url), 8749 kUnrestrictedAlternatePort, 8750 AlternateProtocolFromNextProto(GetParam()), 1); 8751 8752 scoped_ptr<HttpTransaction> trans( 8753 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8754 TestCompletionCallback callback; 8755 8756 int rv = trans->Start( 8757 &unrestricted_port_request, callback.callback(), BoundNetLog()); 8758 EXPECT_EQ(ERR_IO_PENDING, rv); 8759 // Valid change to an unrestricted port should pass. 8760 EXPECT_EQ(OK, callback.WaitForResult()); 8761 } 8762 8763 TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) { 8764 // Ensure that we're not allowed to redirect traffic via an alternate 8765 // protocol to an unsafe port, and that we resume the second 8766 // HttpStreamFactoryImpl::Job once the alternate protocol request fails. 8767 session_deps_.use_alternate_protocols = true; 8768 8769 HttpRequestInfo request; 8770 request.method = "GET"; 8771 request.url = GURL("http://www.google.com/"); 8772 request.load_flags = 0; 8773 8774 // The alternate protocol request will error out before we attempt to connect, 8775 // so only the standard HTTP request will try to connect. 8776 MockRead data_reads[] = { 8777 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8778 MockRead("hello world"), 8779 MockRead(ASYNC, OK), 8780 }; 8781 StaticSocketDataProvider data( 8782 data_reads, arraysize(data_reads), NULL, 0); 8783 session_deps_.socket_factory->AddSocketDataProvider(&data); 8784 8785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8786 8787 base::WeakPtr<HttpServerProperties> http_server_properties = 8788 session->http_server_properties(); 8789 const int kUnsafePort = 7; 8790 http_server_properties->SetAlternateProtocol( 8791 HostPortPair::FromURL(request.url), 8792 kUnsafePort, 8793 AlternateProtocolFromNextProto(GetParam()), 1); 8794 8795 scoped_ptr<HttpTransaction> trans( 8796 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8797 TestCompletionCallback callback; 8798 8799 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8800 EXPECT_EQ(ERR_IO_PENDING, rv); 8801 // The HTTP request should succeed. 8802 EXPECT_EQ(OK, callback.WaitForResult()); 8803 8804 // Disable alternate protocol before the asserts. 8805 // HttpStreamFactory::set_use_alternate_protocols(false); 8806 8807 const HttpResponseInfo* response = trans->GetResponseInfo(); 8808 ASSERT_TRUE(response != NULL); 8809 ASSERT_TRUE(response->headers.get() != NULL); 8810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8811 8812 std::string response_data; 8813 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8814 EXPECT_EQ("hello world", response_data); 8815 } 8816 8817 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) { 8818 session_deps_.use_alternate_protocols = true; 8819 session_deps_.next_protos = SpdyNextProtos(); 8820 8821 HttpRequestInfo request; 8822 request.method = "GET"; 8823 request.url = GURL("http://www.google.com/"); 8824 request.load_flags = 0; 8825 8826 std::string alternate_protocol_http_header = 8827 GetAlternateProtocolHttpHeader(); 8828 8829 MockRead data_reads[] = { 8830 MockRead("HTTP/1.1 200 OK\r\n"), 8831 MockRead(alternate_protocol_http_header.c_str()), 8832 MockRead("hello world"), 8833 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8834 MockRead(ASYNC, OK) 8835 }; 8836 8837 StaticSocketDataProvider first_transaction( 8838 data_reads, arraysize(data_reads), NULL, 0); 8839 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8840 8841 SSLSocketDataProvider ssl(ASYNC, OK); 8842 ssl.SetNextProto(GetParam()); 8843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8844 8845 scoped_ptr<SpdyFrame> req( 8846 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8847 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 8848 8849 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8850 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8851 MockRead spdy_reads[] = { 8852 CreateMockRead(*resp), 8853 CreateMockRead(*data), 8854 MockRead(ASYNC, 0, 0), 8855 }; 8856 8857 DelayedSocketData spdy_data( 8858 1, // wait for one write to finish before reading. 8859 spdy_reads, arraysize(spdy_reads), 8860 spdy_writes, arraysize(spdy_writes)); 8861 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8862 8863 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8864 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 8865 NULL, 0, NULL, 0); 8866 hanging_non_alternate_protocol_socket.set_connect_data( 8867 never_finishing_connect); 8868 session_deps_.socket_factory->AddSocketDataProvider( 8869 &hanging_non_alternate_protocol_socket); 8870 8871 TestCompletionCallback callback; 8872 8873 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8874 scoped_ptr<HttpTransaction> trans( 8875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8876 8877 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8878 EXPECT_EQ(ERR_IO_PENDING, rv); 8879 EXPECT_EQ(OK, callback.WaitForResult()); 8880 8881 const HttpResponseInfo* response = trans->GetResponseInfo(); 8882 ASSERT_TRUE(response != NULL); 8883 ASSERT_TRUE(response->headers.get() != NULL); 8884 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8885 8886 std::string response_data; 8887 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8888 EXPECT_EQ("hello world", response_data); 8889 8890 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8891 8892 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8893 EXPECT_EQ(ERR_IO_PENDING, rv); 8894 EXPECT_EQ(OK, callback.WaitForResult()); 8895 8896 response = trans->GetResponseInfo(); 8897 ASSERT_TRUE(response != NULL); 8898 ASSERT_TRUE(response->headers.get() != NULL); 8899 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8900 EXPECT_TRUE(response->was_fetched_via_spdy); 8901 EXPECT_TRUE(response->was_npn_negotiated); 8902 8903 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8904 EXPECT_EQ("hello!", response_data); 8905 } 8906 8907 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) { 8908 session_deps_.use_alternate_protocols = true; 8909 session_deps_.next_protos = SpdyNextProtos(); 8910 8911 HttpRequestInfo request; 8912 request.method = "GET"; 8913 request.url = GURL("http://www.google.com/"); 8914 request.load_flags = 0; 8915 8916 std::string alternate_protocol_http_header = 8917 GetAlternateProtocolHttpHeader(); 8918 8919 MockRead data_reads[] = { 8920 MockRead("HTTP/1.1 200 OK\r\n"), 8921 MockRead(alternate_protocol_http_header.c_str()), 8922 MockRead("hello world"), 8923 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8924 MockRead(ASYNC, OK), 8925 }; 8926 8927 StaticSocketDataProvider first_transaction( 8928 data_reads, arraysize(data_reads), NULL, 0); 8929 // Socket 1 is the HTTP transaction with the Alternate-Protocol header. 8930 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8931 8932 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8933 StaticSocketDataProvider hanging_socket( 8934 NULL, 0, NULL, 0); 8935 hanging_socket.set_connect_data(never_finishing_connect); 8936 // Socket 2 and 3 are the hanging Alternate-Protocol and 8937 // non-Alternate-Protocol jobs from the 2nd transaction. 8938 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8939 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8940 8941 SSLSocketDataProvider ssl(ASYNC, OK); 8942 ssl.SetNextProto(GetParam()); 8943 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8944 8945 scoped_ptr<SpdyFrame> req1( 8946 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8947 scoped_ptr<SpdyFrame> req2( 8948 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 8949 MockWrite spdy_writes[] = { 8950 CreateMockWrite(*req1), 8951 CreateMockWrite(*req2), 8952 }; 8953 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8954 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8955 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 8956 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 8957 MockRead spdy_reads[] = { 8958 CreateMockRead(*resp1), 8959 CreateMockRead(*data1), 8960 CreateMockRead(*resp2), 8961 CreateMockRead(*data2), 8962 MockRead(ASYNC, 0, 0), 8963 }; 8964 8965 DelayedSocketData spdy_data( 8966 2, // wait for writes to finish before reading. 8967 spdy_reads, arraysize(spdy_reads), 8968 spdy_writes, arraysize(spdy_writes)); 8969 // Socket 4 is the successful Alternate-Protocol for transaction 3. 8970 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8971 8972 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3. 8973 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8974 8975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8976 TestCompletionCallback callback1; 8977 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 8978 8979 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog()); 8980 EXPECT_EQ(ERR_IO_PENDING, rv); 8981 EXPECT_EQ(OK, callback1.WaitForResult()); 8982 8983 const HttpResponseInfo* response = trans1.GetResponseInfo(); 8984 ASSERT_TRUE(response != NULL); 8985 ASSERT_TRUE(response->headers.get() != NULL); 8986 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8987 8988 std::string response_data; 8989 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 8990 EXPECT_EQ("hello world", response_data); 8991 8992 TestCompletionCallback callback2; 8993 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 8994 rv = trans2.Start(&request, callback2.callback(), BoundNetLog()); 8995 EXPECT_EQ(ERR_IO_PENDING, rv); 8996 8997 TestCompletionCallback callback3; 8998 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get()); 8999 rv = trans3.Start(&request, callback3.callback(), BoundNetLog()); 9000 EXPECT_EQ(ERR_IO_PENDING, rv); 9001 9002 EXPECT_EQ(OK, callback2.WaitForResult()); 9003 EXPECT_EQ(OK, callback3.WaitForResult()); 9004 9005 response = trans2.GetResponseInfo(); 9006 ASSERT_TRUE(response != NULL); 9007 ASSERT_TRUE(response->headers.get() != NULL); 9008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9009 EXPECT_TRUE(response->was_fetched_via_spdy); 9010 EXPECT_TRUE(response->was_npn_negotiated); 9011 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 9012 EXPECT_EQ("hello!", response_data); 9013 9014 response = trans3.GetResponseInfo(); 9015 ASSERT_TRUE(response != NULL); 9016 ASSERT_TRUE(response->headers.get() != NULL); 9017 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9018 EXPECT_TRUE(response->was_fetched_via_spdy); 9019 EXPECT_TRUE(response->was_npn_negotiated); 9020 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data)); 9021 EXPECT_EQ("hello!", response_data); 9022 } 9023 9024 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) { 9025 session_deps_.use_alternate_protocols = true; 9026 session_deps_.next_protos = SpdyNextProtos(); 9027 9028 HttpRequestInfo request; 9029 request.method = "GET"; 9030 request.url = GURL("http://www.google.com/"); 9031 request.load_flags = 0; 9032 9033 std::string alternate_protocol_http_header = 9034 GetAlternateProtocolHttpHeader(); 9035 9036 MockRead data_reads[] = { 9037 MockRead("HTTP/1.1 200 OK\r\n"), 9038 MockRead(alternate_protocol_http_header.c_str()), 9039 MockRead("hello world"), 9040 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 9041 MockRead(ASYNC, OK), 9042 }; 9043 9044 StaticSocketDataProvider first_transaction( 9045 data_reads, arraysize(data_reads), NULL, 0); 9046 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9047 9048 SSLSocketDataProvider ssl(ASYNC, OK); 9049 ssl.SetNextProto(GetParam()); 9050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9051 9052 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 9053 StaticSocketDataProvider hanging_alternate_protocol_socket( 9054 NULL, 0, NULL, 0); 9055 hanging_alternate_protocol_socket.set_connect_data( 9056 never_finishing_connect); 9057 session_deps_.socket_factory->AddSocketDataProvider( 9058 &hanging_alternate_protocol_socket); 9059 9060 // 2nd request is just a copy of the first one, over HTTP again. 9061 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9062 9063 TestCompletionCallback callback; 9064 9065 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9066 scoped_ptr<HttpTransaction> trans( 9067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9068 9069 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9070 EXPECT_EQ(ERR_IO_PENDING, rv); 9071 EXPECT_EQ(OK, callback.WaitForResult()); 9072 9073 const HttpResponseInfo* response = trans->GetResponseInfo(); 9074 ASSERT_TRUE(response != NULL); 9075 ASSERT_TRUE(response->headers.get() != NULL); 9076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9077 9078 std::string response_data; 9079 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9080 EXPECT_EQ("hello world", response_data); 9081 9082 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9083 9084 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9085 EXPECT_EQ(ERR_IO_PENDING, rv); 9086 EXPECT_EQ(OK, callback.WaitForResult()); 9087 9088 response = trans->GetResponseInfo(); 9089 ASSERT_TRUE(response != NULL); 9090 ASSERT_TRUE(response->headers.get() != NULL); 9091 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9092 EXPECT_FALSE(response->was_fetched_via_spdy); 9093 EXPECT_FALSE(response->was_npn_negotiated); 9094 9095 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9096 EXPECT_EQ("hello world", response_data); 9097 } 9098 9099 class CapturingProxyResolver : public ProxyResolver { 9100 public: 9101 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {} 9102 virtual ~CapturingProxyResolver() {} 9103 9104 virtual int GetProxyForURL(const GURL& url, 9105 ProxyInfo* results, 9106 const CompletionCallback& callback, 9107 RequestHandle* request, 9108 const BoundNetLog& net_log) OVERRIDE { 9109 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, 9110 HostPortPair("myproxy", 80)); 9111 results->UseProxyServer(proxy_server); 9112 resolved_.push_back(url); 9113 return OK; 9114 } 9115 9116 virtual void CancelRequest(RequestHandle request) OVERRIDE { 9117 NOTREACHED(); 9118 } 9119 9120 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE { 9121 NOTREACHED(); 9122 return LOAD_STATE_IDLE; 9123 } 9124 9125 virtual void CancelSetPacScript() OVERRIDE { 9126 NOTREACHED(); 9127 } 9128 9129 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&, 9130 const CompletionCallback& /*callback*/) OVERRIDE { 9131 return OK; 9132 } 9133 9134 const std::vector<GURL>& resolved() const { return resolved_; } 9135 9136 private: 9137 std::vector<GURL> resolved_; 9138 9139 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver); 9140 }; 9141 9142 TEST_P(HttpNetworkTransactionTest, 9143 UseAlternateProtocolForTunneledNpnSpdy) { 9144 session_deps_.use_alternate_protocols = true; 9145 session_deps_.next_protos = SpdyNextProtos(); 9146 9147 ProxyConfig proxy_config; 9148 proxy_config.set_auto_detect(true); 9149 proxy_config.set_pac_url(GURL("http://fooproxyurl")); 9150 9151 CapturingProxyResolver* capturing_proxy_resolver = 9152 new CapturingProxyResolver(); 9153 session_deps_.proxy_service.reset(new ProxyService( 9154 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver, 9155 NULL)); 9156 CapturingNetLog net_log; 9157 session_deps_.net_log = &net_log; 9158 9159 HttpRequestInfo request; 9160 request.method = "GET"; 9161 request.url = GURL("http://www.google.com/"); 9162 request.load_flags = 0; 9163 9164 std::string alternate_protocol_http_header = 9165 GetAlternateProtocolHttpHeader(); 9166 9167 MockRead data_reads[] = { 9168 MockRead("HTTP/1.1 200 OK\r\n"), 9169 MockRead(alternate_protocol_http_header.c_str()), 9170 MockRead("hello world"), 9171 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 9172 MockRead(ASYNC, OK), 9173 }; 9174 9175 StaticSocketDataProvider first_transaction( 9176 data_reads, arraysize(data_reads), NULL, 0); 9177 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9178 9179 SSLSocketDataProvider ssl(ASYNC, OK); 9180 ssl.SetNextProto(GetParam()); 9181 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9182 9183 scoped_ptr<SpdyFrame> req( 9184 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 9185 MockWrite spdy_writes[] = { 9186 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 9187 "Host: www.google.com\r\n" 9188 "Proxy-Connection: keep-alive\r\n\r\n"), // 0 9189 CreateMockWrite(*req), // 3 9190 }; 9191 9192 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 9193 9194 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 9195 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 9196 MockRead spdy_reads[] = { 9197 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1 9198 CreateMockRead(*resp.get(), 4), // 2, 4 9199 CreateMockRead(*data.get(), 4), // 5 9200 MockRead(ASYNC, 0, 0, 4), // 6 9201 }; 9202 9203 OrderedSocketData spdy_data( 9204 spdy_reads, arraysize(spdy_reads), 9205 spdy_writes, arraysize(spdy_writes)); 9206 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 9207 9208 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 9209 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 9210 NULL, 0, NULL, 0); 9211 hanging_non_alternate_protocol_socket.set_connect_data( 9212 never_finishing_connect); 9213 session_deps_.socket_factory->AddSocketDataProvider( 9214 &hanging_non_alternate_protocol_socket); 9215 9216 TestCompletionCallback callback; 9217 9218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9219 scoped_ptr<HttpTransaction> trans( 9220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9221 9222 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9223 EXPECT_EQ(ERR_IO_PENDING, rv); 9224 EXPECT_EQ(OK, callback.WaitForResult()); 9225 9226 const HttpResponseInfo* response = trans->GetResponseInfo(); 9227 ASSERT_TRUE(response != NULL); 9228 ASSERT_TRUE(response->headers.get() != NULL); 9229 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9230 EXPECT_FALSE(response->was_fetched_via_spdy); 9231 EXPECT_FALSE(response->was_npn_negotiated); 9232 9233 std::string response_data; 9234 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9235 EXPECT_EQ("hello world", response_data); 9236 9237 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9238 9239 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9240 EXPECT_EQ(ERR_IO_PENDING, rv); 9241 EXPECT_EQ(OK, callback.WaitForResult()); 9242 9243 response = trans->GetResponseInfo(); 9244 ASSERT_TRUE(response != NULL); 9245 ASSERT_TRUE(response->headers.get() != NULL); 9246 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9247 EXPECT_TRUE(response->was_fetched_via_spdy); 9248 EXPECT_TRUE(response->was_npn_negotiated); 9249 9250 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9251 EXPECT_EQ("hello!", response_data); 9252 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size()); 9253 EXPECT_EQ("http://www.google.com/", 9254 capturing_proxy_resolver->resolved()[0].spec()); 9255 EXPECT_EQ("https://www.google.com/", 9256 capturing_proxy_resolver->resolved()[1].spec()); 9257 9258 LoadTimingInfo load_timing_info; 9259 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 9260 TestLoadTimingNotReusedWithPac(load_timing_info, 9261 CONNECT_TIMING_HAS_SSL_TIMES); 9262 } 9263 9264 TEST_P(HttpNetworkTransactionTest, 9265 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) { 9266 session_deps_.use_alternate_protocols = true; 9267 session_deps_.next_protos = SpdyNextProtos(); 9268 9269 HttpRequestInfo request; 9270 request.method = "GET"; 9271 request.url = GURL("http://www.google.com/"); 9272 request.load_flags = 0; 9273 9274 std::string alternate_protocol_http_header = 9275 GetAlternateProtocolHttpHeader(); 9276 9277 MockRead data_reads[] = { 9278 MockRead("HTTP/1.1 200 OK\r\n"), 9279 MockRead(alternate_protocol_http_header.c_str()), 9280 MockRead("hello world"), 9281 MockRead(ASYNC, OK), 9282 }; 9283 9284 StaticSocketDataProvider first_transaction( 9285 data_reads, arraysize(data_reads), NULL, 0); 9286 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9287 9288 SSLSocketDataProvider ssl(ASYNC, OK); 9289 ssl.SetNextProto(GetParam()); 9290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9291 9292 scoped_ptr<SpdyFrame> req( 9293 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 9294 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 9295 9296 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 9297 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 9298 MockRead spdy_reads[] = { 9299 CreateMockRead(*resp), 9300 CreateMockRead(*data), 9301 MockRead(ASYNC, 0, 0), 9302 }; 9303 9304 DelayedSocketData spdy_data( 9305 1, // wait for one write to finish before reading. 9306 spdy_reads, arraysize(spdy_reads), 9307 spdy_writes, arraysize(spdy_writes)); 9308 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 9309 9310 TestCompletionCallback callback; 9311 9312 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9313 9314 scoped_ptr<HttpTransaction> trans( 9315 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9316 9317 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9318 EXPECT_EQ(ERR_IO_PENDING, rv); 9319 EXPECT_EQ(OK, callback.WaitForResult()); 9320 9321 const HttpResponseInfo* response = trans->GetResponseInfo(); 9322 ASSERT_TRUE(response != NULL); 9323 ASSERT_TRUE(response->headers.get() != NULL); 9324 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9325 9326 std::string response_data; 9327 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9328 EXPECT_EQ("hello world", response_data); 9329 9330 // Set up an initial SpdySession in the pool to reuse. 9331 HostPortPair host_port_pair("www.google.com", 443); 9332 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 9333 PRIVACY_MODE_DISABLED); 9334 base::WeakPtr<SpdySession> spdy_session = 9335 CreateSecureSpdySession(session, key, BoundNetLog()); 9336 9337 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9338 9339 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9340 EXPECT_EQ(ERR_IO_PENDING, rv); 9341 EXPECT_EQ(OK, callback.WaitForResult()); 9342 9343 response = trans->GetResponseInfo(); 9344 ASSERT_TRUE(response != NULL); 9345 ASSERT_TRUE(response->headers.get() != NULL); 9346 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9347 EXPECT_TRUE(response->was_fetched_via_spdy); 9348 EXPECT_TRUE(response->was_npn_negotiated); 9349 9350 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9351 EXPECT_EQ("hello!", response_data); 9352 } 9353 9354 // GenerateAuthToken is a mighty big test. 9355 // It tests all permutation of GenerateAuthToken behavior: 9356 // - Synchronous and Asynchronous completion. 9357 // - OK or error on completion. 9358 // - Direct connection, non-authenticating proxy, and authenticating proxy. 9359 // - HTTP or HTTPS backend (to include proxy tunneling). 9360 // - Non-authenticating and authenticating backend. 9361 // 9362 // In all, there are 44 reasonable permuations (for example, if there are 9363 // problems generating an auth token for an authenticating proxy, we don't 9364 // need to test all permutations of the backend server). 9365 // 9366 // The test proceeds by going over each of the configuration cases, and 9367 // potentially running up to three rounds in each of the tests. The TestConfig 9368 // specifies both the configuration for the test as well as the expectations 9369 // for the results. 9370 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) { 9371 static const char kServer[] = "http://www.example.com"; 9372 static const char kSecureServer[] = "https://www.example.com"; 9373 static const char kProxy[] = "myproxy:70"; 9374 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS; 9375 9376 enum AuthTiming { 9377 AUTH_NONE, 9378 AUTH_SYNC, 9379 AUTH_ASYNC, 9380 }; 9381 9382 const MockWrite kGet( 9383 "GET / HTTP/1.1\r\n" 9384 "Host: www.example.com\r\n" 9385 "Connection: keep-alive\r\n\r\n"); 9386 const MockWrite kGetProxy( 9387 "GET http://www.example.com/ HTTP/1.1\r\n" 9388 "Host: www.example.com\r\n" 9389 "Proxy-Connection: keep-alive\r\n\r\n"); 9390 const MockWrite kGetAuth( 9391 "GET / HTTP/1.1\r\n" 9392 "Host: www.example.com\r\n" 9393 "Connection: keep-alive\r\n" 9394 "Authorization: auth_token\r\n\r\n"); 9395 const MockWrite kGetProxyAuth( 9396 "GET http://www.example.com/ HTTP/1.1\r\n" 9397 "Host: www.example.com\r\n" 9398 "Proxy-Connection: keep-alive\r\n" 9399 "Proxy-Authorization: auth_token\r\n\r\n"); 9400 const MockWrite kGetAuthThroughProxy( 9401 "GET http://www.example.com/ HTTP/1.1\r\n" 9402 "Host: www.example.com\r\n" 9403 "Proxy-Connection: keep-alive\r\n" 9404 "Authorization: auth_token\r\n\r\n"); 9405 const MockWrite kGetAuthWithProxyAuth( 9406 "GET http://www.example.com/ HTTP/1.1\r\n" 9407 "Host: www.example.com\r\n" 9408 "Proxy-Connection: keep-alive\r\n" 9409 "Proxy-Authorization: auth_token\r\n" 9410 "Authorization: auth_token\r\n\r\n"); 9411 const MockWrite kConnect( 9412 "CONNECT www.example.com:443 HTTP/1.1\r\n" 9413 "Host: www.example.com\r\n" 9414 "Proxy-Connection: keep-alive\r\n\r\n"); 9415 const MockWrite kConnectProxyAuth( 9416 "CONNECT www.example.com:443 HTTP/1.1\r\n" 9417 "Host: www.example.com\r\n" 9418 "Proxy-Connection: keep-alive\r\n" 9419 "Proxy-Authorization: auth_token\r\n\r\n"); 9420 9421 const MockRead kSuccess( 9422 "HTTP/1.1 200 OK\r\n" 9423 "Content-Type: text/html; charset=iso-8859-1\r\n" 9424 "Content-Length: 3\r\n\r\n" 9425 "Yes"); 9426 const MockRead kFailure( 9427 "Should not be called."); 9428 const MockRead kServerChallenge( 9429 "HTTP/1.1 401 Unauthorized\r\n" 9430 "WWW-Authenticate: Mock realm=server\r\n" 9431 "Content-Type: text/html; charset=iso-8859-1\r\n" 9432 "Content-Length: 14\r\n\r\n" 9433 "Unauthorized\r\n"); 9434 const MockRead kProxyChallenge( 9435 "HTTP/1.1 407 Unauthorized\r\n" 9436 "Proxy-Authenticate: Mock realm=proxy\r\n" 9437 "Proxy-Connection: close\r\n" 9438 "Content-Type: text/html; charset=iso-8859-1\r\n" 9439 "Content-Length: 14\r\n\r\n" 9440 "Unauthorized\r\n"); 9441 const MockRead kProxyConnected( 9442 "HTTP/1.1 200 Connection Established\r\n\r\n"); 9443 9444 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with 9445 // no constructors, but the C++ compiler on Windows warns about 9446 // unspecified data in compound literals. So, moved to using constructors, 9447 // and TestRound's created with the default constructor should not be used. 9448 struct TestRound { 9449 TestRound() 9450 : expected_rv(ERR_UNEXPECTED), 9451 extra_write(NULL), 9452 extra_read(NULL) { 9453 } 9454 TestRound(const MockWrite& write_arg, const MockRead& read_arg, 9455 int expected_rv_arg) 9456 : write(write_arg), 9457 read(read_arg), 9458 expected_rv(expected_rv_arg), 9459 extra_write(NULL), 9460 extra_read(NULL) { 9461 } 9462 TestRound(const MockWrite& write_arg, const MockRead& read_arg, 9463 int expected_rv_arg, const MockWrite* extra_write_arg, 9464 const MockRead* extra_read_arg) 9465 : write(write_arg), 9466 read(read_arg), 9467 expected_rv(expected_rv_arg), 9468 extra_write(extra_write_arg), 9469 extra_read(extra_read_arg) { 9470 } 9471 MockWrite write; 9472 MockRead read; 9473 int expected_rv; 9474 const MockWrite* extra_write; 9475 const MockRead* extra_read; 9476 }; 9477 9478 static const int kNoSSL = 500; 9479 9480 struct TestConfig { 9481 const char* proxy_url; 9482 AuthTiming proxy_auth_timing; 9483 int proxy_auth_rv; 9484 const char* server_url; 9485 AuthTiming server_auth_timing; 9486 int server_auth_rv; 9487 int num_auth_rounds; 9488 int first_ssl_round; 9489 TestRound rounds[3]; 9490 } test_configs[] = { 9491 // Non-authenticating HTTP server with a direct connection. 9492 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 9493 { TestRound(kGet, kSuccess, OK)}}, 9494 // Authenticating HTTP server with a direct connection. 9495 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 9496 { TestRound(kGet, kServerChallenge, OK), 9497 TestRound(kGetAuth, kSuccess, OK)}}, 9498 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 9499 { TestRound(kGet, kServerChallenge, OK), 9500 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9501 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 9502 { TestRound(kGet, kServerChallenge, OK), 9503 TestRound(kGetAuth, kSuccess, OK)}}, 9504 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 9505 { TestRound(kGet, kServerChallenge, OK), 9506 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9507 // Non-authenticating HTTP server through a non-authenticating proxy. 9508 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 9509 { TestRound(kGetProxy, kSuccess, OK)}}, 9510 // Authenticating HTTP server through a non-authenticating proxy. 9511 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 9512 { TestRound(kGetProxy, kServerChallenge, OK), 9513 TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 9514 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 9515 { TestRound(kGetProxy, kServerChallenge, OK), 9516 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 9517 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 9518 { TestRound(kGetProxy, kServerChallenge, OK), 9519 TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 9520 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 9521 { TestRound(kGetProxy, kServerChallenge, OK), 9522 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 9523 // Non-authenticating HTTP server through an authenticating proxy. 9524 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 9525 { TestRound(kGetProxy, kProxyChallenge, OK), 9526 TestRound(kGetProxyAuth, kSuccess, OK)}}, 9527 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 9528 { TestRound(kGetProxy, kProxyChallenge, OK), 9529 TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 9530 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 9531 { TestRound(kGetProxy, kProxyChallenge, OK), 9532 TestRound(kGetProxyAuth, kSuccess, OK)}}, 9533 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 9534 { TestRound(kGetProxy, kProxyChallenge, OK), 9535 TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 9536 // Authenticating HTTP server through an authenticating proxy. 9537 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 9538 { TestRound(kGetProxy, kProxyChallenge, OK), 9539 TestRound(kGetProxyAuth, kServerChallenge, OK), 9540 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9541 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 9542 { TestRound(kGetProxy, kProxyChallenge, OK), 9543 TestRound(kGetProxyAuth, kServerChallenge, OK), 9544 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9545 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 9546 { TestRound(kGetProxy, kProxyChallenge, OK), 9547 TestRound(kGetProxyAuth, kServerChallenge, OK), 9548 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9549 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 9550 { TestRound(kGetProxy, kProxyChallenge, OK), 9551 TestRound(kGetProxyAuth, kServerChallenge, OK), 9552 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9553 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 9554 { TestRound(kGetProxy, kProxyChallenge, OK), 9555 TestRound(kGetProxyAuth, kServerChallenge, OK), 9556 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9557 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 9558 { TestRound(kGetProxy, kProxyChallenge, OK), 9559 TestRound(kGetProxyAuth, kServerChallenge, OK), 9560 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9561 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 9562 { TestRound(kGetProxy, kProxyChallenge, OK), 9563 TestRound(kGetProxyAuth, kServerChallenge, OK), 9564 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9565 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 9566 { TestRound(kGetProxy, kProxyChallenge, OK), 9567 TestRound(kGetProxyAuth, kServerChallenge, OK), 9568 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9569 // Non-authenticating HTTPS server with a direct connection. 9570 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 9571 { TestRound(kGet, kSuccess, OK)}}, 9572 // Authenticating HTTPS server with a direct connection. 9573 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 9574 { TestRound(kGet, kServerChallenge, OK), 9575 TestRound(kGetAuth, kSuccess, OK)}}, 9576 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 9577 { TestRound(kGet, kServerChallenge, OK), 9578 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9579 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 9580 { TestRound(kGet, kServerChallenge, OK), 9581 TestRound(kGetAuth, kSuccess, OK)}}, 9582 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 9583 { TestRound(kGet, kServerChallenge, OK), 9584 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9585 // Non-authenticating HTTPS server with a non-authenticating proxy. 9586 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 9587 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}}, 9588 // Authenticating HTTPS server through a non-authenticating proxy. 9589 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 9590 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9591 TestRound(kGetAuth, kSuccess, OK)}}, 9592 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 9593 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9594 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9595 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 9596 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9597 TestRound(kGetAuth, kSuccess, OK)}}, 9598 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 9599 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9600 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9601 // Non-Authenticating HTTPS server through an authenticating proxy. 9602 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 9603 { TestRound(kConnect, kProxyChallenge, OK), 9604 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 9605 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 9606 { TestRound(kConnect, kProxyChallenge, OK), 9607 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 9608 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 9609 { TestRound(kConnect, kProxyChallenge, OK), 9610 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 9611 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 9612 { TestRound(kConnect, kProxyChallenge, OK), 9613 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 9614 // Authenticating HTTPS server through an authenticating proxy. 9615 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 9616 { TestRound(kConnect, kProxyChallenge, OK), 9617 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9618 &kGet, &kServerChallenge), 9619 TestRound(kGetAuth, kSuccess, OK)}}, 9620 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 9621 { TestRound(kConnect, kProxyChallenge, OK), 9622 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9623 &kGet, &kServerChallenge), 9624 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9625 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 9626 { TestRound(kConnect, kProxyChallenge, OK), 9627 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9628 &kGet, &kServerChallenge), 9629 TestRound(kGetAuth, kSuccess, OK)}}, 9630 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 9631 { TestRound(kConnect, kProxyChallenge, OK), 9632 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9633 &kGet, &kServerChallenge), 9634 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9635 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 9636 { TestRound(kConnect, kProxyChallenge, OK), 9637 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9638 &kGet, &kServerChallenge), 9639 TestRound(kGetAuth, kSuccess, OK)}}, 9640 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 9641 { TestRound(kConnect, kProxyChallenge, OK), 9642 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9643 &kGet, &kServerChallenge), 9644 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9645 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 9646 { TestRound(kConnect, kProxyChallenge, OK), 9647 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9648 &kGet, &kServerChallenge), 9649 TestRound(kGetAuth, kSuccess, OK)}}, 9650 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 9651 { TestRound(kConnect, kProxyChallenge, OK), 9652 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9653 &kGet, &kServerChallenge), 9654 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9655 }; 9656 9657 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) { 9658 HttpAuthHandlerMock::Factory* auth_factory( 9659 new HttpAuthHandlerMock::Factory()); 9660 session_deps_.http_auth_handler_factory.reset(auth_factory); 9661 const TestConfig& test_config = test_configs[i]; 9662 9663 // Set up authentication handlers as necessary. 9664 if (test_config.proxy_auth_timing != AUTH_NONE) { 9665 for (int n = 0; n < 2; n++) { 9666 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9667 std::string auth_challenge = "Mock realm=proxy"; 9668 GURL origin(test_config.proxy_url); 9669 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), 9670 auth_challenge.end()); 9671 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY, 9672 origin, BoundNetLog()); 9673 auth_handler->SetGenerateExpectation( 9674 test_config.proxy_auth_timing == AUTH_ASYNC, 9675 test_config.proxy_auth_rv); 9676 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); 9677 } 9678 } 9679 if (test_config.server_auth_timing != AUTH_NONE) { 9680 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9681 std::string auth_challenge = "Mock realm=server"; 9682 GURL origin(test_config.server_url); 9683 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), 9684 auth_challenge.end()); 9685 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 9686 origin, BoundNetLog()); 9687 auth_handler->SetGenerateExpectation( 9688 test_config.server_auth_timing == AUTH_ASYNC, 9689 test_config.server_auth_rv); 9690 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); 9691 } 9692 if (test_config.proxy_url) { 9693 session_deps_.proxy_service.reset( 9694 ProxyService::CreateFixed(test_config.proxy_url)); 9695 } else { 9696 session_deps_.proxy_service.reset(ProxyService::CreateDirect()); 9697 } 9698 9699 HttpRequestInfo request; 9700 request.method = "GET"; 9701 request.url = GURL(test_config.server_url); 9702 request.load_flags = 0; 9703 9704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); 9706 9707 for (int round = 0; round < test_config.num_auth_rounds; ++round) { 9708 const TestRound& read_write_round = test_config.rounds[round]; 9709 9710 // Set up expected reads and writes. 9711 MockRead reads[2]; 9712 reads[0] = read_write_round.read; 9713 size_t length_reads = 1; 9714 if (read_write_round.extra_read) { 9715 reads[1] = *read_write_round.extra_read; 9716 length_reads = 2; 9717 } 9718 9719 MockWrite writes[2]; 9720 writes[0] = read_write_round.write; 9721 size_t length_writes = 1; 9722 if (read_write_round.extra_write) { 9723 writes[1] = *read_write_round.extra_write; 9724 length_writes = 2; 9725 } 9726 StaticSocketDataProvider data_provider( 9727 reads, length_reads, writes, length_writes); 9728 session_deps_.socket_factory->AddSocketDataProvider(&data_provider); 9729 9730 // Add an SSL sequence if necessary. 9731 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK); 9732 if (round >= test_config.first_ssl_round) 9733 session_deps_.socket_factory->AddSSLSocketDataProvider( 9734 &ssl_socket_data_provider); 9735 9736 // Start or restart the transaction. 9737 TestCompletionCallback callback; 9738 int rv; 9739 if (round == 0) { 9740 rv = trans.Start(&request, callback.callback(), BoundNetLog()); 9741 } else { 9742 rv = trans.RestartWithAuth( 9743 AuthCredentials(kFoo, kBar), callback.callback()); 9744 } 9745 if (rv == ERR_IO_PENDING) 9746 rv = callback.WaitForResult(); 9747 9748 // Compare results with expected data. 9749 EXPECT_EQ(read_write_round.expected_rv, rv); 9750 const HttpResponseInfo* response = trans.GetResponseInfo(); 9751 if (read_write_round.expected_rv == OK) { 9752 ASSERT_TRUE(response != NULL); 9753 } else { 9754 EXPECT_TRUE(response == NULL); 9755 EXPECT_EQ(round + 1, test_config.num_auth_rounds); 9756 continue; 9757 } 9758 if (round + 1 < test_config.num_auth_rounds) { 9759 EXPECT_FALSE(response->auth_challenge.get() == NULL); 9760 } else { 9761 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9762 } 9763 } 9764 } 9765 } 9766 9767 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) { 9768 // Do multi-round authentication and make sure it works correctly. 9769 HttpAuthHandlerMock::Factory* auth_factory( 9770 new HttpAuthHandlerMock::Factory()); 9771 session_deps_.http_auth_handler_factory.reset(auth_factory); 9772 session_deps_.proxy_service.reset(ProxyService::CreateDirect()); 9773 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1"); 9774 session_deps_.host_resolver->set_synchronous_mode(true); 9775 9776 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9777 auth_handler->set_connection_based(true); 9778 std::string auth_challenge = "Mock realm=server"; 9779 GURL origin("http://www.example.com"); 9780 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), 9781 auth_challenge.end()); 9782 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 9783 origin, BoundNetLog()); 9784 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); 9785 9786 int rv = OK; 9787 const HttpResponseInfo* response = NULL; 9788 HttpRequestInfo request; 9789 request.method = "GET"; 9790 request.url = origin; 9791 request.load_flags = 0; 9792 9793 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9794 9795 // Use a TCP Socket Pool with only one connection per group. This is used 9796 // to validate that the TCP socket is not released to the pool between 9797 // each round of multi-round authentication. 9798 HttpNetworkSessionPeer session_peer(session); 9799 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP"); 9800 TransportClientSocketPool* transport_pool = new TransportClientSocketPool( 9801 50, // Max sockets for pool 9802 1, // Max sockets per group 9803 &transport_pool_histograms, 9804 session_deps_.host_resolver.get(), 9805 session_deps_.socket_factory.get(), 9806 session_deps_.net_log); 9807 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 9808 new MockClientSocketPoolManager); 9809 mock_pool_manager->SetTransportSocketPool(transport_pool); 9810 session_peer.SetClientSocketPoolManager( 9811 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 9812 9813 scoped_ptr<HttpTransaction> trans( 9814 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9815 TestCompletionCallback callback; 9816 9817 const MockWrite kGet( 9818 "GET / HTTP/1.1\r\n" 9819 "Host: www.example.com\r\n" 9820 "Connection: keep-alive\r\n\r\n"); 9821 const MockWrite kGetAuth( 9822 "GET / HTTP/1.1\r\n" 9823 "Host: www.example.com\r\n" 9824 "Connection: keep-alive\r\n" 9825 "Authorization: auth_token\r\n\r\n"); 9826 9827 const MockRead kServerChallenge( 9828 "HTTP/1.1 401 Unauthorized\r\n" 9829 "WWW-Authenticate: Mock realm=server\r\n" 9830 "Content-Type: text/html; charset=iso-8859-1\r\n" 9831 "Content-Length: 14\r\n\r\n" 9832 "Unauthorized\r\n"); 9833 const MockRead kSuccess( 9834 "HTTP/1.1 200 OK\r\n" 9835 "Content-Type: text/html; charset=iso-8859-1\r\n" 9836 "Content-Length: 3\r\n\r\n" 9837 "Yes"); 9838 9839 MockWrite writes[] = { 9840 // First round 9841 kGet, 9842 // Second round 9843 kGetAuth, 9844 // Third round 9845 kGetAuth, 9846 // Fourth round 9847 kGetAuth, 9848 // Competing request 9849 kGet, 9850 }; 9851 MockRead reads[] = { 9852 // First round 9853 kServerChallenge, 9854 // Second round 9855 kServerChallenge, 9856 // Third round 9857 kServerChallenge, 9858 // Fourth round 9859 kSuccess, 9860 // Competing response 9861 kSuccess, 9862 }; 9863 StaticSocketDataProvider data_provider(reads, arraysize(reads), 9864 writes, arraysize(writes)); 9865 session_deps_.socket_factory->AddSocketDataProvider(&data_provider); 9866 9867 const char* const kSocketGroup = "www.example.com:80"; 9868 9869 // First round of authentication. 9870 auth_handler->SetGenerateExpectation(false, OK); 9871 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9872 if (rv == ERR_IO_PENDING) 9873 rv = callback.WaitForResult(); 9874 EXPECT_EQ(OK, rv); 9875 response = trans->GetResponseInfo(); 9876 ASSERT_TRUE(response != NULL); 9877 EXPECT_FALSE(response->auth_challenge.get() == NULL); 9878 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9879 9880 // In between rounds, another request comes in for the same domain. 9881 // It should not be able to grab the TCP socket that trans has already 9882 // claimed. 9883 scoped_ptr<HttpTransaction> trans_compete( 9884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9885 TestCompletionCallback callback_compete; 9886 rv = trans_compete->Start( 9887 &request, callback_compete.callback(), BoundNetLog()); 9888 EXPECT_EQ(ERR_IO_PENDING, rv); 9889 // callback_compete.WaitForResult at this point would stall forever, 9890 // since the HttpNetworkTransaction does not release the request back to 9891 // the pool until after authentication completes. 9892 9893 // Second round of authentication. 9894 auth_handler->SetGenerateExpectation(false, OK); 9895 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); 9896 if (rv == ERR_IO_PENDING) 9897 rv = callback.WaitForResult(); 9898 EXPECT_EQ(OK, rv); 9899 response = trans->GetResponseInfo(); 9900 ASSERT_TRUE(response != NULL); 9901 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9902 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9903 9904 // Third round of authentication. 9905 auth_handler->SetGenerateExpectation(false, OK); 9906 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); 9907 if (rv == ERR_IO_PENDING) 9908 rv = callback.WaitForResult(); 9909 EXPECT_EQ(OK, rv); 9910 response = trans->GetResponseInfo(); 9911 ASSERT_TRUE(response != NULL); 9912 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9913 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9914 9915 // Fourth round of authentication, which completes successfully. 9916 auth_handler->SetGenerateExpectation(false, OK); 9917 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); 9918 if (rv == ERR_IO_PENDING) 9919 rv = callback.WaitForResult(); 9920 EXPECT_EQ(OK, rv); 9921 response = trans->GetResponseInfo(); 9922 ASSERT_TRUE(response != NULL); 9923 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9924 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9925 9926 // Read the body since the fourth round was successful. This will also 9927 // release the socket back to the pool. 9928 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50)); 9929 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 9930 if (rv == ERR_IO_PENDING) 9931 rv = callback.WaitForResult(); 9932 EXPECT_EQ(3, rv); 9933 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 9934 EXPECT_EQ(0, rv); 9935 // There are still 0 idle sockets, since the trans_compete transaction 9936 // will be handed it immediately after trans releases it to the group. 9937 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9938 9939 // The competing request can now finish. Wait for the headers and then 9940 // read the body. 9941 rv = callback_compete.WaitForResult(); 9942 EXPECT_EQ(OK, rv); 9943 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); 9944 if (rv == ERR_IO_PENDING) 9945 rv = callback.WaitForResult(); 9946 EXPECT_EQ(3, rv); 9947 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); 9948 EXPECT_EQ(0, rv); 9949 9950 // Finally, the socket is released to the group. 9951 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9952 } 9953 9954 // This tests the case that a request is issued via http instead of spdy after 9955 // npn is negotiated. 9956 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) { 9957 session_deps_.use_alternate_protocols = true; 9958 NextProtoVector next_protos; 9959 next_protos.push_back(kProtoHTTP11); 9960 session_deps_.next_protos = next_protos; 9961 9962 HttpRequestInfo request; 9963 request.method = "GET"; 9964 request.url = GURL("https://www.google.com/"); 9965 request.load_flags = 0; 9966 9967 MockWrite data_writes[] = { 9968 MockWrite("GET / HTTP/1.1\r\n" 9969 "Host: www.google.com\r\n" 9970 "Connection: keep-alive\r\n\r\n"), 9971 }; 9972 9973 std::string alternate_protocol_http_header = 9974 GetAlternateProtocolHttpHeader(); 9975 9976 MockRead data_reads[] = { 9977 MockRead("HTTP/1.1 200 OK\r\n"), 9978 MockRead(alternate_protocol_http_header.c_str()), 9979 MockRead("hello world"), 9980 MockRead(SYNCHRONOUS, OK), 9981 }; 9982 9983 SSLSocketDataProvider ssl(ASYNC, OK); 9984 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 9985 ssl.next_proto = "http/1.1"; 9986 ssl.protocol_negotiated = kProtoHTTP11; 9987 9988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9989 9990 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 9991 data_writes, arraysize(data_writes)); 9992 session_deps_.socket_factory->AddSocketDataProvider(&data); 9993 9994 TestCompletionCallback callback; 9995 9996 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9997 scoped_ptr<HttpTransaction> trans( 9998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9999 10000 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 10001 10002 EXPECT_EQ(ERR_IO_PENDING, rv); 10003 EXPECT_EQ(OK, callback.WaitForResult()); 10004 10005 const HttpResponseInfo* response = trans->GetResponseInfo(); 10006 ASSERT_TRUE(response != NULL); 10007 ASSERT_TRUE(response->headers.get() != NULL); 10008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10009 10010 std::string response_data; 10011 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 10012 EXPECT_EQ("hello world", response_data); 10013 10014 EXPECT_FALSE(response->was_fetched_via_spdy); 10015 EXPECT_TRUE(response->was_npn_negotiated); 10016 } 10017 10018 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) { 10019 // Simulate the SSL handshake completing with an NPN negotiation 10020 // followed by an immediate server closing of the socket. 10021 // Fix crash: http://crbug.com/46369 10022 session_deps_.use_alternate_protocols = true; 10023 session_deps_.next_protos = SpdyNextProtos(); 10024 10025 HttpRequestInfo request; 10026 request.method = "GET"; 10027 request.url = GURL("https://www.google.com/"); 10028 request.load_flags = 0; 10029 10030 SSLSocketDataProvider ssl(ASYNC, OK); 10031 ssl.SetNextProto(GetParam()); 10032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10033 10034 scoped_ptr<SpdyFrame> req( 10035 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 10036 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 10037 10038 MockRead spdy_reads[] = { 10039 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately. 10040 }; 10041 10042 DelayedSocketData spdy_data( 10043 0, // don't wait in this case, immediate hangup. 10044 spdy_reads, arraysize(spdy_reads), 10045 spdy_writes, arraysize(spdy_writes)); 10046 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10047 10048 TestCompletionCallback callback; 10049 10050 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10051 scoped_ptr<HttpTransaction> trans( 10052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10053 10054 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 10055 EXPECT_EQ(ERR_IO_PENDING, rv); 10056 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); 10057 } 10058 10059 // A subclass of HttpAuthHandlerMock that records the request URL when 10060 // it gets it. This is needed since the auth handler may get destroyed 10061 // before we get a chance to query it. 10062 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock { 10063 public: 10064 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {} 10065 10066 virtual ~UrlRecordingHttpAuthHandlerMock() {} 10067 10068 protected: 10069 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials, 10070 const HttpRequestInfo* request, 10071 const CompletionCallback& callback, 10072 std::string* auth_token) OVERRIDE { 10073 *url_ = request->url; 10074 return HttpAuthHandlerMock::GenerateAuthTokenImpl( 10075 credentials, request, callback, auth_token); 10076 } 10077 10078 private: 10079 GURL* url_; 10080 }; 10081 10082 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { 10083 // This test ensures that the URL passed into the proxy is upgraded 10084 // to https when doing an Alternate Protocol upgrade. 10085 session_deps_.use_alternate_protocols = true; 10086 session_deps_.next_protos = SpdyNextProtos(); 10087 10088 session_deps_.proxy_service.reset( 10089 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 10090 CapturingNetLog net_log; 10091 session_deps_.net_log = &net_log; 10092 GURL request_url; 10093 { 10094 HttpAuthHandlerMock::Factory* auth_factory = 10095 new HttpAuthHandlerMock::Factory(); 10096 UrlRecordingHttpAuthHandlerMock* auth_handler = 10097 new UrlRecordingHttpAuthHandlerMock(&request_url); 10098 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); 10099 auth_factory->set_do_init_from_challenge(true); 10100 session_deps_.http_auth_handler_factory.reset(auth_factory); 10101 } 10102 10103 HttpRequestInfo request; 10104 request.method = "GET"; 10105 request.url = GURL("http://www.google.com"); 10106 request.load_flags = 0; 10107 10108 // First round goes unauthenticated through the proxy. 10109 MockWrite data_writes_1[] = { 10110 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 10111 "Host: www.google.com\r\n" 10112 "Proxy-Connection: keep-alive\r\n" 10113 "\r\n"), 10114 }; 10115 MockRead data_reads_1[] = { 10116 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 10117 MockRead("HTTP/1.1 200 OK\r\n" 10118 "Alternate-Protocol: 443:npn-spdy/2\r\n" 10119 "Proxy-Connection: close\r\n" 10120 "\r\n"), 10121 }; 10122 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1), 10123 data_writes_1, arraysize(data_writes_1)); 10124 10125 // Second round tries to tunnel to www.google.com due to the 10126 // Alternate-Protocol announcement in the first round. It fails due 10127 // to a proxy authentication challenge. 10128 // After the failure, a tunnel is established to www.google.com using 10129 // Proxy-Authorization headers. There is then a SPDY request round. 10130 // 10131 // NOTE: Despite the "Proxy-Connection: Close", these are done on the 10132 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket 10133 // does a Disconnect and Connect on the same socket, rather than trying 10134 // to obtain a new one. 10135 // 10136 // NOTE: Originally, the proxy response to the second CONNECT request 10137 // simply returned another 407 so the unit test could skip the SSL connection 10138 // establishment and SPDY framing issues. Alas, the 10139 // retry-http-when-alternate-protocol fails logic kicks in, which was more 10140 // complicated to set up expectations for than the SPDY session. 10141 10142 scoped_ptr<SpdyFrame> req( 10143 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 10144 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10145 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10146 10147 MockWrite data_writes_2[] = { 10148 // First connection attempt without Proxy-Authorization. 10149 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10150 "Host: www.google.com\r\n" 10151 "Proxy-Connection: keep-alive\r\n" 10152 "\r\n"), 10153 10154 // Second connection attempt with Proxy-Authorization. 10155 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10156 "Host: www.google.com\r\n" 10157 "Proxy-Connection: keep-alive\r\n" 10158 "Proxy-Authorization: auth_token\r\n" 10159 "\r\n"), 10160 10161 // SPDY request 10162 CreateMockWrite(*req), 10163 }; 10164 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n" 10165 "Proxy-Authenticate: Mock\r\n" 10166 "Proxy-Connection: close\r\n" 10167 "\r\n"); 10168 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 10169 MockRead data_reads_2[] = { 10170 // First connection attempt fails 10171 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1), 10172 MockRead(ASYNC, kRejectConnectResponse, 10173 arraysize(kRejectConnectResponse) - 1, 1), 10174 10175 // Second connection attempt passes 10176 MockRead(ASYNC, kAcceptConnectResponse, 10177 arraysize(kAcceptConnectResponse) -1, 4), 10178 10179 // SPDY response 10180 CreateMockRead(*resp.get(), 6), 10181 CreateMockRead(*data.get(), 6), 10182 MockRead(ASYNC, 0, 0, 6), 10183 }; 10184 OrderedSocketData data_2( 10185 data_reads_2, arraysize(data_reads_2), 10186 data_writes_2, arraysize(data_writes_2)); 10187 10188 SSLSocketDataProvider ssl(ASYNC, OK); 10189 ssl.SetNextProto(GetParam()); 10190 10191 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 10192 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 10193 NULL, 0, NULL, 0); 10194 hanging_non_alternate_protocol_socket.set_connect_data( 10195 never_finishing_connect); 10196 10197 session_deps_.socket_factory->AddSocketDataProvider(&data_1); 10198 session_deps_.socket_factory->AddSocketDataProvider(&data_2); 10199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10200 session_deps_.socket_factory->AddSocketDataProvider( 10201 &hanging_non_alternate_protocol_socket); 10202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10203 10204 // First round should work and provide the Alternate-Protocol state. 10205 TestCompletionCallback callback_1; 10206 scoped_ptr<HttpTransaction> trans_1( 10207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10208 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog()); 10209 EXPECT_EQ(ERR_IO_PENDING, rv); 10210 EXPECT_EQ(OK, callback_1.WaitForResult()); 10211 10212 // Second round should attempt a tunnel connect and get an auth challenge. 10213 TestCompletionCallback callback_2; 10214 scoped_ptr<HttpTransaction> trans_2( 10215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10216 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog()); 10217 EXPECT_EQ(ERR_IO_PENDING, rv); 10218 EXPECT_EQ(OK, callback_2.WaitForResult()); 10219 const HttpResponseInfo* response = trans_2->GetResponseInfo(); 10220 ASSERT_TRUE(response != NULL); 10221 ASSERT_FALSE(response->auth_challenge.get() == NULL); 10222 10223 // Restart with auth. Tunnel should work and response received. 10224 TestCompletionCallback callback_3; 10225 rv = trans_2->RestartWithAuth( 10226 AuthCredentials(kFoo, kBar), callback_3.callback()); 10227 EXPECT_EQ(ERR_IO_PENDING, rv); 10228 EXPECT_EQ(OK, callback_3.WaitForResult()); 10229 10230 // After all that work, these two lines (or actually, just the scheme) are 10231 // what this test is all about. Make sure it happens correctly. 10232 EXPECT_EQ("https", request_url.scheme()); 10233 EXPECT_EQ("www.google.com", request_url.host()); 10234 10235 LoadTimingInfo load_timing_info; 10236 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info)); 10237 TestLoadTimingNotReusedWithPac(load_timing_info, 10238 CONNECT_TIMING_HAS_SSL_TIMES); 10239 } 10240 10241 // Test that if we cancel the transaction as the connection is completing, that 10242 // everything tears down correctly. 10243 TEST_P(HttpNetworkTransactionTest, SimpleCancel) { 10244 // Setup everything about the connection to complete synchronously, so that 10245 // after calling HttpNetworkTransaction::Start, the only thing we're waiting 10246 // for is the callback from the HttpStreamRequest. 10247 // Then cancel the transaction. 10248 // Verify that we don't crash. 10249 MockConnect mock_connect(SYNCHRONOUS, OK); 10250 MockRead data_reads[] = { 10251 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"), 10252 MockRead(SYNCHRONOUS, "hello world"), 10253 MockRead(SYNCHRONOUS, OK), 10254 }; 10255 10256 HttpRequestInfo request; 10257 request.method = "GET"; 10258 request.url = GURL("http://www.google.com/"); 10259 request.load_flags = 0; 10260 10261 session_deps_.host_resolver->set_synchronous_mode(true); 10262 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10263 scoped_ptr<HttpTransaction> trans( 10264 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10265 10266 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 10267 data.set_connect_data(mock_connect); 10268 session_deps_.socket_factory->AddSocketDataProvider(&data); 10269 10270 TestCompletionCallback callback; 10271 10272 CapturingBoundNetLog log; 10273 int rv = trans->Start(&request, callback.callback(), log.bound()); 10274 EXPECT_EQ(ERR_IO_PENDING, rv); 10275 trans.reset(); // Cancel the transaction here. 10276 10277 base::MessageLoop::current()->RunUntilIdle(); 10278 } 10279 10280 // Test that if a transaction is cancelled after receiving the headers, the 10281 // stream is drained properly and added back to the socket pool. The main 10282 // purpose of this test is to make sure that an HttpStreamParser can be read 10283 // from after the HttpNetworkTransaction and the objects it owns have been 10284 // deleted. 10285 // See http://crbug.com/368418 10286 TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) { 10287 MockRead data_reads[] = { 10288 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"), 10289 MockRead(ASYNC, "Content-Length: 2\r\n"), 10290 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"), 10291 MockRead(ASYNC, "1"), 10292 // 2 async reads are necessary to trigger a ReadResponseBody call after the 10293 // HttpNetworkTransaction has been deleted. 10294 MockRead(ASYNC, "2"), 10295 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this. 10296 }; 10297 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 10298 session_deps_.socket_factory->AddSocketDataProvider(&data); 10299 10300 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10301 10302 { 10303 HttpRequestInfo request; 10304 request.method = "GET"; 10305 request.url = GURL("http://www.google.com/"); 10306 request.load_flags = 0; 10307 10308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); 10309 TestCompletionCallback callback; 10310 10311 int rv = trans.Start(&request, callback.callback(), BoundNetLog()); 10312 EXPECT_EQ(ERR_IO_PENDING, rv); 10313 callback.WaitForResult(); 10314 10315 const HttpResponseInfo* response = trans.GetResponseInfo(); 10316 ASSERT_TRUE(response != NULL); 10317 EXPECT_TRUE(response->headers.get() != NULL); 10318 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10319 10320 // The transaction and HttpRequestInfo are deleted. 10321 } 10322 10323 // Let the HttpResponseBodyDrainer drain the socket. 10324 base::MessageLoop::current()->RunUntilIdle(); 10325 10326 // Socket should now be idle, waiting to be reused. 10327 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 10328 } 10329 10330 // Test a basic GET request through a proxy. 10331 TEST_P(HttpNetworkTransactionTest, ProxyGet) { 10332 session_deps_.proxy_service.reset( 10333 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 10334 CapturingBoundNetLog log; 10335 session_deps_.net_log = log.bound().net_log(); 10336 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10337 10338 HttpRequestInfo request; 10339 request.method = "GET"; 10340 request.url = GURL("http://www.google.com/"); 10341 10342 MockWrite data_writes1[] = { 10343 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 10344 "Host: www.google.com\r\n" 10345 "Proxy-Connection: keep-alive\r\n\r\n"), 10346 }; 10347 10348 MockRead data_reads1[] = { 10349 MockRead("HTTP/1.1 200 OK\r\n"), 10350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 10351 MockRead("Content-Length: 100\r\n\r\n"), 10352 MockRead(SYNCHRONOUS, OK), 10353 }; 10354 10355 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 10356 data_writes1, arraysize(data_writes1)); 10357 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10358 10359 TestCompletionCallback callback1; 10360 10361 scoped_ptr<HttpTransaction> trans( 10362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10363 BeforeProxyHeadersSentHandler proxy_headers_handler; 10364 trans->SetBeforeProxyHeadersSentCallback( 10365 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent, 10366 base::Unretained(&proxy_headers_handler))); 10367 10368 int rv = trans->Start(&request, callback1.callback(), log.bound()); 10369 EXPECT_EQ(ERR_IO_PENDING, rv); 10370 10371 rv = callback1.WaitForResult(); 10372 EXPECT_EQ(OK, rv); 10373 10374 const HttpResponseInfo* response = trans->GetResponseInfo(); 10375 ASSERT_TRUE(response != NULL); 10376 10377 EXPECT_TRUE(response->headers->IsKeepAlive()); 10378 EXPECT_EQ(200, response->headers->response_code()); 10379 EXPECT_EQ(100, response->headers->GetContentLength()); 10380 EXPECT_TRUE(response->was_fetched_via_proxy); 10381 EXPECT_TRUE( 10382 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70"))); 10383 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent()); 10384 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri()); 10385 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 10386 10387 LoadTimingInfo load_timing_info; 10388 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 10389 TestLoadTimingNotReusedWithPac(load_timing_info, 10390 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 10391 } 10392 10393 // Test a basic HTTPS GET request through a proxy. 10394 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) { 10395 session_deps_.proxy_service.reset( 10396 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 10397 CapturingBoundNetLog log; 10398 session_deps_.net_log = log.bound().net_log(); 10399 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10400 10401 HttpRequestInfo request; 10402 request.method = "GET"; 10403 request.url = GURL("https://www.google.com/"); 10404 10405 // Since we have proxy, should try to establish tunnel. 10406 MockWrite data_writes1[] = { 10407 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10408 "Host: www.google.com\r\n" 10409 "Proxy-Connection: keep-alive\r\n\r\n"), 10410 10411 MockWrite("GET / HTTP/1.1\r\n" 10412 "Host: www.google.com\r\n" 10413 "Connection: keep-alive\r\n\r\n"), 10414 }; 10415 10416 MockRead data_reads1[] = { 10417 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 10418 10419 MockRead("HTTP/1.1 200 OK\r\n"), 10420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 10421 MockRead("Content-Length: 100\r\n\r\n"), 10422 MockRead(SYNCHRONOUS, OK), 10423 }; 10424 10425 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 10426 data_writes1, arraysize(data_writes1)); 10427 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10428 SSLSocketDataProvider ssl(ASYNC, OK); 10429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10430 10431 TestCompletionCallback callback1; 10432 10433 scoped_ptr<HttpTransaction> trans( 10434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10435 10436 int rv = trans->Start(&request, callback1.callback(), log.bound()); 10437 EXPECT_EQ(ERR_IO_PENDING, rv); 10438 10439 rv = callback1.WaitForResult(); 10440 EXPECT_EQ(OK, rv); 10441 net::CapturingNetLog::CapturedEntryList entries; 10442 log.GetEntries(&entries); 10443 size_t pos = ExpectLogContainsSomewhere( 10444 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 10445 NetLog::PHASE_NONE); 10446 ExpectLogContainsSomewhere( 10447 entries, pos, 10448 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 10449 NetLog::PHASE_NONE); 10450 10451 const HttpResponseInfo* response = trans->GetResponseInfo(); 10452 ASSERT_TRUE(response != NULL); 10453 10454 EXPECT_TRUE(response->headers->IsKeepAlive()); 10455 EXPECT_EQ(200, response->headers->response_code()); 10456 EXPECT_EQ(100, response->headers->GetContentLength()); 10457 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 10458 EXPECT_TRUE(response->was_fetched_via_proxy); 10459 EXPECT_TRUE( 10460 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70"))); 10461 10462 LoadTimingInfo load_timing_info; 10463 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 10464 TestLoadTimingNotReusedWithPac(load_timing_info, 10465 CONNECT_TIMING_HAS_SSL_TIMES); 10466 } 10467 10468 // Test a basic HTTPS GET request through a proxy, but the server hangs up 10469 // while establishing the tunnel. 10470 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { 10471 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 10472 CapturingBoundNetLog log; 10473 session_deps_.net_log = log.bound().net_log(); 10474 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10475 10476 HttpRequestInfo request; 10477 request.method = "GET"; 10478 request.url = GURL("https://www.google.com/"); 10479 10480 // Since we have proxy, should try to establish tunnel. 10481 MockWrite data_writes1[] = { 10482 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10483 "Host: www.google.com\r\n" 10484 "Proxy-Connection: keep-alive\r\n\r\n"), 10485 10486 MockWrite("GET / HTTP/1.1\r\n" 10487 "Host: www.google.com\r\n" 10488 "Connection: keep-alive\r\n\r\n"), 10489 }; 10490 10491 MockRead data_reads1[] = { 10492 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 10493 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 10494 MockRead(ASYNC, 0, 0), // EOF 10495 }; 10496 10497 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 10498 data_writes1, arraysize(data_writes1)); 10499 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10500 SSLSocketDataProvider ssl(ASYNC, OK); 10501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10502 10503 TestCompletionCallback callback1; 10504 10505 scoped_ptr<HttpTransaction> trans( 10506 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10507 10508 int rv = trans->Start(&request, callback1.callback(), log.bound()); 10509 EXPECT_EQ(ERR_IO_PENDING, rv); 10510 10511 rv = callback1.WaitForResult(); 10512 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 10513 net::CapturingNetLog::CapturedEntryList entries; 10514 log.GetEntries(&entries); 10515 size_t pos = ExpectLogContainsSomewhere( 10516 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 10517 NetLog::PHASE_NONE); 10518 ExpectLogContainsSomewhere( 10519 entries, pos, 10520 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 10521 NetLog::PHASE_NONE); 10522 } 10523 10524 // Test for crbug.com/55424. 10525 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) { 10526 scoped_ptr<SpdyFrame> req( 10527 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10528 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 10529 10530 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10531 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10532 MockRead spdy_reads[] = { 10533 CreateMockRead(*resp), 10534 CreateMockRead(*data), 10535 MockRead(ASYNC, 0, 0), 10536 }; 10537 10538 DelayedSocketData spdy_data( 10539 1, // wait for one write to finish before reading. 10540 spdy_reads, arraysize(spdy_reads), 10541 spdy_writes, arraysize(spdy_writes)); 10542 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10543 10544 SSLSocketDataProvider ssl(ASYNC, OK); 10545 ssl.SetNextProto(GetParam()); 10546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10547 10548 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10549 10550 // Set up an initial SpdySession in the pool to reuse. 10551 HostPortPair host_port_pair("www.google.com", 443); 10552 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 10553 PRIVACY_MODE_DISABLED); 10554 base::WeakPtr<SpdySession> spdy_session = 10555 CreateInsecureSpdySession(session, key, BoundNetLog()); 10556 10557 HttpRequestInfo request; 10558 request.method = "GET"; 10559 request.url = GURL("https://www.google.com/"); 10560 request.load_flags = 0; 10561 10562 // This is the important line that marks this as a preconnect. 10563 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED; 10564 10565 scoped_ptr<HttpTransaction> trans( 10566 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10567 10568 TestCompletionCallback callback; 10569 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 10570 EXPECT_EQ(ERR_IO_PENDING, rv); 10571 EXPECT_EQ(OK, callback.WaitForResult()); 10572 } 10573 10574 // Given a net error, cause that error to be returned from the first Write() 10575 // call and verify that the HttpTransaction fails with that error. 10576 void HttpNetworkTransactionTest::CheckErrorIsPassedBack( 10577 int error, IoMode mode) { 10578 net::HttpRequestInfo request_info; 10579 request_info.url = GURL("https://www.example.com/"); 10580 request_info.method = "GET"; 10581 request_info.load_flags = net::LOAD_NORMAL; 10582 10583 SSLSocketDataProvider ssl_data(mode, OK); 10584 net::MockWrite data_writes[] = { 10585 net::MockWrite(mode, error), 10586 }; 10587 net::StaticSocketDataProvider data(NULL, 0, 10588 data_writes, arraysize(data_writes)); 10589 session_deps_.socket_factory->AddSocketDataProvider(&data); 10590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); 10591 10592 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10593 scoped_ptr<HttpTransaction> trans( 10594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10595 10596 TestCompletionCallback callback; 10597 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10598 if (rv == net::ERR_IO_PENDING) 10599 rv = callback.WaitForResult(); 10600 ASSERT_EQ(error, rv); 10601 } 10602 10603 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) { 10604 // Just check a grab bag of cert errors. 10605 static const int kErrors[] = { 10606 ERR_CERT_COMMON_NAME_INVALID, 10607 ERR_CERT_AUTHORITY_INVALID, 10608 ERR_CERT_DATE_INVALID, 10609 }; 10610 for (size_t i = 0; i < arraysize(kErrors); i++) { 10611 CheckErrorIsPassedBack(kErrors[i], ASYNC); 10612 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS); 10613 } 10614 } 10615 10616 // Ensure that a client certificate is removed from the SSL client auth 10617 // cache when: 10618 // 1) No proxy is involved. 10619 // 2) TLS False Start is disabled. 10620 // 3) The initial TLS handshake requests a client certificate. 10621 // 4) The client supplies an invalid/unacceptable certificate. 10622 TEST_P(HttpNetworkTransactionTest, 10623 ClientAuthCertCache_Direct_NoFalseStart) { 10624 net::HttpRequestInfo request_info; 10625 request_info.url = GURL("https://www.example.com/"); 10626 request_info.method = "GET"; 10627 request_info.load_flags = net::LOAD_NORMAL; 10628 10629 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10630 cert_request->host_and_port = HostPortPair("www.example.com", 443); 10631 10632 // [ssl_]data1 contains the data for the first SSL handshake. When a 10633 // CertificateRequest is received for the first time, the handshake will 10634 // be aborted to allow the caller to provide a certificate. 10635 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10636 ssl_data1.cert_request_info = cert_request.get(); 10637 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10638 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10639 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10640 10641 // [ssl_]data2 contains the data for the second SSL handshake. When TLS 10642 // False Start is not being used, the result of the SSL handshake will be 10643 // returned as part of the SSLClientSocket::Connect() call. This test 10644 // matches the result of a server sending a handshake_failure alert, 10645 // rather than a Finished message, because it requires a client 10646 // certificate and none was supplied. 10647 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10648 ssl_data2.cert_request_info = cert_request.get(); 10649 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10650 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 10651 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10652 10653 // [ssl_]data3 contains the data for the third SSL handshake. When a 10654 // connection to a server fails during an SSL handshake, 10655 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous 10656 // connection was attempted with TLSv1.1. This is transparent to the caller 10657 // of the HttpNetworkTransaction. Because this test failure is due to 10658 // requiring a client certificate, this fallback handshake should also 10659 // fail. 10660 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10661 ssl_data3.cert_request_info = cert_request.get(); 10662 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10663 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 10664 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10665 10666 // [ssl_]data4 contains the data for the fourth SSL handshake. When a 10667 // connection to a server fails during an SSL handshake, 10668 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous 10669 // connection was attempted with TLSv1. This is transparent to the caller 10670 // of the HttpNetworkTransaction. Because this test failure is due to 10671 // requiring a client certificate, this fallback handshake should also 10672 // fail. 10673 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10674 ssl_data4.cert_request_info = cert_request.get(); 10675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4); 10676 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0); 10677 session_deps_.socket_factory->AddSocketDataProvider(&data4); 10678 10679 // Need one more if TLSv1.2 is enabled. 10680 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10681 ssl_data5.cert_request_info = cert_request.get(); 10682 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5); 10683 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0); 10684 session_deps_.socket_factory->AddSocketDataProvider(&data5); 10685 10686 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10687 scoped_ptr<HttpTransaction> trans( 10688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10689 10690 // Begin the SSL handshake with the peer. This consumes ssl_data1. 10691 TestCompletionCallback callback; 10692 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10693 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10694 10695 // Complete the SSL handshake, which should abort due to requiring a 10696 // client certificate. 10697 rv = callback.WaitForResult(); 10698 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10699 10700 // Indicate that no certificate should be supplied. From the perspective 10701 // of SSLClientCertCache, NULL is just as meaningful as a real 10702 // certificate, so this is the same as supply a 10703 // legitimate-but-unacceptable certificate. 10704 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10705 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10706 10707 // Ensure the certificate was added to the client auth cache before 10708 // allowing the connection to continue restarting. 10709 scoped_refptr<X509Certificate> client_cert; 10710 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( 10711 HostPortPair("www.example.com", 443), &client_cert)); 10712 ASSERT_EQ(NULL, client_cert.get()); 10713 10714 // Restart the handshake. This will consume ssl_data2, which fails, and 10715 // then consume ssl_data3 and ssl_data4, both of which should also fail. 10716 // The result code is checked against what ssl_data4 should return. 10717 rv = callback.WaitForResult(); 10718 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 10719 10720 // Ensure that the client certificate is removed from the cache on a 10721 // handshake failure. 10722 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10723 HostPortPair("www.example.com", 443), &client_cert)); 10724 } 10725 10726 // Ensure that a client certificate is removed from the SSL client auth 10727 // cache when: 10728 // 1) No proxy is involved. 10729 // 2) TLS False Start is enabled. 10730 // 3) The initial TLS handshake requests a client certificate. 10731 // 4) The client supplies an invalid/unacceptable certificate. 10732 TEST_P(HttpNetworkTransactionTest, 10733 ClientAuthCertCache_Direct_FalseStart) { 10734 net::HttpRequestInfo request_info; 10735 request_info.url = GURL("https://www.example.com/"); 10736 request_info.method = "GET"; 10737 request_info.load_flags = net::LOAD_NORMAL; 10738 10739 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10740 cert_request->host_and_port = HostPortPair("www.example.com", 443); 10741 10742 // When TLS False Start is used, SSLClientSocket::Connect() calls will 10743 // return successfully after reading up to the peer's Certificate message. 10744 // This is to allow the caller to call SSLClientSocket::Write(), which can 10745 // enqueue application data to be sent in the same packet as the 10746 // ChangeCipherSpec and Finished messages. 10747 // The actual handshake will be finished when SSLClientSocket::Read() is 10748 // called, which expects to process the peer's ChangeCipherSpec and 10749 // Finished messages. If there was an error negotiating with the peer, 10750 // such as due to the peer requiring a client certificate when none was 10751 // supplied, the alert sent by the peer won't be processed until Read() is 10752 // called. 10753 10754 // Like the non-False Start case, when a client certificate is requested by 10755 // the peer, the handshake is aborted during the Connect() call. 10756 // [ssl_]data1 represents the initial SSL handshake with the peer. 10757 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10758 ssl_data1.cert_request_info = cert_request.get(); 10759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10760 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10761 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10762 10763 // When a client certificate is supplied, Connect() will not be aborted 10764 // when the peer requests the certificate. Instead, the handshake will 10765 // artificially succeed, allowing the caller to write the HTTP request to 10766 // the socket. The handshake messages are not processed until Read() is 10767 // called, which then detects that the handshake was aborted, due to the 10768 // peer sending a handshake_failure because it requires a client 10769 // certificate. 10770 SSLSocketDataProvider ssl_data2(ASYNC, net::OK); 10771 ssl_data2.cert_request_info = cert_request.get(); 10772 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10773 net::MockRead data2_reads[] = { 10774 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR), 10775 }; 10776 net::StaticSocketDataProvider data2( 10777 data2_reads, arraysize(data2_reads), NULL, 0); 10778 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10779 10780 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is 10781 // the data for the SSL handshake once the TLSv1.1 connection falls back to 10782 // TLSv1. It has the same behaviour as [ssl_]data2. 10783 SSLSocketDataProvider ssl_data3(ASYNC, net::OK); 10784 ssl_data3.cert_request_info = cert_request.get(); 10785 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10786 net::StaticSocketDataProvider data3( 10787 data2_reads, arraysize(data2_reads), NULL, 0); 10788 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10789 10790 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection 10791 // falls back to SSLv3. It has the same behaviour as [ssl_]data2. 10792 SSLSocketDataProvider ssl_data4(ASYNC, net::OK); 10793 ssl_data4.cert_request_info = cert_request.get(); 10794 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4); 10795 net::StaticSocketDataProvider data4( 10796 data2_reads, arraysize(data2_reads), NULL, 0); 10797 session_deps_.socket_factory->AddSocketDataProvider(&data4); 10798 10799 // Need one more if TLSv1.2 is enabled. 10800 SSLSocketDataProvider ssl_data5(ASYNC, net::OK); 10801 ssl_data5.cert_request_info = cert_request.get(); 10802 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5); 10803 net::StaticSocketDataProvider data5( 10804 data2_reads, arraysize(data2_reads), NULL, 0); 10805 session_deps_.socket_factory->AddSocketDataProvider(&data5); 10806 10807 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10808 scoped_ptr<HttpTransaction> trans( 10809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10810 10811 // Begin the initial SSL handshake. 10812 TestCompletionCallback callback; 10813 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10814 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10815 10816 // Complete the SSL handshake, which should abort due to requiring a 10817 // client certificate. 10818 rv = callback.WaitForResult(); 10819 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10820 10821 // Indicate that no certificate should be supplied. From the perspective 10822 // of SSLClientCertCache, NULL is just as meaningful as a real 10823 // certificate, so this is the same as supply a 10824 // legitimate-but-unacceptable certificate. 10825 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10826 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10827 10828 // Ensure the certificate was added to the client auth cache before 10829 // allowing the connection to continue restarting. 10830 scoped_refptr<X509Certificate> client_cert; 10831 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( 10832 HostPortPair("www.example.com", 443), &client_cert)); 10833 ASSERT_EQ(NULL, client_cert.get()); 10834 10835 // Restart the handshake. This will consume ssl_data2, which fails, and 10836 // then consume ssl_data3 and ssl_data4, both of which should also fail. 10837 // The result code is checked against what ssl_data4 should return. 10838 rv = callback.WaitForResult(); 10839 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 10840 10841 // Ensure that the client certificate is removed from the cache on a 10842 // handshake failure. 10843 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10844 HostPortPair("www.example.com", 443), &client_cert)); 10845 } 10846 10847 // Ensure that a client certificate is removed from the SSL client auth 10848 // cache when: 10849 // 1) An HTTPS proxy is involved. 10850 // 3) The HTTPS proxy requests a client certificate. 10851 // 4) The client supplies an invalid/unacceptable certificate for the 10852 // proxy. 10853 // The test is repeated twice, first for connecting to an HTTPS endpoint, 10854 // then for connecting to an HTTP endpoint. 10855 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) { 10856 session_deps_.proxy_service.reset( 10857 ProxyService::CreateFixed("https://proxy:70")); 10858 CapturingBoundNetLog log; 10859 session_deps_.net_log = log.bound().net_log(); 10860 10861 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10862 cert_request->host_and_port = HostPortPair("proxy", 70); 10863 10864 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of 10865 // [ssl_]data[1-3]. Rather than represending the endpoint 10866 // (www.example.com:443), they represent failures with the HTTPS proxy 10867 // (proxy:70). 10868 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10869 ssl_data1.cert_request_info = cert_request.get(); 10870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10871 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10872 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10873 10874 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10875 ssl_data2.cert_request_info = cert_request.get(); 10876 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10877 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 10878 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10879 10880 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3. 10881 #if 0 10882 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10883 ssl_data3.cert_request_info = cert_request.get(); 10884 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10885 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 10886 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10887 #endif 10888 10889 net::HttpRequestInfo requests[2]; 10890 requests[0].url = GURL("https://www.example.com/"); 10891 requests[0].method = "GET"; 10892 requests[0].load_flags = net::LOAD_NORMAL; 10893 10894 requests[1].url = GURL("http://www.example.com/"); 10895 requests[1].method = "GET"; 10896 requests[1].load_flags = net::LOAD_NORMAL; 10897 10898 for (size_t i = 0; i < arraysize(requests); ++i) { 10899 session_deps_.socket_factory->ResetNextMockIndexes(); 10900 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10901 scoped_ptr<HttpNetworkTransaction> trans( 10902 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10903 10904 // Begin the SSL handshake with the proxy. 10905 TestCompletionCallback callback; 10906 int rv = trans->Start( 10907 &requests[i], callback.callback(), net::BoundNetLog()); 10908 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10909 10910 // Complete the SSL handshake, which should abort due to requiring a 10911 // client certificate. 10912 rv = callback.WaitForResult(); 10913 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10914 10915 // Indicate that no certificate should be supplied. From the perspective 10916 // of SSLClientCertCache, NULL is just as meaningful as a real 10917 // certificate, so this is the same as supply a 10918 // legitimate-but-unacceptable certificate. 10919 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10920 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10921 10922 // Ensure the certificate was added to the client auth cache before 10923 // allowing the connection to continue restarting. 10924 scoped_refptr<X509Certificate> client_cert; 10925 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( 10926 HostPortPair("proxy", 70), &client_cert)); 10927 ASSERT_EQ(NULL, client_cert.get()); 10928 // Ensure the certificate was NOT cached for the endpoint. This only 10929 // applies to HTTPS requests, but is fine to check for HTTP requests. 10930 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10931 HostPortPair("www.example.com", 443), &client_cert)); 10932 10933 // Restart the handshake. This will consume ssl_data2, which fails, and 10934 // then consume ssl_data3, which should also fail. The result code is 10935 // checked against what ssl_data3 should return. 10936 rv = callback.WaitForResult(); 10937 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv); 10938 10939 // Now that the new handshake has failed, ensure that the client 10940 // certificate was removed from the client auth cache. 10941 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10942 HostPortPair("proxy", 70), &client_cert)); 10943 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10944 HostPortPair("www.example.com", 443), &client_cert)); 10945 } 10946 } 10947 10948 // Unlike TEST/TEST_F, which are macros that expand to further macros, 10949 // TEST_P is a macro that expands directly to code that stringizes the 10950 // arguments. As a result, macros passed as parameters (such as prefix 10951 // or test_case_name) will not be expanded by the preprocessor. To 10952 // work around this, indirect the macro for TEST_P, so that the 10953 // pre-processor will expand macros such as MAYBE_test_name before 10954 // instantiating the test. 10955 #define WRAPPED_TEST_P(test_case_name, test_name) \ 10956 TEST_P(test_case_name, test_name) 10957 10958 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 10959 #if defined(OS_WIN) 10960 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling 10961 #else 10962 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling 10963 #endif 10964 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) { 10965 session_deps_.use_alternate_protocols = true; 10966 session_deps_.next_protos = SpdyNextProtos(); 10967 10968 // Set up a special HttpNetworkSession with a MockCachingHostResolver. 10969 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 10970 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10971 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 10972 pool_peer.DisableDomainAuthenticationVerification(); 10973 10974 SSLSocketDataProvider ssl(ASYNC, OK); 10975 ssl.SetNextProto(GetParam()); 10976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10977 10978 scoped_ptr<SpdyFrame> host1_req( 10979 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10980 scoped_ptr<SpdyFrame> host2_req( 10981 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 10982 MockWrite spdy_writes[] = { 10983 CreateMockWrite(*host1_req, 1), 10984 CreateMockWrite(*host2_req, 4), 10985 }; 10986 scoped_ptr<SpdyFrame> host1_resp( 10987 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10988 scoped_ptr<SpdyFrame> host1_resp_body( 10989 spdy_util_.ConstructSpdyBodyFrame(1, true)); 10990 scoped_ptr<SpdyFrame> host2_resp( 10991 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 10992 scoped_ptr<SpdyFrame> host2_resp_body( 10993 spdy_util_.ConstructSpdyBodyFrame(3, true)); 10994 MockRead spdy_reads[] = { 10995 CreateMockRead(*host1_resp, 2), 10996 CreateMockRead(*host1_resp_body, 3), 10997 CreateMockRead(*host2_resp, 5), 10998 CreateMockRead(*host2_resp_body, 6), 10999 MockRead(ASYNC, 0, 7), 11000 }; 11001 11002 IPAddressNumber ip; 11003 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 11004 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11005 MockConnect connect(ASYNC, OK, peer_addr); 11006 OrderedSocketData spdy_data( 11007 connect, 11008 spdy_reads, arraysize(spdy_reads), 11009 spdy_writes, arraysize(spdy_writes)); 11010 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 11011 11012 TestCompletionCallback callback; 11013 HttpRequestInfo request1; 11014 request1.method = "GET"; 11015 request1.url = GURL("https://www.google.com/"); 11016 request1.load_flags = 0; 11017 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 11018 11019 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 11020 EXPECT_EQ(ERR_IO_PENDING, rv); 11021 EXPECT_EQ(OK, callback.WaitForResult()); 11022 11023 const HttpResponseInfo* response = trans1.GetResponseInfo(); 11024 ASSERT_TRUE(response != NULL); 11025 ASSERT_TRUE(response->headers.get() != NULL); 11026 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11027 11028 std::string response_data; 11029 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 11030 EXPECT_EQ("hello!", response_data); 11031 11032 // Preload www.gmail.com into HostCache. 11033 HostPortPair host_port("www.gmail.com", 443); 11034 HostResolver::RequestInfo resolve_info(host_port); 11035 AddressList ignored; 11036 rv = session_deps_.host_resolver->Resolve(resolve_info, 11037 DEFAULT_PRIORITY, 11038 &ignored, 11039 callback.callback(), 11040 NULL, 11041 BoundNetLog()); 11042 EXPECT_EQ(ERR_IO_PENDING, rv); 11043 rv = callback.WaitForResult(); 11044 EXPECT_EQ(OK, rv); 11045 11046 HttpRequestInfo request2; 11047 request2.method = "GET"; 11048 request2.url = GURL("https://www.gmail.com/"); 11049 request2.load_flags = 0; 11050 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 11051 11052 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 11053 EXPECT_EQ(ERR_IO_PENDING, rv); 11054 EXPECT_EQ(OK, callback.WaitForResult()); 11055 11056 response = trans2.GetResponseInfo(); 11057 ASSERT_TRUE(response != NULL); 11058 ASSERT_TRUE(response->headers.get() != NULL); 11059 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11060 EXPECT_TRUE(response->was_fetched_via_spdy); 11061 EXPECT_TRUE(response->was_npn_negotiated); 11062 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 11063 EXPECT_EQ("hello!", response_data); 11064 } 11065 #undef MAYBE_UseIPConnectionPooling 11066 11067 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) { 11068 session_deps_.use_alternate_protocols = true; 11069 session_deps_.next_protos = SpdyNextProtos(); 11070 11071 // Set up a special HttpNetworkSession with a MockCachingHostResolver. 11072 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 11073 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11074 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 11075 pool_peer.DisableDomainAuthenticationVerification(); 11076 11077 SSLSocketDataProvider ssl(ASYNC, OK); 11078 ssl.SetNextProto(GetParam()); 11079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11080 11081 scoped_ptr<SpdyFrame> host1_req( 11082 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 11083 scoped_ptr<SpdyFrame> host2_req( 11084 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 11085 MockWrite spdy_writes[] = { 11086 CreateMockWrite(*host1_req, 1), 11087 CreateMockWrite(*host2_req, 4), 11088 }; 11089 scoped_ptr<SpdyFrame> host1_resp( 11090 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11091 scoped_ptr<SpdyFrame> host1_resp_body( 11092 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11093 scoped_ptr<SpdyFrame> host2_resp( 11094 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11095 scoped_ptr<SpdyFrame> host2_resp_body( 11096 spdy_util_.ConstructSpdyBodyFrame(3, true)); 11097 MockRead spdy_reads[] = { 11098 CreateMockRead(*host1_resp, 2), 11099 CreateMockRead(*host1_resp_body, 3), 11100 CreateMockRead(*host2_resp, 5), 11101 CreateMockRead(*host2_resp_body, 6), 11102 MockRead(ASYNC, 0, 7), 11103 }; 11104 11105 IPAddressNumber ip; 11106 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 11107 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11108 MockConnect connect(ASYNC, OK, peer_addr); 11109 OrderedSocketData spdy_data( 11110 connect, 11111 spdy_reads, arraysize(spdy_reads), 11112 spdy_writes, arraysize(spdy_writes)); 11113 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 11114 11115 TestCompletionCallback callback; 11116 HttpRequestInfo request1; 11117 request1.method = "GET"; 11118 request1.url = GURL("https://www.google.com/"); 11119 request1.load_flags = 0; 11120 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 11121 11122 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 11123 EXPECT_EQ(ERR_IO_PENDING, rv); 11124 EXPECT_EQ(OK, callback.WaitForResult()); 11125 11126 const HttpResponseInfo* response = trans1.GetResponseInfo(); 11127 ASSERT_TRUE(response != NULL); 11128 ASSERT_TRUE(response->headers.get() != NULL); 11129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11130 11131 std::string response_data; 11132 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 11133 EXPECT_EQ("hello!", response_data); 11134 11135 HttpRequestInfo request2; 11136 request2.method = "GET"; 11137 request2.url = GURL("https://www.gmail.com/"); 11138 request2.load_flags = 0; 11139 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 11140 11141 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 11142 EXPECT_EQ(ERR_IO_PENDING, rv); 11143 EXPECT_EQ(OK, callback.WaitForResult()); 11144 11145 response = trans2.GetResponseInfo(); 11146 ASSERT_TRUE(response != NULL); 11147 ASSERT_TRUE(response->headers.get() != NULL); 11148 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11149 EXPECT_TRUE(response->was_fetched_via_spdy); 11150 EXPECT_TRUE(response->was_npn_negotiated); 11151 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 11152 EXPECT_EQ("hello!", response_data); 11153 } 11154 11155 class OneTimeCachingHostResolver : public net::HostResolver { 11156 public: 11157 explicit OneTimeCachingHostResolver(const HostPortPair& host_port) 11158 : host_port_(host_port) {} 11159 virtual ~OneTimeCachingHostResolver() {} 11160 11161 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); } 11162 11163 // HostResolver methods: 11164 virtual int Resolve(const RequestInfo& info, 11165 RequestPriority priority, 11166 AddressList* addresses, 11167 const CompletionCallback& callback, 11168 RequestHandle* out_req, 11169 const BoundNetLog& net_log) OVERRIDE { 11170 return host_resolver_.Resolve( 11171 info, priority, addresses, callback, out_req, net_log); 11172 } 11173 11174 virtual int ResolveFromCache(const RequestInfo& info, 11175 AddressList* addresses, 11176 const BoundNetLog& net_log) OVERRIDE { 11177 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log); 11178 if (rv == OK && info.host_port_pair().Equals(host_port_)) 11179 host_resolver_.GetHostCache()->clear(); 11180 return rv; 11181 } 11182 11183 virtual void CancelRequest(RequestHandle req) OVERRIDE { 11184 host_resolver_.CancelRequest(req); 11185 } 11186 11187 MockCachingHostResolver* GetMockHostResolver() { 11188 return &host_resolver_; 11189 } 11190 11191 private: 11192 MockCachingHostResolver host_resolver_; 11193 const HostPortPair host_port_; 11194 }; 11195 11196 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 11197 #if defined(OS_WIN) 11198 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \ 11199 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration 11200 #else 11201 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \ 11202 UseIPConnectionPoolingWithHostCacheExpiration 11203 #endif 11204 WRAPPED_TEST_P(HttpNetworkTransactionTest, 11205 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) { 11206 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_ 11207 // prefix doesn't work with parametrized tests). 11208 #if defined(OS_WIN) 11209 return; 11210 #else 11211 session_deps_.use_alternate_protocols = true; 11212 session_deps_.next_protos = SpdyNextProtos(); 11213 11214 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver. 11215 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443)); 11216 HttpNetworkSession::Params params = 11217 SpdySessionDependencies::CreateSessionParams(&session_deps_); 11218 params.host_resolver = &host_resolver; 11219 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11220 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 11221 pool_peer.DisableDomainAuthenticationVerification(); 11222 11223 SSLSocketDataProvider ssl(ASYNC, OK); 11224 ssl.SetNextProto(GetParam()); 11225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11226 11227 scoped_ptr<SpdyFrame> host1_req( 11228 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 11229 scoped_ptr<SpdyFrame> host2_req( 11230 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 11231 MockWrite spdy_writes[] = { 11232 CreateMockWrite(*host1_req, 1), 11233 CreateMockWrite(*host2_req, 4), 11234 }; 11235 scoped_ptr<SpdyFrame> host1_resp( 11236 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11237 scoped_ptr<SpdyFrame> host1_resp_body( 11238 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11239 scoped_ptr<SpdyFrame> host2_resp( 11240 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11241 scoped_ptr<SpdyFrame> host2_resp_body( 11242 spdy_util_.ConstructSpdyBodyFrame(3, true)); 11243 MockRead spdy_reads[] = { 11244 CreateMockRead(*host1_resp, 2), 11245 CreateMockRead(*host1_resp_body, 3), 11246 CreateMockRead(*host2_resp, 5), 11247 CreateMockRead(*host2_resp_body, 6), 11248 MockRead(ASYNC, 0, 7), 11249 }; 11250 11251 IPAddressNumber ip; 11252 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 11253 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11254 MockConnect connect(ASYNC, OK, peer_addr); 11255 OrderedSocketData spdy_data( 11256 connect, 11257 spdy_reads, arraysize(spdy_reads), 11258 spdy_writes, arraysize(spdy_writes)); 11259 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 11260 11261 TestCompletionCallback callback; 11262 HttpRequestInfo request1; 11263 request1.method = "GET"; 11264 request1.url = GURL("https://www.google.com/"); 11265 request1.load_flags = 0; 11266 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 11267 11268 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 11269 EXPECT_EQ(ERR_IO_PENDING, rv); 11270 EXPECT_EQ(OK, callback.WaitForResult()); 11271 11272 const HttpResponseInfo* response = trans1.GetResponseInfo(); 11273 ASSERT_TRUE(response != NULL); 11274 ASSERT_TRUE(response->headers.get() != NULL); 11275 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11276 11277 std::string response_data; 11278 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 11279 EXPECT_EQ("hello!", response_data); 11280 11281 // Preload cache entries into HostCache. 11282 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443)); 11283 AddressList ignored; 11284 rv = host_resolver.Resolve(resolve_info, 11285 DEFAULT_PRIORITY, 11286 &ignored, 11287 callback.callback(), 11288 NULL, 11289 BoundNetLog()); 11290 EXPECT_EQ(ERR_IO_PENDING, rv); 11291 rv = callback.WaitForResult(); 11292 EXPECT_EQ(OK, rv); 11293 11294 HttpRequestInfo request2; 11295 request2.method = "GET"; 11296 request2.url = GURL("https://www.gmail.com/"); 11297 request2.load_flags = 0; 11298 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 11299 11300 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 11301 EXPECT_EQ(ERR_IO_PENDING, rv); 11302 EXPECT_EQ(OK, callback.WaitForResult()); 11303 11304 response = trans2.GetResponseInfo(); 11305 ASSERT_TRUE(response != NULL); 11306 ASSERT_TRUE(response->headers.get() != NULL); 11307 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11308 EXPECT_TRUE(response->was_fetched_via_spdy); 11309 EXPECT_TRUE(response->was_npn_negotiated); 11310 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 11311 EXPECT_EQ("hello!", response_data); 11312 #endif 11313 } 11314 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration 11315 11316 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) { 11317 const std::string https_url = "https://www.google.com/"; 11318 const std::string http_url = "http://www.google.com:443/"; 11319 11320 // SPDY GET for HTTPS URL 11321 scoped_ptr<SpdyFrame> req1( 11322 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 11323 11324 MockWrite writes1[] = { 11325 CreateMockWrite(*req1, 0), 11326 }; 11327 11328 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11329 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11330 MockRead reads1[] = { 11331 CreateMockRead(*resp1, 1), 11332 CreateMockRead(*body1, 2), 11333 MockRead(ASYNC, ERR_IO_PENDING, 3) 11334 }; 11335 11336 DelayedSocketData data1( 11337 1, reads1, arraysize(reads1), 11338 writes1, arraysize(writes1)); 11339 MockConnect connect_data1(ASYNC, OK); 11340 data1.set_connect_data(connect_data1); 11341 11342 // HTTP GET for the HTTP URL 11343 MockWrite writes2[] = { 11344 MockWrite(ASYNC, 4, 11345 "GET / HTTP/1.1\r\n" 11346 "Host: www.google.com:443\r\n" 11347 "Connection: keep-alive\r\n\r\n"), 11348 }; 11349 11350 MockRead reads2[] = { 11351 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 11352 MockRead(ASYNC, 6, "hello"), 11353 MockRead(ASYNC, 7, OK), 11354 }; 11355 11356 DelayedSocketData data2( 11357 1, reads2, arraysize(reads2), 11358 writes2, arraysize(writes2)); 11359 11360 SSLSocketDataProvider ssl(ASYNC, OK); 11361 ssl.SetNextProto(GetParam()); 11362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11363 session_deps_.socket_factory->AddSocketDataProvider(&data1); 11364 session_deps_.socket_factory->AddSocketDataProvider(&data2); 11365 11366 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11367 11368 // Start the first transaction to set up the SpdySession 11369 HttpRequestInfo request1; 11370 request1.method = "GET"; 11371 request1.url = GURL(https_url); 11372 request1.load_flags = 0; 11373 HttpNetworkTransaction trans1(LOWEST, session.get()); 11374 TestCompletionCallback callback1; 11375 EXPECT_EQ(ERR_IO_PENDING, 11376 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11377 base::MessageLoop::current()->RunUntilIdle(); 11378 11379 EXPECT_EQ(OK, callback1.WaitForResult()); 11380 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11381 11382 // Now, start the HTTP request 11383 HttpRequestInfo request2; 11384 request2.method = "GET"; 11385 request2.url = GURL(http_url); 11386 request2.load_flags = 0; 11387 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11388 TestCompletionCallback callback2; 11389 EXPECT_EQ(ERR_IO_PENDING, 11390 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11391 base::MessageLoop::current()->RunUntilIdle(); 11392 11393 EXPECT_EQ(OK, callback2.WaitForResult()); 11394 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11395 } 11396 11397 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { 11398 const std::string https_url = "https://www.google.com/"; 11399 const std::string http_url = "http://www.google.com:443/"; 11400 11401 // SPDY GET for HTTPS URL (through CONNECT tunnel) 11402 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 11403 LOWEST)); 11404 scoped_ptr<SpdyFrame> req1( 11405 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 11406 scoped_ptr<SpdyFrame> wrapped_req1( 11407 spdy_util_.ConstructWrappedSpdyFrame(req1, 1)); 11408 11409 // SPDY GET for HTTP URL (through the proxy, but not the tunnel). 11410 SpdyHeaderBlock req2_block; 11411 req2_block[spdy_util_.GetMethodKey()] = "GET"; 11412 req2_block[spdy_util_.GetPathKey()] = 11413 spdy_util_.is_spdy2() ? http_url.c_str() : "/"; 11414 req2_block[spdy_util_.GetHostKey()] = "www.google.com:443"; 11415 req2_block[spdy_util_.GetSchemeKey()] = "http"; 11416 spdy_util_.MaybeAddVersionHeader(&req2_block); 11417 scoped_ptr<SpdyFrame> req2( 11418 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true)); 11419 11420 MockWrite writes1[] = { 11421 CreateMockWrite(*connect, 0), 11422 CreateMockWrite(*wrapped_req1, 2), 11423 CreateMockWrite(*req2, 5), 11424 }; 11425 11426 scoped_ptr<SpdyFrame> conn_resp( 11427 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11428 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11429 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11430 scoped_ptr<SpdyFrame> wrapped_resp1( 11431 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1)); 11432 scoped_ptr<SpdyFrame> wrapped_body1( 11433 spdy_util_.ConstructWrappedSpdyFrame(body1, 1)); 11434 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11435 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 11436 MockRead reads1[] = { 11437 CreateMockRead(*conn_resp, 1), 11438 CreateMockRead(*wrapped_resp1, 3), 11439 CreateMockRead(*wrapped_body1, 4), 11440 CreateMockRead(*resp2, 6), 11441 CreateMockRead(*body2, 7), 11442 MockRead(ASYNC, ERR_IO_PENDING, 8) 11443 }; 11444 11445 DeterministicSocketData data1(reads1, arraysize(reads1), 11446 writes1, arraysize(writes1)); 11447 MockConnect connect_data1(ASYNC, OK); 11448 data1.set_connect_data(connect_data1); 11449 11450 session_deps_.proxy_service.reset( 11451 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 11452 CapturingNetLog log; 11453 session_deps_.net_log = &log; 11454 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy 11455 ssl1.SetNextProto(GetParam()); 11456 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11457 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server 11458 ssl2.SetNextProto(GetParam()); 11459 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11460 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1); 11461 11462 scoped_refptr<HttpNetworkSession> session( 11463 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11464 11465 // Start the first transaction to set up the SpdySession 11466 HttpRequestInfo request1; 11467 request1.method = "GET"; 11468 request1.url = GURL(https_url); 11469 request1.load_flags = 0; 11470 HttpNetworkTransaction trans1(LOWEST, session.get()); 11471 TestCompletionCallback callback1; 11472 EXPECT_EQ(ERR_IO_PENDING, 11473 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11474 base::MessageLoop::current()->RunUntilIdle(); 11475 data1.RunFor(4); 11476 11477 EXPECT_EQ(OK, callback1.WaitForResult()); 11478 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11479 11480 LoadTimingInfo load_timing_info1; 11481 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1)); 11482 TestLoadTimingNotReusedWithPac(load_timing_info1, 11483 CONNECT_TIMING_HAS_SSL_TIMES); 11484 11485 // Now, start the HTTP request 11486 HttpRequestInfo request2; 11487 request2.method = "GET"; 11488 request2.url = GURL(http_url); 11489 request2.load_flags = 0; 11490 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11491 TestCompletionCallback callback2; 11492 EXPECT_EQ(ERR_IO_PENDING, 11493 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11494 base::MessageLoop::current()->RunUntilIdle(); 11495 data1.RunFor(3); 11496 11497 EXPECT_EQ(OK, callback2.WaitForResult()); 11498 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11499 11500 LoadTimingInfo load_timing_info2; 11501 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2)); 11502 // The established SPDY sessions is considered reused by the HTTP request. 11503 TestLoadTimingReusedWithPac(load_timing_info2); 11504 // HTTP requests over a SPDY session should have a different connection 11505 // socket_log_id than requests over a tunnel. 11506 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 11507 } 11508 11509 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) { 11510 session_deps_.force_spdy_always = true; 11511 const std::string https_url = "https://www.google.com/"; 11512 const std::string http_url = "http://www.google.com:443/"; 11513 11514 // SPDY GET for HTTPS URL 11515 scoped_ptr<SpdyFrame> req1( 11516 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 11517 // SPDY GET for the HTTP URL 11518 scoped_ptr<SpdyFrame> req2( 11519 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM)); 11520 11521 MockWrite writes[] = { 11522 CreateMockWrite(*req1, 1), 11523 CreateMockWrite(*req2, 4), 11524 }; 11525 11526 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11527 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11528 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11529 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 11530 MockRead reads[] = { 11531 CreateMockRead(*resp1, 2), 11532 CreateMockRead(*body1, 3), 11533 CreateMockRead(*resp2, 5), 11534 CreateMockRead(*body2, 6), 11535 MockRead(ASYNC, ERR_IO_PENDING, 7) 11536 }; 11537 11538 OrderedSocketData data(reads, arraysize(reads), 11539 writes, arraysize(writes)); 11540 11541 SSLSocketDataProvider ssl(ASYNC, OK); 11542 ssl.SetNextProto(GetParam()); 11543 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11544 session_deps_.socket_factory->AddSocketDataProvider(&data); 11545 11546 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11547 11548 // Start the first transaction to set up the SpdySession 11549 HttpRequestInfo request1; 11550 request1.method = "GET"; 11551 request1.url = GURL(https_url); 11552 request1.load_flags = 0; 11553 HttpNetworkTransaction trans1(LOWEST, session.get()); 11554 TestCompletionCallback callback1; 11555 EXPECT_EQ(ERR_IO_PENDING, 11556 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11557 base::MessageLoop::current()->RunUntilIdle(); 11558 11559 EXPECT_EQ(OK, callback1.WaitForResult()); 11560 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11561 11562 // Now, start the HTTP request 11563 HttpRequestInfo request2; 11564 request2.method = "GET"; 11565 request2.url = GURL(http_url); 11566 request2.load_flags = 0; 11567 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11568 TestCompletionCallback callback2; 11569 EXPECT_EQ(ERR_IO_PENDING, 11570 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11571 base::MessageLoop::current()->RunUntilIdle(); 11572 11573 EXPECT_EQ(OK, callback2.WaitForResult()); 11574 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11575 } 11576 11577 // Test that in the case where we have a SPDY session to a SPDY proxy 11578 // that we do not pool other origins that resolve to the same IP when 11579 // the certificate does not match the new origin. 11580 // http://crbug.com/134690 11581 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) { 11582 const std::string url1 = "http://www.google.com/"; 11583 const std::string url2 = "https://mail.google.com/"; 11584 const std::string ip_addr = "1.2.3.4"; 11585 11586 // SPDY GET for HTTP URL (through SPDY proxy) 11587 scoped_ptr<SpdyHeaderBlock> headers( 11588 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/")); 11589 scoped_ptr<SpdyFrame> req1( 11590 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true)); 11591 11592 MockWrite writes1[] = { 11593 CreateMockWrite(*req1, 0), 11594 }; 11595 11596 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11597 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11598 MockRead reads1[] = { 11599 CreateMockRead(*resp1, 1), 11600 CreateMockRead(*body1, 2), 11601 MockRead(ASYNC, OK, 3) // EOF 11602 }; 11603 11604 scoped_ptr<DeterministicSocketData> data1( 11605 new DeterministicSocketData(reads1, arraysize(reads1), 11606 writes1, arraysize(writes1))); 11607 IPAddressNumber ip; 11608 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip)); 11609 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11610 MockConnect connect_data1(ASYNC, OK, peer_addr); 11611 data1->set_connect_data(connect_data1); 11612 11613 // SPDY GET for HTTPS URL (direct) 11614 scoped_ptr<SpdyFrame> req2( 11615 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM)); 11616 11617 MockWrite writes2[] = { 11618 CreateMockWrite(*req2, 0), 11619 }; 11620 11621 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11622 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11623 MockRead reads2[] = { 11624 CreateMockRead(*resp2, 1), 11625 CreateMockRead(*body2, 2), 11626 MockRead(ASYNC, OK, 3) // EOF 11627 }; 11628 11629 scoped_ptr<DeterministicSocketData> data2( 11630 new DeterministicSocketData(reads2, arraysize(reads2), 11631 writes2, arraysize(writes2))); 11632 MockConnect connect_data2(ASYNC, OK); 11633 data2->set_connect_data(connect_data2); 11634 11635 // Set up a proxy config that sends HTTP requests to a proxy, and 11636 // all others direct. 11637 ProxyConfig proxy_config; 11638 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443"); 11639 CapturingProxyResolver* capturing_proxy_resolver = 11640 new CapturingProxyResolver(); 11641 session_deps_.proxy_service.reset(new ProxyService( 11642 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver, 11643 NULL)); 11644 11645 // Load a valid cert. Note, that this does not need to 11646 // be valid for proxy because the MockSSLClientSocket does 11647 // not actually verify it. But SpdySession will use this 11648 // to see if it is valid for the new origin 11649 base::FilePath certs_dir = GetTestCertsDirectory(); 11650 scoped_refptr<X509Certificate> server_cert( 11651 ImportCertFromFile(certs_dir, "ok_cert.pem")); 11652 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get()); 11653 11654 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy 11655 ssl1.SetNextProto(GetParam()); 11656 ssl1.cert = server_cert; 11657 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11658 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11659 data1.get()); 11660 11661 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server 11662 ssl2.SetNextProto(GetParam()); 11663 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11664 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11665 data2.get()); 11666 11667 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 11668 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr); 11669 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr); 11670 11671 scoped_refptr<HttpNetworkSession> session( 11672 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11673 11674 // Start the first transaction to set up the SpdySession 11675 HttpRequestInfo request1; 11676 request1.method = "GET"; 11677 request1.url = GURL(url1); 11678 request1.load_flags = 0; 11679 HttpNetworkTransaction trans1(LOWEST, session.get()); 11680 TestCompletionCallback callback1; 11681 ASSERT_EQ(ERR_IO_PENDING, 11682 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11683 data1->RunFor(3); 11684 11685 ASSERT_TRUE(callback1.have_result()); 11686 EXPECT_EQ(OK, callback1.WaitForResult()); 11687 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11688 11689 // Now, start the HTTP request 11690 HttpRequestInfo request2; 11691 request2.method = "GET"; 11692 request2.url = GURL(url2); 11693 request2.load_flags = 0; 11694 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11695 TestCompletionCallback callback2; 11696 EXPECT_EQ(ERR_IO_PENDING, 11697 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11698 base::MessageLoop::current()->RunUntilIdle(); 11699 data2->RunFor(3); 11700 11701 ASSERT_TRUE(callback2.have_result()); 11702 EXPECT_EQ(OK, callback2.WaitForResult()); 11703 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11704 } 11705 11706 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED 11707 // error) in SPDY session, removes the socket from pool and closes the SPDY 11708 // session. Verify that new url's from the same HttpNetworkSession (and a new 11709 // SpdySession) do work. http://crbug.com/224701 11710 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) { 11711 const std::string https_url = "https://www.google.com/"; 11712 11713 MockRead reads1[] = { 11714 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0) 11715 }; 11716 11717 scoped_ptr<DeterministicSocketData> data1( 11718 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0)); 11719 data1->SetStop(1); 11720 11721 scoped_ptr<SpdyFrame> req2( 11722 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM)); 11723 MockWrite writes2[] = { 11724 CreateMockWrite(*req2, 0), 11725 }; 11726 11727 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11728 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11729 MockRead reads2[] = { 11730 CreateMockRead(*resp2, 1), 11731 CreateMockRead(*body2, 2), 11732 MockRead(ASYNC, OK, 3) // EOF 11733 }; 11734 11735 scoped_ptr<DeterministicSocketData> data2( 11736 new DeterministicSocketData(reads2, arraysize(reads2), 11737 writes2, arraysize(writes2))); 11738 11739 SSLSocketDataProvider ssl1(ASYNC, OK); 11740 ssl1.SetNextProto(GetParam()); 11741 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11742 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11743 data1.get()); 11744 11745 SSLSocketDataProvider ssl2(ASYNC, OK); 11746 ssl2.SetNextProto(GetParam()); 11747 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11748 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11749 data2.get()); 11750 11751 scoped_refptr<HttpNetworkSession> session( 11752 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11753 11754 // Start the first transaction to set up the SpdySession and verify that 11755 // connection was closed. 11756 HttpRequestInfo request1; 11757 request1.method = "GET"; 11758 request1.url = GURL(https_url); 11759 request1.load_flags = 0; 11760 HttpNetworkTransaction trans1(MEDIUM, session.get()); 11761 TestCompletionCallback callback1; 11762 EXPECT_EQ(ERR_IO_PENDING, 11763 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11764 base::MessageLoop::current()->RunUntilIdle(); 11765 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult()); 11766 11767 // Now, start the second request and make sure it succeeds. 11768 HttpRequestInfo request2; 11769 request2.method = "GET"; 11770 request2.url = GURL(https_url); 11771 request2.load_flags = 0; 11772 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11773 TestCompletionCallback callback2; 11774 EXPECT_EQ(ERR_IO_PENDING, 11775 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11776 base::MessageLoop::current()->RunUntilIdle(); 11777 data2->RunFor(3); 11778 11779 ASSERT_TRUE(callback2.have_result()); 11780 EXPECT_EQ(OK, callback2.WaitForResult()); 11781 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11782 } 11783 11784 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) { 11785 session_deps_.next_protos = SpdyNextProtos(); 11786 ClientSocketPoolManager::set_max_sockets_per_group( 11787 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 11788 ClientSocketPoolManager::set_max_sockets_per_pool( 11789 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 11790 11791 // Use two different hosts with different IPs so they don't get pooled. 11792 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1"); 11793 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2"); 11794 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11795 11796 SSLSocketDataProvider ssl1(ASYNC, OK); 11797 ssl1.SetNextProto(GetParam()); 11798 SSLSocketDataProvider ssl2(ASYNC, OK); 11799 ssl2.SetNextProto(GetParam()); 11800 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); 11801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 11802 11803 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet( 11804 "https://www.a.com", false, 1, DEFAULT_PRIORITY)); 11805 MockWrite spdy1_writes[] = { 11806 CreateMockWrite(*host1_req, 1), 11807 }; 11808 scoped_ptr<SpdyFrame> host1_resp( 11809 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11810 scoped_ptr<SpdyFrame> host1_resp_body( 11811 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11812 MockRead spdy1_reads[] = { 11813 CreateMockRead(*host1_resp, 2), 11814 CreateMockRead(*host1_resp_body, 3), 11815 MockRead(ASYNC, ERR_IO_PENDING, 4), 11816 }; 11817 11818 scoped_ptr<OrderedSocketData> spdy1_data( 11819 new OrderedSocketData( 11820 spdy1_reads, arraysize(spdy1_reads), 11821 spdy1_writes, arraysize(spdy1_writes))); 11822 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get()); 11823 11824 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet( 11825 "https://www.b.com", false, 1, DEFAULT_PRIORITY)); 11826 MockWrite spdy2_writes[] = { 11827 CreateMockWrite(*host2_req, 1), 11828 }; 11829 scoped_ptr<SpdyFrame> host2_resp( 11830 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11831 scoped_ptr<SpdyFrame> host2_resp_body( 11832 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11833 MockRead spdy2_reads[] = { 11834 CreateMockRead(*host2_resp, 2), 11835 CreateMockRead(*host2_resp_body, 3), 11836 MockRead(ASYNC, ERR_IO_PENDING, 4), 11837 }; 11838 11839 scoped_ptr<OrderedSocketData> spdy2_data( 11840 new OrderedSocketData( 11841 spdy2_reads, arraysize(spdy2_reads), 11842 spdy2_writes, arraysize(spdy2_writes))); 11843 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get()); 11844 11845 MockWrite http_write[] = { 11846 MockWrite("GET / HTTP/1.1\r\n" 11847 "Host: www.a.com\r\n" 11848 "Connection: keep-alive\r\n\r\n"), 11849 }; 11850 11851 MockRead http_read[] = { 11852 MockRead("HTTP/1.1 200 OK\r\n"), 11853 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 11854 MockRead("Content-Length: 6\r\n\r\n"), 11855 MockRead("hello!"), 11856 }; 11857 StaticSocketDataProvider http_data(http_read, arraysize(http_read), 11858 http_write, arraysize(http_write)); 11859 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 11860 11861 HostPortPair host_port_pair_a("www.a.com", 443); 11862 SpdySessionKey spdy_session_key_a( 11863 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 11864 EXPECT_FALSE( 11865 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11866 11867 TestCompletionCallback callback; 11868 HttpRequestInfo request1; 11869 request1.method = "GET"; 11870 request1.url = GURL("https://www.a.com/"); 11871 request1.load_flags = 0; 11872 scoped_ptr<HttpNetworkTransaction> trans( 11873 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11874 11875 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 11876 EXPECT_EQ(ERR_IO_PENDING, rv); 11877 EXPECT_EQ(OK, callback.WaitForResult()); 11878 11879 const HttpResponseInfo* response = trans->GetResponseInfo(); 11880 ASSERT_TRUE(response != NULL); 11881 ASSERT_TRUE(response->headers.get() != NULL); 11882 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11883 EXPECT_TRUE(response->was_fetched_via_spdy); 11884 EXPECT_TRUE(response->was_npn_negotiated); 11885 11886 std::string response_data; 11887 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11888 EXPECT_EQ("hello!", response_data); 11889 trans.reset(); 11890 EXPECT_TRUE( 11891 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11892 11893 HostPortPair host_port_pair_b("www.b.com", 443); 11894 SpdySessionKey spdy_session_key_b( 11895 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 11896 EXPECT_FALSE( 11897 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11898 HttpRequestInfo request2; 11899 request2.method = "GET"; 11900 request2.url = GURL("https://www.b.com/"); 11901 request2.load_flags = 0; 11902 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11903 11904 rv = trans->Start(&request2, callback.callback(), BoundNetLog()); 11905 EXPECT_EQ(ERR_IO_PENDING, rv); 11906 EXPECT_EQ(OK, callback.WaitForResult()); 11907 11908 response = trans->GetResponseInfo(); 11909 ASSERT_TRUE(response != NULL); 11910 ASSERT_TRUE(response->headers.get() != NULL); 11911 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11912 EXPECT_TRUE(response->was_fetched_via_spdy); 11913 EXPECT_TRUE(response->was_npn_negotiated); 11914 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11915 EXPECT_EQ("hello!", response_data); 11916 EXPECT_FALSE( 11917 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11918 EXPECT_TRUE( 11919 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11920 11921 HostPortPair host_port_pair_a1("www.a.com", 80); 11922 SpdySessionKey spdy_session_key_a1( 11923 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 11924 EXPECT_FALSE( 11925 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1)); 11926 HttpRequestInfo request3; 11927 request3.method = "GET"; 11928 request3.url = GURL("http://www.a.com/"); 11929 request3.load_flags = 0; 11930 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11931 11932 rv = trans->Start(&request3, callback.callback(), BoundNetLog()); 11933 EXPECT_EQ(ERR_IO_PENDING, rv); 11934 EXPECT_EQ(OK, callback.WaitForResult()); 11935 11936 response = trans->GetResponseInfo(); 11937 ASSERT_TRUE(response != NULL); 11938 ASSERT_TRUE(response->headers.get() != NULL); 11939 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11940 EXPECT_FALSE(response->was_fetched_via_spdy); 11941 EXPECT_FALSE(response->was_npn_negotiated); 11942 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11943 EXPECT_EQ("hello!", response_data); 11944 EXPECT_FALSE( 11945 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11946 EXPECT_FALSE( 11947 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11948 } 11949 11950 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) { 11951 HttpRequestInfo request; 11952 request.method = "GET"; 11953 request.url = GURL("http://www.google.com/"); 11954 request.load_flags = 0; 11955 11956 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11957 scoped_ptr<HttpTransaction> trans( 11958 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11959 11960 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED); 11961 StaticSocketDataProvider data; 11962 data.set_connect_data(mock_connect); 11963 session_deps_.socket_factory->AddSocketDataProvider(&data); 11964 11965 TestCompletionCallback callback; 11966 11967 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11968 EXPECT_EQ(ERR_IO_PENDING, rv); 11969 11970 rv = callback.WaitForResult(); 11971 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); 11972 11973 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11974 11975 // We don't care whether this succeeds or fails, but it shouldn't crash. 11976 HttpRequestHeaders request_headers; 11977 trans->GetFullRequestHeaders(&request_headers); 11978 } 11979 11980 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) { 11981 HttpRequestInfo request; 11982 request.method = "GET"; 11983 request.url = GURL("http://www.google.com/"); 11984 request.load_flags = 0; 11985 11986 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11987 scoped_ptr<HttpTransaction> trans( 11988 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11989 11990 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 11991 StaticSocketDataProvider data; 11992 data.set_connect_data(mock_connect); 11993 session_deps_.socket_factory->AddSocketDataProvider(&data); 11994 11995 TestCompletionCallback callback; 11996 11997 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11998 EXPECT_EQ(ERR_IO_PENDING, rv); 11999 12000 rv = callback.WaitForResult(); 12001 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); 12002 12003 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12004 12005 // We don't care whether this succeeds or fails, but it shouldn't crash. 12006 HttpRequestHeaders request_headers; 12007 trans->GetFullRequestHeaders(&request_headers); 12008 } 12009 12010 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) { 12011 HttpRequestInfo request; 12012 request.method = "GET"; 12013 request.url = GURL("http://www.google.com/"); 12014 request.load_flags = 0; 12015 12016 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12017 scoped_ptr<HttpTransaction> trans( 12018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12019 12020 MockWrite data_writes[] = { 12021 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12022 }; 12023 MockRead data_reads[] = { 12024 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 12025 }; 12026 12027 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12028 data_writes, arraysize(data_writes)); 12029 session_deps_.socket_factory->AddSocketDataProvider(&data); 12030 12031 TestCompletionCallback callback; 12032 12033 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12034 EXPECT_EQ(ERR_IO_PENDING, rv); 12035 12036 rv = callback.WaitForResult(); 12037 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12038 12039 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12040 12041 HttpRequestHeaders request_headers; 12042 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12043 EXPECT_TRUE(request_headers.HasHeader("Host")); 12044 } 12045 12046 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) { 12047 HttpRequestInfo request; 12048 request.method = "GET"; 12049 request.url = GURL("http://www.google.com/"); 12050 request.load_flags = 0; 12051 12052 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12053 scoped_ptr<HttpTransaction> trans( 12054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12055 12056 MockWrite data_writes[] = { 12057 MockWrite(ASYNC, ERR_CONNECTION_RESET), 12058 }; 12059 MockRead data_reads[] = { 12060 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 12061 }; 12062 12063 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12064 data_writes, arraysize(data_writes)); 12065 session_deps_.socket_factory->AddSocketDataProvider(&data); 12066 12067 TestCompletionCallback callback; 12068 12069 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12070 EXPECT_EQ(ERR_IO_PENDING, rv); 12071 12072 rv = callback.WaitForResult(); 12073 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12074 12075 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12076 12077 HttpRequestHeaders request_headers; 12078 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12079 EXPECT_TRUE(request_headers.HasHeader("Host")); 12080 } 12081 12082 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) { 12083 HttpRequestInfo request; 12084 request.method = "GET"; 12085 request.url = GURL("http://www.google.com/"); 12086 request.load_flags = 0; 12087 12088 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12089 scoped_ptr<HttpTransaction> trans( 12090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12091 12092 MockWrite data_writes[] = { 12093 MockWrite("GET / HTTP/1.1\r\n" 12094 "Host: www.google.com\r\n" 12095 "Connection: keep-alive\r\n\r\n"), 12096 }; 12097 MockRead data_reads[] = { 12098 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET), 12099 }; 12100 12101 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12102 data_writes, arraysize(data_writes)); 12103 session_deps_.socket_factory->AddSocketDataProvider(&data); 12104 12105 TestCompletionCallback callback; 12106 12107 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12108 EXPECT_EQ(ERR_IO_PENDING, rv); 12109 12110 rv = callback.WaitForResult(); 12111 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12112 12113 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12114 12115 HttpRequestHeaders request_headers; 12116 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12117 EXPECT_TRUE(request_headers.HasHeader("Host")); 12118 } 12119 12120 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) { 12121 HttpRequestInfo request; 12122 request.method = "GET"; 12123 request.url = GURL("http://www.google.com/"); 12124 request.load_flags = 0; 12125 12126 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12127 scoped_ptr<HttpTransaction> trans( 12128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12129 12130 MockWrite data_writes[] = { 12131 MockWrite("GET / HTTP/1.1\r\n" 12132 "Host: www.google.com\r\n" 12133 "Connection: keep-alive\r\n\r\n"), 12134 }; 12135 MockRead data_reads[] = { 12136 MockRead(ASYNC, ERR_CONNECTION_RESET), 12137 }; 12138 12139 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12140 data_writes, arraysize(data_writes)); 12141 session_deps_.socket_factory->AddSocketDataProvider(&data); 12142 12143 TestCompletionCallback callback; 12144 12145 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12146 EXPECT_EQ(ERR_IO_PENDING, rv); 12147 12148 rv = callback.WaitForResult(); 12149 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12150 12151 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12152 12153 HttpRequestHeaders request_headers; 12154 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12155 EXPECT_TRUE(request_headers.HasHeader("Host")); 12156 } 12157 12158 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) { 12159 HttpRequestInfo request; 12160 request.method = "GET"; 12161 request.url = GURL("http://www.google.com/"); 12162 request.load_flags = 0; 12163 request.extra_headers.SetHeader("X-Foo", "bar"); 12164 12165 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12166 scoped_ptr<HttpTransaction> trans( 12167 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12168 12169 MockWrite data_writes[] = { 12170 MockWrite("GET / HTTP/1.1\r\n" 12171 "Host: www.google.com\r\n" 12172 "Connection: keep-alive\r\n" 12173 "X-Foo: bar\r\n\r\n"), 12174 }; 12175 MockRead data_reads[] = { 12176 MockRead("HTTP/1.1 200 OK\r\n" 12177 "Content-Length: 5\r\n\r\n" 12178 "hello"), 12179 MockRead(ASYNC, ERR_UNEXPECTED), 12180 }; 12181 12182 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12183 data_writes, arraysize(data_writes)); 12184 session_deps_.socket_factory->AddSocketDataProvider(&data); 12185 12186 TestCompletionCallback callback; 12187 12188 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12189 EXPECT_EQ(ERR_IO_PENDING, rv); 12190 12191 rv = callback.WaitForResult(); 12192 EXPECT_EQ(OK, rv); 12193 12194 HttpRequestHeaders request_headers; 12195 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12196 std::string foo; 12197 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo)); 12198 EXPECT_EQ("bar", foo); 12199 } 12200 12201 namespace { 12202 12203 // Fake HttpStreamBase that simply records calls to SetPriority(). 12204 class FakeStream : public HttpStreamBase, 12205 public base::SupportsWeakPtr<FakeStream> { 12206 public: 12207 explicit FakeStream(RequestPriority priority) : priority_(priority) {} 12208 virtual ~FakeStream() {} 12209 12210 RequestPriority priority() const { return priority_; } 12211 12212 virtual int InitializeStream(const HttpRequestInfo* request_info, 12213 RequestPriority priority, 12214 const BoundNetLog& net_log, 12215 const CompletionCallback& callback) OVERRIDE { 12216 return ERR_IO_PENDING; 12217 } 12218 12219 virtual int SendRequest(const HttpRequestHeaders& request_headers, 12220 HttpResponseInfo* response, 12221 const CompletionCallback& callback) OVERRIDE { 12222 ADD_FAILURE(); 12223 return ERR_UNEXPECTED; 12224 } 12225 12226 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE { 12227 ADD_FAILURE(); 12228 return ERR_UNEXPECTED; 12229 } 12230 12231 virtual int ReadResponseBody(IOBuffer* buf, int buf_len, 12232 const CompletionCallback& callback) OVERRIDE { 12233 ADD_FAILURE(); 12234 return ERR_UNEXPECTED; 12235 } 12236 12237 virtual void Close(bool not_reusable) OVERRIDE {} 12238 12239 virtual bool IsResponseBodyComplete() const OVERRIDE { 12240 ADD_FAILURE(); 12241 return false; 12242 } 12243 12244 virtual bool CanFindEndOfResponse() const OVERRIDE { 12245 return false; 12246 } 12247 12248 virtual bool IsConnectionReused() const OVERRIDE { 12249 ADD_FAILURE(); 12250 return false; 12251 } 12252 12253 virtual void SetConnectionReused() OVERRIDE { 12254 ADD_FAILURE(); 12255 } 12256 12257 virtual bool IsConnectionReusable() const OVERRIDE { 12258 ADD_FAILURE(); 12259 return false; 12260 } 12261 12262 virtual int64 GetTotalReceivedBytes() const OVERRIDE { 12263 ADD_FAILURE(); 12264 return 0; 12265 } 12266 12267 virtual bool GetLoadTimingInfo( 12268 LoadTimingInfo* load_timing_info) const OVERRIDE { 12269 ADD_FAILURE(); 12270 return false; 12271 } 12272 12273 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { 12274 ADD_FAILURE(); 12275 } 12276 12277 virtual void GetSSLCertRequestInfo( 12278 SSLCertRequestInfo* cert_request_info) OVERRIDE { 12279 ADD_FAILURE(); 12280 } 12281 12282 virtual bool IsSpdyHttpStream() const OVERRIDE { 12283 ADD_FAILURE(); 12284 return false; 12285 } 12286 12287 virtual void Drain(HttpNetworkSession* session) OVERRIDE { 12288 ADD_FAILURE(); 12289 } 12290 12291 virtual void SetPriority(RequestPriority priority) OVERRIDE { 12292 priority_ = priority; 12293 } 12294 12295 private: 12296 RequestPriority priority_; 12297 12298 DISALLOW_COPY_AND_ASSIGN(FakeStream); 12299 }; 12300 12301 // Fake HttpStreamRequest that simply records calls to SetPriority() 12302 // and vends FakeStreams with its current priority. 12303 class FakeStreamRequest : public HttpStreamRequest, 12304 public base::SupportsWeakPtr<FakeStreamRequest> { 12305 public: 12306 FakeStreamRequest(RequestPriority priority, 12307 HttpStreamRequest::Delegate* delegate) 12308 : priority_(priority), 12309 delegate_(delegate), 12310 websocket_stream_create_helper_(NULL) {} 12311 12312 FakeStreamRequest(RequestPriority priority, 12313 HttpStreamRequest::Delegate* delegate, 12314 WebSocketHandshakeStreamBase::CreateHelper* create_helper) 12315 : priority_(priority), 12316 delegate_(delegate), 12317 websocket_stream_create_helper_(create_helper) {} 12318 12319 virtual ~FakeStreamRequest() {} 12320 12321 RequestPriority priority() const { return priority_; } 12322 12323 const WebSocketHandshakeStreamBase::CreateHelper* 12324 websocket_stream_create_helper() const { 12325 return websocket_stream_create_helper_; 12326 } 12327 12328 // Create a new FakeStream and pass it to the request's 12329 // delegate. Returns a weak pointer to the FakeStream. 12330 base::WeakPtr<FakeStream> FinishStreamRequest() { 12331 FakeStream* fake_stream = new FakeStream(priority_); 12332 // Do this before calling OnStreamReady() as OnStreamReady() may 12333 // immediately delete |fake_stream|. 12334 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr(); 12335 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream); 12336 return weak_stream; 12337 } 12338 12339 virtual int RestartTunnelWithProxyAuth( 12340 const AuthCredentials& credentials) OVERRIDE { 12341 ADD_FAILURE(); 12342 return ERR_UNEXPECTED; 12343 } 12344 12345 virtual LoadState GetLoadState() const OVERRIDE { 12346 ADD_FAILURE(); 12347 return LoadState(); 12348 } 12349 12350 virtual void SetPriority(RequestPriority priority) OVERRIDE { 12351 priority_ = priority; 12352 } 12353 12354 virtual bool was_npn_negotiated() const OVERRIDE { 12355 return false; 12356 } 12357 12358 virtual NextProto protocol_negotiated() const OVERRIDE { 12359 return kProtoUnknown; 12360 } 12361 12362 virtual bool using_spdy() const OVERRIDE { 12363 return false; 12364 } 12365 12366 private: 12367 RequestPriority priority_; 12368 HttpStreamRequest::Delegate* const delegate_; 12369 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_; 12370 12371 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest); 12372 }; 12373 12374 // Fake HttpStreamFactory that vends FakeStreamRequests. 12375 class FakeStreamFactory : public HttpStreamFactory { 12376 public: 12377 FakeStreamFactory() {} 12378 virtual ~FakeStreamFactory() {} 12379 12380 // Returns a WeakPtr<> to the last HttpStreamRequest returned by 12381 // RequestStream() (which may be NULL if it was destroyed already). 12382 base::WeakPtr<FakeStreamRequest> last_stream_request() { 12383 return last_stream_request_; 12384 } 12385 12386 virtual HttpStreamRequest* RequestStream( 12387 const HttpRequestInfo& info, 12388 RequestPriority priority, 12389 const SSLConfig& server_ssl_config, 12390 const SSLConfig& proxy_ssl_config, 12391 HttpStreamRequest::Delegate* delegate, 12392 const BoundNetLog& net_log) OVERRIDE { 12393 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate); 12394 last_stream_request_ = fake_request->AsWeakPtr(); 12395 return fake_request; 12396 } 12397 12398 virtual HttpStreamRequest* RequestWebSocketHandshakeStream( 12399 const HttpRequestInfo& info, 12400 RequestPriority priority, 12401 const SSLConfig& server_ssl_config, 12402 const SSLConfig& proxy_ssl_config, 12403 HttpStreamRequest::Delegate* delegate, 12404 WebSocketHandshakeStreamBase::CreateHelper* create_helper, 12405 const BoundNetLog& net_log) OVERRIDE { 12406 FakeStreamRequest* fake_request = 12407 new FakeStreamRequest(priority, delegate, create_helper); 12408 last_stream_request_ = fake_request->AsWeakPtr(); 12409 return fake_request; 12410 } 12411 12412 virtual void PreconnectStreams(int num_streams, 12413 const HttpRequestInfo& info, 12414 RequestPriority priority, 12415 const SSLConfig& server_ssl_config, 12416 const SSLConfig& proxy_ssl_config) OVERRIDE { 12417 ADD_FAILURE(); 12418 } 12419 12420 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE { 12421 ADD_FAILURE(); 12422 return NULL; 12423 } 12424 12425 private: 12426 base::WeakPtr<FakeStreamRequest> last_stream_request_; 12427 12428 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory); 12429 }; 12430 12431 // TODO(yhirano): Split this class out into a net/websockets file, if it is 12432 // worth doing. 12433 class FakeWebSocketStreamCreateHelper : 12434 public WebSocketHandshakeStreamBase::CreateHelper { 12435 public: 12436 virtual WebSocketHandshakeStreamBase* CreateBasicStream( 12437 scoped_ptr<ClientSocketHandle> connection, 12438 bool using_proxy) OVERRIDE { 12439 NOTREACHED(); 12440 return NULL; 12441 } 12442 12443 virtual WebSocketHandshakeStreamBase* CreateSpdyStream( 12444 const base::WeakPtr<SpdySession>& session, 12445 bool use_relative_url) OVERRIDE { 12446 NOTREACHED(); 12447 return NULL; 12448 }; 12449 12450 virtual ~FakeWebSocketStreamCreateHelper() {} 12451 12452 virtual scoped_ptr<WebSocketStream> Upgrade() { 12453 NOTREACHED(); 12454 return scoped_ptr<WebSocketStream>(); 12455 } 12456 }; 12457 12458 } // namespace 12459 12460 // Make sure that HttpNetworkTransaction passes on its priority to its 12461 // stream request on start. 12462 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) { 12463 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12464 HttpNetworkSessionPeer peer(session); 12465 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12466 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12467 12468 HttpNetworkTransaction trans(LOW, session.get()); 12469 12470 ASSERT_TRUE(fake_factory->last_stream_request() == NULL); 12471 12472 HttpRequestInfo request; 12473 TestCompletionCallback callback; 12474 EXPECT_EQ(ERR_IO_PENDING, 12475 trans.Start(&request, callback.callback(), BoundNetLog())); 12476 12477 base::WeakPtr<FakeStreamRequest> fake_request = 12478 fake_factory->last_stream_request(); 12479 ASSERT_TRUE(fake_request != NULL); 12480 EXPECT_EQ(LOW, fake_request->priority()); 12481 } 12482 12483 // Make sure that HttpNetworkTransaction passes on its priority 12484 // updates to its stream request. 12485 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) { 12486 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12487 HttpNetworkSessionPeer peer(session); 12488 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12489 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12490 12491 HttpNetworkTransaction trans(LOW, session.get()); 12492 12493 HttpRequestInfo request; 12494 TestCompletionCallback callback; 12495 EXPECT_EQ(ERR_IO_PENDING, 12496 trans.Start(&request, callback.callback(), BoundNetLog())); 12497 12498 base::WeakPtr<FakeStreamRequest> fake_request = 12499 fake_factory->last_stream_request(); 12500 ASSERT_TRUE(fake_request != NULL); 12501 EXPECT_EQ(LOW, fake_request->priority()); 12502 12503 trans.SetPriority(LOWEST); 12504 ASSERT_TRUE(fake_request != NULL); 12505 EXPECT_EQ(LOWEST, fake_request->priority()); 12506 } 12507 12508 // Make sure that HttpNetworkTransaction passes on its priority 12509 // updates to its stream. 12510 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) { 12511 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12512 HttpNetworkSessionPeer peer(session); 12513 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12514 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12515 12516 HttpNetworkTransaction trans(LOW, session.get()); 12517 12518 HttpRequestInfo request; 12519 TestCompletionCallback callback; 12520 EXPECT_EQ(ERR_IO_PENDING, 12521 trans.Start(&request, callback.callback(), BoundNetLog())); 12522 12523 base::WeakPtr<FakeStreamRequest> fake_request = 12524 fake_factory->last_stream_request(); 12525 ASSERT_TRUE(fake_request != NULL); 12526 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest(); 12527 ASSERT_TRUE(fake_stream != NULL); 12528 EXPECT_EQ(LOW, fake_stream->priority()); 12529 12530 trans.SetPriority(LOWEST); 12531 EXPECT_EQ(LOWEST, fake_stream->priority()); 12532 } 12533 12534 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) { 12535 // The same logic needs to be tested for both ws: and wss: schemes, but this 12536 // test is already parameterised on NextProto, so it uses a loop to verify 12537 // that the different schemes work. 12538 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"}; 12539 for (size_t i = 0; i < arraysize(test_cases); ++i) { 12540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12541 HttpNetworkSessionPeer peer(session); 12542 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12543 FakeWebSocketStreamCreateHelper websocket_stream_create_helper; 12544 peer.SetHttpStreamFactoryForWebSocket( 12545 scoped_ptr<HttpStreamFactory>(fake_factory)); 12546 12547 HttpNetworkTransaction trans(LOW, session.get()); 12548 trans.SetWebSocketHandshakeStreamCreateHelper( 12549 &websocket_stream_create_helper); 12550 12551 HttpRequestInfo request; 12552 TestCompletionCallback callback; 12553 request.method = "GET"; 12554 request.url = GURL(test_cases[i]); 12555 12556 EXPECT_EQ(ERR_IO_PENDING, 12557 trans.Start(&request, callback.callback(), BoundNetLog())); 12558 12559 base::WeakPtr<FakeStreamRequest> fake_request = 12560 fake_factory->last_stream_request(); 12561 ASSERT_TRUE(fake_request != NULL); 12562 EXPECT_EQ(&websocket_stream_create_helper, 12563 fake_request->websocket_stream_create_helper()); 12564 } 12565 } 12566 12567 // Tests that when a used socket is returned to the SSL socket pool, it's closed 12568 // if the transport socket pool is stalled on the global socket limit. 12569 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) { 12570 ClientSocketPoolManager::set_max_sockets_per_group( 12571 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12572 ClientSocketPoolManager::set_max_sockets_per_pool( 12573 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12574 12575 // Set up SSL request. 12576 12577 HttpRequestInfo ssl_request; 12578 ssl_request.method = "GET"; 12579 ssl_request.url = GURL("https://www.google.com/"); 12580 12581 MockWrite ssl_writes[] = { 12582 MockWrite("GET / HTTP/1.1\r\n" 12583 "Host: www.google.com\r\n" 12584 "Connection: keep-alive\r\n\r\n"), 12585 }; 12586 MockRead ssl_reads[] = { 12587 MockRead("HTTP/1.1 200 OK\r\n"), 12588 MockRead("Content-Length: 11\r\n\r\n"), 12589 MockRead("hello world"), 12590 MockRead(SYNCHRONOUS, OK), 12591 }; 12592 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads), 12593 ssl_writes, arraysize(ssl_writes)); 12594 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data); 12595 12596 SSLSocketDataProvider ssl(ASYNC, OK); 12597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 12598 12599 // Set up HTTP request. 12600 12601 HttpRequestInfo http_request; 12602 http_request.method = "GET"; 12603 http_request.url = GURL("http://www.google.com/"); 12604 12605 MockWrite http_writes[] = { 12606 MockWrite("GET / HTTP/1.1\r\n" 12607 "Host: www.google.com\r\n" 12608 "Connection: keep-alive\r\n\r\n"), 12609 }; 12610 MockRead http_reads[] = { 12611 MockRead("HTTP/1.1 200 OK\r\n"), 12612 MockRead("Content-Length: 7\r\n\r\n"), 12613 MockRead("falafel"), 12614 MockRead(SYNCHRONOUS, OK), 12615 }; 12616 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 12617 http_writes, arraysize(http_writes)); 12618 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 12619 12620 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12621 12622 // Start the SSL request. 12623 TestCompletionCallback ssl_callback; 12624 scoped_ptr<HttpTransaction> ssl_trans( 12625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12626 ASSERT_EQ(ERR_IO_PENDING, 12627 ssl_trans->Start(&ssl_request, ssl_callback.callback(), 12628 BoundNetLog())); 12629 12630 // Start the HTTP request. Pool should stall. 12631 TestCompletionCallback http_callback; 12632 scoped_ptr<HttpTransaction> http_trans( 12633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12634 ASSERT_EQ(ERR_IO_PENDING, 12635 http_trans->Start(&http_request, http_callback.callback(), 12636 BoundNetLog())); 12637 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get())); 12638 12639 // Wait for response from SSL request. 12640 ASSERT_EQ(OK, ssl_callback.WaitForResult()); 12641 std::string response_data; 12642 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data)); 12643 EXPECT_EQ("hello world", response_data); 12644 12645 // The SSL socket should automatically be closed, so the HTTP request can 12646 // start. 12647 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); 12648 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get())); 12649 12650 // The HTTP request can now complete. 12651 ASSERT_EQ(OK, http_callback.WaitForResult()); 12652 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data)); 12653 EXPECT_EQ("falafel", response_data); 12654 12655 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 12656 } 12657 12658 // Tests that when a SSL connection is established but there's no corresponding 12659 // request that needs it, the new socket is closed if the transport socket pool 12660 // is stalled on the global socket limit. 12661 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) { 12662 ClientSocketPoolManager::set_max_sockets_per_group( 12663 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12664 ClientSocketPoolManager::set_max_sockets_per_pool( 12665 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12666 12667 // Set up an ssl request. 12668 12669 HttpRequestInfo ssl_request; 12670 ssl_request.method = "GET"; 12671 ssl_request.url = GURL("https://www.foopy.com/"); 12672 12673 // No data will be sent on the SSL socket. 12674 StaticSocketDataProvider ssl_data; 12675 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data); 12676 12677 SSLSocketDataProvider ssl(ASYNC, OK); 12678 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 12679 12680 // Set up HTTP request. 12681 12682 HttpRequestInfo http_request; 12683 http_request.method = "GET"; 12684 http_request.url = GURL("http://www.google.com/"); 12685 12686 MockWrite http_writes[] = { 12687 MockWrite("GET / HTTP/1.1\r\n" 12688 "Host: www.google.com\r\n" 12689 "Connection: keep-alive\r\n\r\n"), 12690 }; 12691 MockRead http_reads[] = { 12692 MockRead("HTTP/1.1 200 OK\r\n"), 12693 MockRead("Content-Length: 7\r\n\r\n"), 12694 MockRead("falafel"), 12695 MockRead(SYNCHRONOUS, OK), 12696 }; 12697 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 12698 http_writes, arraysize(http_writes)); 12699 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 12700 12701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12702 12703 // Preconnect an SSL socket. A preconnect is needed because connect jobs are 12704 // cancelled when a normal transaction is cancelled. 12705 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory(); 12706 net::SSLConfig ssl_config; 12707 session->ssl_config_service()->GetSSLConfig(&ssl_config); 12708 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY, 12709 ssl_config, ssl_config); 12710 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); 12711 12712 // Start the HTTP request. Pool should stall. 12713 TestCompletionCallback http_callback; 12714 scoped_ptr<HttpTransaction> http_trans( 12715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12716 ASSERT_EQ(ERR_IO_PENDING, 12717 http_trans->Start(&http_request, http_callback.callback(), 12718 BoundNetLog())); 12719 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get())); 12720 12721 // The SSL connection will automatically be closed once the connection is 12722 // established, to let the HTTP request start. 12723 ASSERT_EQ(OK, http_callback.WaitForResult()); 12724 std::string response_data; 12725 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data)); 12726 EXPECT_EQ("falafel", response_data); 12727 12728 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 12729 } 12730 12731 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) { 12732 ScopedVector<UploadElementReader> element_readers; 12733 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12734 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12735 12736 HttpRequestInfo request; 12737 request.method = "POST"; 12738 request.url = GURL("http://www.foo.com/"); 12739 request.upload_data_stream = &upload_data_stream; 12740 request.load_flags = 0; 12741 12742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12743 scoped_ptr<HttpTransaction> trans( 12744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12745 // Send headers successfully, but get an error while sending the body. 12746 MockWrite data_writes[] = { 12747 MockWrite("POST / HTTP/1.1\r\n" 12748 "Host: www.foo.com\r\n" 12749 "Connection: keep-alive\r\n" 12750 "Content-Length: 3\r\n\r\n"), 12751 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12752 }; 12753 12754 MockRead data_reads[] = { 12755 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 12756 MockRead("hello world"), 12757 MockRead(SYNCHRONOUS, OK), 12758 }; 12759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12760 arraysize(data_writes)); 12761 session_deps_.socket_factory->AddSocketDataProvider(&data); 12762 12763 TestCompletionCallback callback; 12764 12765 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12766 EXPECT_EQ(ERR_IO_PENDING, rv); 12767 12768 rv = callback.WaitForResult(); 12769 EXPECT_EQ(OK, rv); 12770 12771 const HttpResponseInfo* response = trans->GetResponseInfo(); 12772 ASSERT_TRUE(response != NULL); 12773 12774 EXPECT_TRUE(response->headers.get() != NULL); 12775 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 12776 12777 std::string response_data; 12778 rv = ReadTransaction(trans.get(), &response_data); 12779 EXPECT_EQ(OK, rv); 12780 EXPECT_EQ("hello world", response_data); 12781 } 12782 12783 // This test makes sure the retry logic doesn't trigger when reading an error 12784 // response from a server that rejected a POST with a CONNECTION_RESET. 12785 TEST_P(HttpNetworkTransactionTest, 12786 PostReadsErrorResponseAfterResetOnReusedSocket) { 12787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12788 MockWrite data_writes[] = { 12789 MockWrite("GET / HTTP/1.1\r\n" 12790 "Host: www.foo.com\r\n" 12791 "Connection: keep-alive\r\n\r\n"), 12792 MockWrite("POST / HTTP/1.1\r\n" 12793 "Host: www.foo.com\r\n" 12794 "Connection: keep-alive\r\n" 12795 "Content-Length: 3\r\n\r\n"), 12796 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12797 }; 12798 12799 MockRead data_reads[] = { 12800 MockRead("HTTP/1.1 200 Peachy\r\n" 12801 "Content-Length: 14\r\n\r\n"), 12802 MockRead("first response"), 12803 MockRead("HTTP/1.1 400 Not OK\r\n" 12804 "Content-Length: 15\r\n\r\n"), 12805 MockRead("second response"), 12806 MockRead(SYNCHRONOUS, OK), 12807 }; 12808 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12809 arraysize(data_writes)); 12810 session_deps_.socket_factory->AddSocketDataProvider(&data); 12811 12812 TestCompletionCallback callback; 12813 HttpRequestInfo request1; 12814 request1.method = "GET"; 12815 request1.url = GURL("http://www.foo.com/"); 12816 request1.load_flags = 0; 12817 12818 scoped_ptr<HttpTransaction> trans1( 12819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12820 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); 12821 EXPECT_EQ(ERR_IO_PENDING, rv); 12822 12823 rv = callback.WaitForResult(); 12824 EXPECT_EQ(OK, rv); 12825 12826 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 12827 ASSERT_TRUE(response1 != NULL); 12828 12829 EXPECT_TRUE(response1->headers.get() != NULL); 12830 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine()); 12831 12832 std::string response_data1; 12833 rv = ReadTransaction(trans1.get(), &response_data1); 12834 EXPECT_EQ(OK, rv); 12835 EXPECT_EQ("first response", response_data1); 12836 // Delete the transaction to release the socket back into the socket pool. 12837 trans1.reset(); 12838 12839 ScopedVector<UploadElementReader> element_readers; 12840 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12841 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12842 12843 HttpRequestInfo request2; 12844 request2.method = "POST"; 12845 request2.url = GURL("http://www.foo.com/"); 12846 request2.upload_data_stream = &upload_data_stream; 12847 request2.load_flags = 0; 12848 12849 scoped_ptr<HttpTransaction> trans2( 12850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12851 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 12852 EXPECT_EQ(ERR_IO_PENDING, rv); 12853 12854 rv = callback.WaitForResult(); 12855 EXPECT_EQ(OK, rv); 12856 12857 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 12858 ASSERT_TRUE(response2 != NULL); 12859 12860 EXPECT_TRUE(response2->headers.get() != NULL); 12861 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine()); 12862 12863 std::string response_data2; 12864 rv = ReadTransaction(trans2.get(), &response_data2); 12865 EXPECT_EQ(OK, rv); 12866 EXPECT_EQ("second response", response_data2); 12867 } 12868 12869 TEST_P(HttpNetworkTransactionTest, 12870 PostReadsErrorResponseAfterResetPartialBodySent) { 12871 ScopedVector<UploadElementReader> element_readers; 12872 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12873 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12874 12875 HttpRequestInfo request; 12876 request.method = "POST"; 12877 request.url = GURL("http://www.foo.com/"); 12878 request.upload_data_stream = &upload_data_stream; 12879 request.load_flags = 0; 12880 12881 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12882 scoped_ptr<HttpTransaction> trans( 12883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12884 // Send headers successfully, but get an error while sending the body. 12885 MockWrite data_writes[] = { 12886 MockWrite("POST / HTTP/1.1\r\n" 12887 "Host: www.foo.com\r\n" 12888 "Connection: keep-alive\r\n" 12889 "Content-Length: 3\r\n\r\n" 12890 "fo"), 12891 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12892 }; 12893 12894 MockRead data_reads[] = { 12895 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 12896 MockRead("hello world"), 12897 MockRead(SYNCHRONOUS, OK), 12898 }; 12899 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12900 arraysize(data_writes)); 12901 session_deps_.socket_factory->AddSocketDataProvider(&data); 12902 12903 TestCompletionCallback callback; 12904 12905 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12906 EXPECT_EQ(ERR_IO_PENDING, rv); 12907 12908 rv = callback.WaitForResult(); 12909 EXPECT_EQ(OK, rv); 12910 12911 const HttpResponseInfo* response = trans->GetResponseInfo(); 12912 ASSERT_TRUE(response != NULL); 12913 12914 EXPECT_TRUE(response->headers.get() != NULL); 12915 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 12916 12917 std::string response_data; 12918 rv = ReadTransaction(trans.get(), &response_data); 12919 EXPECT_EQ(OK, rv); 12920 EXPECT_EQ("hello world", response_data); 12921 } 12922 12923 // This tests the more common case than the previous test, where headers and 12924 // body are not merged into a single request. 12925 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) { 12926 ScopedVector<UploadElementReader> element_readers; 12927 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12928 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); 12929 12930 HttpRequestInfo request; 12931 request.method = "POST"; 12932 request.url = GURL("http://www.foo.com/"); 12933 request.upload_data_stream = &upload_data_stream; 12934 request.load_flags = 0; 12935 12936 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12937 scoped_ptr<HttpTransaction> trans( 12938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12939 // Send headers successfully, but get an error while sending the body. 12940 MockWrite data_writes[] = { 12941 MockWrite("POST / HTTP/1.1\r\n" 12942 "Host: www.foo.com\r\n" 12943 "Connection: keep-alive\r\n" 12944 "Transfer-Encoding: chunked\r\n\r\n"), 12945 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12946 }; 12947 12948 MockRead data_reads[] = { 12949 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 12950 MockRead("hello world"), 12951 MockRead(SYNCHRONOUS, OK), 12952 }; 12953 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12954 arraysize(data_writes)); 12955 session_deps_.socket_factory->AddSocketDataProvider(&data); 12956 12957 TestCompletionCallback callback; 12958 12959 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12960 EXPECT_EQ(ERR_IO_PENDING, rv); 12961 // Make sure the headers are sent before adding a chunk. This ensures that 12962 // they can't be merged with the body in a single send. Not currently 12963 // necessary since a chunked body is never merged with headers, but this makes 12964 // the test more future proof. 12965 base::RunLoop().RunUntilIdle(); 12966 12967 upload_data_stream.AppendChunk("last chunk", 10, true); 12968 12969 rv = callback.WaitForResult(); 12970 EXPECT_EQ(OK, rv); 12971 12972 const HttpResponseInfo* response = trans->GetResponseInfo(); 12973 ASSERT_TRUE(response != NULL); 12974 12975 EXPECT_TRUE(response->headers.get() != NULL); 12976 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 12977 12978 std::string response_data; 12979 rv = ReadTransaction(trans.get(), &response_data); 12980 EXPECT_EQ(OK, rv); 12981 EXPECT_EQ("hello world", response_data); 12982 } 12983 12984 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) { 12985 ScopedVector<UploadElementReader> element_readers; 12986 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12987 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12988 12989 HttpRequestInfo request; 12990 request.method = "POST"; 12991 request.url = GURL("http://www.foo.com/"); 12992 request.upload_data_stream = &upload_data_stream; 12993 request.load_flags = 0; 12994 12995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12996 scoped_ptr<HttpTransaction> trans( 12997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12998 12999 MockWrite data_writes[] = { 13000 MockWrite("POST / HTTP/1.1\r\n" 13001 "Host: www.foo.com\r\n" 13002 "Connection: keep-alive\r\n" 13003 "Content-Length: 3\r\n\r\n"), 13004 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13005 }; 13006 13007 MockRead data_reads[] = { 13008 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 13009 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 13010 MockRead("hello world"), 13011 MockRead(SYNCHRONOUS, OK), 13012 }; 13013 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13014 arraysize(data_writes)); 13015 session_deps_.socket_factory->AddSocketDataProvider(&data); 13016 13017 TestCompletionCallback callback; 13018 13019 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13020 EXPECT_EQ(ERR_IO_PENDING, rv); 13021 13022 rv = callback.WaitForResult(); 13023 EXPECT_EQ(OK, rv); 13024 13025 const HttpResponseInfo* response = trans->GetResponseInfo(); 13026 ASSERT_TRUE(response != NULL); 13027 13028 EXPECT_TRUE(response->headers.get() != NULL); 13029 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 13030 13031 std::string response_data; 13032 rv = ReadTransaction(trans.get(), &response_data); 13033 EXPECT_EQ(OK, rv); 13034 EXPECT_EQ("hello world", response_data); 13035 } 13036 13037 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) { 13038 ScopedVector<UploadElementReader> element_readers; 13039 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13040 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13041 13042 HttpRequestInfo request; 13043 request.method = "POST"; 13044 request.url = GURL("http://www.foo.com/"); 13045 request.upload_data_stream = &upload_data_stream; 13046 request.load_flags = 0; 13047 13048 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13049 scoped_ptr<HttpTransaction> trans( 13050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 13051 // Send headers successfully, but get an error while sending the body. 13052 MockWrite data_writes[] = { 13053 MockWrite("POST / HTTP/1.1\r\n" 13054 "Host: www.foo.com\r\n" 13055 "Connection: keep-alive\r\n" 13056 "Content-Length: 3\r\n\r\n"), 13057 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13058 }; 13059 13060 MockRead data_reads[] = { 13061 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"), 13062 MockRead("hello world"), 13063 MockRead(SYNCHRONOUS, OK), 13064 }; 13065 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13066 arraysize(data_writes)); 13067 session_deps_.socket_factory->AddSocketDataProvider(&data); 13068 13069 TestCompletionCallback callback; 13070 13071 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13072 EXPECT_EQ(ERR_IO_PENDING, rv); 13073 13074 rv = callback.WaitForResult(); 13075 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13076 13077 const HttpResponseInfo* response = trans->GetResponseInfo(); 13078 EXPECT_TRUE(response == NULL); 13079 } 13080 13081 TEST_P(HttpNetworkTransactionTest, 13082 PostIgnoresNonErrorResponseAfterResetAnd100) { 13083 ScopedVector<UploadElementReader> element_readers; 13084 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13085 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13086 13087 HttpRequestInfo request; 13088 request.method = "POST"; 13089 request.url = GURL("http://www.foo.com/"); 13090 request.upload_data_stream = &upload_data_stream; 13091 request.load_flags = 0; 13092 13093 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13094 scoped_ptr<HttpTransaction> trans( 13095 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 13096 // Send headers successfully, but get an error while sending the body. 13097 MockWrite data_writes[] = { 13098 MockWrite("POST / HTTP/1.1\r\n" 13099 "Host: www.foo.com\r\n" 13100 "Connection: keep-alive\r\n" 13101 "Content-Length: 3\r\n\r\n"), 13102 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13103 }; 13104 13105 MockRead data_reads[] = { 13106 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 13107 MockRead("HTTP/1.0 302 Redirect\r\n"), 13108 MockRead("Location: http://somewhere-else.com/\r\n"), 13109 MockRead("Content-Length: 0\r\n\r\n"), 13110 MockRead(SYNCHRONOUS, OK), 13111 }; 13112 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13113 arraysize(data_writes)); 13114 session_deps_.socket_factory->AddSocketDataProvider(&data); 13115 13116 TestCompletionCallback callback; 13117 13118 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13119 EXPECT_EQ(ERR_IO_PENDING, rv); 13120 13121 rv = callback.WaitForResult(); 13122 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13123 13124 const HttpResponseInfo* response = trans->GetResponseInfo(); 13125 EXPECT_TRUE(response == NULL); 13126 } 13127 13128 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) { 13129 ScopedVector<UploadElementReader> element_readers; 13130 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13131 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13132 13133 HttpRequestInfo request; 13134 request.method = "POST"; 13135 request.url = GURL("http://www.foo.com/"); 13136 request.upload_data_stream = &upload_data_stream; 13137 request.load_flags = 0; 13138 13139 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13140 scoped_ptr<HttpTransaction> trans( 13141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 13142 // Send headers successfully, but get an error while sending the body. 13143 MockWrite data_writes[] = { 13144 MockWrite("POST / HTTP/1.1\r\n" 13145 "Host: www.foo.com\r\n" 13146 "Connection: keep-alive\r\n" 13147 "Content-Length: 3\r\n\r\n"), 13148 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13149 }; 13150 13151 MockRead data_reads[] = { 13152 MockRead("HTTP 0.9 rocks!"), 13153 MockRead(SYNCHRONOUS, OK), 13154 }; 13155 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13156 arraysize(data_writes)); 13157 session_deps_.socket_factory->AddSocketDataProvider(&data); 13158 13159 TestCompletionCallback callback; 13160 13161 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13162 EXPECT_EQ(ERR_IO_PENDING, rv); 13163 13164 rv = callback.WaitForResult(); 13165 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13166 13167 const HttpResponseInfo* response = trans->GetResponseInfo(); 13168 EXPECT_TRUE(response == NULL); 13169 } 13170 13171 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) { 13172 ScopedVector<UploadElementReader> element_readers; 13173 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13174 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13175 13176 HttpRequestInfo request; 13177 request.method = "POST"; 13178 request.url = GURL("http://www.foo.com/"); 13179 request.upload_data_stream = &upload_data_stream; 13180 request.load_flags = 0; 13181 13182 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13183 scoped_ptr<HttpTransaction> trans( 13184 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 13185 // Send headers successfully, but get an error while sending the body. 13186 MockWrite data_writes[] = { 13187 MockWrite("POST / HTTP/1.1\r\n" 13188 "Host: www.foo.com\r\n" 13189 "Connection: keep-alive\r\n" 13190 "Content-Length: 3\r\n\r\n"), 13191 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13192 }; 13193 13194 MockRead data_reads[] = { 13195 MockRead("HTTP/1.0 400 Not a Full Response\r\n"), 13196 MockRead(SYNCHRONOUS, OK), 13197 }; 13198 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13199 arraysize(data_writes)); 13200 session_deps_.socket_factory->AddSocketDataProvider(&data); 13201 13202 TestCompletionCallback callback; 13203 13204 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13205 EXPECT_EQ(ERR_IO_PENDING, rv); 13206 13207 rv = callback.WaitForResult(); 13208 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13209 13210 const HttpResponseInfo* response = trans->GetResponseInfo(); 13211 EXPECT_TRUE(response == NULL); 13212 } 13213 13214 } // namespace net 13215