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/file_util.h" 15 #include "base/files/file_path.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/strings/string_util.h" 20 #include "base/strings/utf_string_conversions.h" 21 #include "base/test/test_file_util.h" 22 #include "net/base/auth.h" 23 #include "net/base/capturing_net_log.h" 24 #include "net/base/completion_callback.h" 25 #include "net/base/load_timing_info.h" 26 #include "net/base/load_timing_info_test_util.h" 27 #include "net/base/net_log.h" 28 #include "net/base/net_log_unittest.h" 29 #include "net/base/request_priority.h" 30 #include "net/base/test_completion_callback.h" 31 #include "net/base/test_data_directory.h" 32 #include "net/base/upload_bytes_element_reader.h" 33 #include "net/base/upload_data_stream.h" 34 #include "net/base/upload_file_element_reader.h" 35 #include "net/cert/mock_cert_verifier.h" 36 #include "net/dns/host_cache.h" 37 #include "net/dns/mock_host_resolver.h" 38 #include "net/http/http_auth_handler_digest.h" 39 #include "net/http/http_auth_handler_mock.h" 40 #include "net/http/http_auth_handler_ntlm.h" 41 #include "net/http/http_basic_stream.h" 42 #include "net/http/http_network_session.h" 43 #include "net/http/http_network_session_peer.h" 44 #include "net/http/http_server_properties_impl.h" 45 #include "net/http/http_stream.h" 46 #include "net/http/http_stream_factory.h" 47 #include "net/http/http_transaction_unittest.h" 48 #include "net/proxy/proxy_config_service_fixed.h" 49 #include "net/proxy/proxy_info.h" 50 #include "net/proxy/proxy_resolver.h" 51 #include "net/proxy/proxy_service.h" 52 #include "net/socket/client_socket_factory.h" 53 #include "net/socket/client_socket_pool_manager.h" 54 #include "net/socket/mock_client_socket_pool_manager.h" 55 #include "net/socket/next_proto.h" 56 #include "net/socket/socket_test_util.h" 57 #include "net/socket/ssl_client_socket.h" 58 #include "net/spdy/spdy_framer.h" 59 #include "net/spdy/spdy_session.h" 60 #include "net/spdy/spdy_session_pool.h" 61 #include "net/spdy/spdy_test_util_common.h" 62 #include "net/ssl/ssl_cert_request_info.h" 63 #include "net/ssl/ssl_config_service.h" 64 #include "net/ssl/ssl_config_service_defaults.h" 65 #include "net/ssl/ssl_info.h" 66 #include "net/test/cert_test_util.h" 67 #include "net/websockets/websocket_handshake_stream_base.h" 68 #include "testing/gtest/include/gtest/gtest.h" 69 #include "testing/platform_test.h" 70 #include "url/gurl.h" 71 72 //----------------------------------------------------------------------------- 73 74 namespace { 75 76 const base::string16 kBar(ASCIIToUTF16("bar")); 77 const base::string16 kBar2(ASCIIToUTF16("bar2")); 78 const base::string16 kBar3(ASCIIToUTF16("bar3")); 79 const base::string16 kBaz(ASCIIToUTF16("baz")); 80 const base::string16 kFirst(ASCIIToUTF16("first")); 81 const base::string16 kFoo(ASCIIToUTF16("foo")); 82 const base::string16 kFoo2(ASCIIToUTF16("foo2")); 83 const base::string16 kFoo3(ASCIIToUTF16("foo3")); 84 const base::string16 kFou(ASCIIToUTF16("fou")); 85 const base::string16 kSecond(ASCIIToUTF16("second")); 86 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm")); 87 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword")); 88 89 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) { 90 return session->GetTransportSocketPool( 91 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount(); 92 } 93 94 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) { 95 return session->GetSSLSocketPool( 96 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount(); 97 } 98 99 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) { 100 return session->GetTransportSocketPool( 101 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled(); 102 } 103 104 // Takes in a Value created from a NetLogHttpResponseParameter, and returns 105 // a JSONified list of headers as a single string. Uses single quotes instead 106 // of double quotes for easier comparison. Returns false on failure. 107 bool GetHeaders(base::DictionaryValue* params, std::string* headers) { 108 if (!params) 109 return false; 110 base::ListValue* header_list; 111 if (!params->GetList("headers", &header_list)) 112 return false; 113 std::string double_quote_headers; 114 base::JSONWriter::Write(header_list, &double_quote_headers); 115 base::ReplaceChars(double_quote_headers, "\"", "'", headers); 116 return true; 117 } 118 119 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is 120 // used. 121 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) { 122 EXPECT_TRUE(load_timing_info.socket_reused); 123 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 124 125 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 126 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 127 128 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 129 EXPECT_FALSE(load_timing_info.send_start.is_null()); 130 131 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 132 133 // Set at a higher level. 134 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 135 EXPECT_TRUE(load_timing_info.request_start.is_null()); 136 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 137 } 138 139 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is 140 // used. 141 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info, 142 int connect_timing_flags) { 143 EXPECT_FALSE(load_timing_info.socket_reused); 144 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 145 146 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 147 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 148 149 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 150 connect_timing_flags); 151 EXPECT_LE(load_timing_info.connect_timing.connect_end, 152 load_timing_info.send_start); 153 154 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 155 156 // Set at a higher level. 157 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 158 EXPECT_TRUE(load_timing_info.request_start.is_null()); 159 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 160 } 161 162 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is 163 // used. 164 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) { 165 EXPECT_TRUE(load_timing_info.socket_reused); 166 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 167 168 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 169 170 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 171 EXPECT_LE(load_timing_info.proxy_resolve_start, 172 load_timing_info.proxy_resolve_end); 173 EXPECT_LE(load_timing_info.proxy_resolve_end, 174 load_timing_info.send_start); 175 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 176 177 // Set at a higher level. 178 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 179 EXPECT_TRUE(load_timing_info.request_start.is_null()); 180 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 181 } 182 183 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is 184 // used. 185 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info, 186 int connect_timing_flags) { 187 EXPECT_FALSE(load_timing_info.socket_reused); 188 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 189 190 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 191 EXPECT_LE(load_timing_info.proxy_resolve_start, 192 load_timing_info.proxy_resolve_end); 193 EXPECT_LE(load_timing_info.proxy_resolve_end, 194 load_timing_info.connect_timing.connect_start); 195 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 196 connect_timing_flags); 197 EXPECT_LE(load_timing_info.connect_timing.connect_end, 198 load_timing_info.send_start); 199 200 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 201 202 // Set at a higher level. 203 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 204 EXPECT_TRUE(load_timing_info.request_start.is_null()); 205 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 206 } 207 208 } // namespace 209 210 namespace net { 211 212 namespace { 213 214 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) { 215 return SpdySessionDependencies::SpdyCreateSession(session_deps); 216 } 217 218 } // namespace 219 220 class HttpNetworkTransactionTest 221 : public PlatformTest, 222 public ::testing::WithParamInterface<NextProto> { 223 public: 224 virtual ~HttpNetworkTransactionTest() { 225 // Important to restore the per-pool limit first, since the pool limit must 226 // always be greater than group limit, and the tests reduce both limits. 227 ClientSocketPoolManager::set_max_sockets_per_pool( 228 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_); 229 ClientSocketPoolManager::set_max_sockets_per_group( 230 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_); 231 } 232 233 protected: 234 HttpNetworkTransactionTest() 235 : spdy_util_(GetParam()), 236 session_deps_(GetParam()), 237 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group( 238 HttpNetworkSession::NORMAL_SOCKET_POOL)), 239 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool( 240 HttpNetworkSession::NORMAL_SOCKET_POOL)) { 241 } 242 243 struct SimpleGetHelperResult { 244 int rv; 245 std::string status_line; 246 std::string response_data; 247 LoadTimingInfo load_timing_info; 248 }; 249 250 virtual void SetUp() { 251 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 252 base::MessageLoop::current()->RunUntilIdle(); 253 } 254 255 virtual void TearDown() { 256 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 257 base::MessageLoop::current()->RunUntilIdle(); 258 // Empty the current queue. 259 base::MessageLoop::current()->RunUntilIdle(); 260 PlatformTest::TearDown(); 261 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 262 base::MessageLoop::current()->RunUntilIdle(); 263 HttpStreamFactory::set_use_alternate_protocols(false); 264 HttpStreamFactory::SetNextProtos(std::vector<NextProto>()); 265 } 266 267 // This is the expected return from a current server advertising SPDY. 268 std::string GetAlternateProtocolHttpHeader() { 269 return 270 std::string("Alternate-Protocol: 443:") + 271 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) + 272 "\r\n\r\n"; 273 } 274 275 // Either |write_failure| specifies a write failure or |read_failure| 276 // specifies a read failure when using a reused socket. In either case, the 277 // failure should cause the network transaction to resend the request, and the 278 // other argument should be NULL. 279 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure, 280 const MockRead* read_failure); 281 282 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[], 283 size_t data_count) { 284 SimpleGetHelperResult out; 285 286 HttpRequestInfo request; 287 request.method = "GET"; 288 request.url = GURL("http://www.google.com/"); 289 request.load_flags = 0; 290 291 CapturingBoundNetLog log; 292 session_deps_.net_log = log.bound().net_log(); 293 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 294 scoped_ptr<HttpTransaction> trans( 295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 296 297 for (size_t i = 0; i < data_count; ++i) { 298 session_deps_.socket_factory->AddSocketDataProvider(data[i]); 299 } 300 301 TestCompletionCallback callback; 302 303 EXPECT_TRUE(log.bound().IsLoggingAllEvents()); 304 int rv = trans->Start(&request, callback.callback(), log.bound()); 305 EXPECT_EQ(ERR_IO_PENDING, rv); 306 307 out.rv = callback.WaitForResult(); 308 309 // Even in the failure cases that use this function, connections are always 310 // successfully established before the error. 311 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info)); 312 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 313 314 if (out.rv != OK) 315 return out; 316 317 const HttpResponseInfo* response = trans->GetResponseInfo(); 318 // Can't use ASSERT_* inside helper functions like this, so 319 // return an error. 320 if (response == NULL || response->headers.get() == NULL) { 321 out.rv = ERR_UNEXPECTED; 322 return out; 323 } 324 out.status_line = response->headers->GetStatusLine(); 325 326 EXPECT_EQ("127.0.0.1", response->socket_address.host()); 327 EXPECT_EQ(80, response->socket_address.port()); 328 329 rv = ReadTransaction(trans.get(), &out.response_data); 330 EXPECT_EQ(OK, rv); 331 332 net::CapturingNetLog::CapturedEntryList entries; 333 log.GetEntries(&entries); 334 size_t pos = ExpectLogContainsSomewhere( 335 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, 336 NetLog::PHASE_NONE); 337 ExpectLogContainsSomewhere( 338 entries, pos, 339 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, 340 NetLog::PHASE_NONE); 341 342 std::string line; 343 EXPECT_TRUE(entries[pos].GetStringValue("line", &line)); 344 EXPECT_EQ("GET / HTTP/1.1\r\n", line); 345 346 HttpRequestHeaders request_headers; 347 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 348 std::string value; 349 EXPECT_TRUE(request_headers.GetHeader("Host", &value)); 350 EXPECT_EQ("www.google.com", value); 351 EXPECT_TRUE(request_headers.GetHeader("Connection", &value)); 352 EXPECT_EQ("keep-alive", value); 353 354 std::string response_headers; 355 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers)); 356 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']", 357 response_headers); 358 359 return out; 360 } 361 362 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[], 363 size_t reads_count) { 364 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0); 365 StaticSocketDataProvider* data[] = { &reads }; 366 return SimpleGetHelperForData(data, 1); 367 } 368 369 void ConnectStatusHelperWithExpectedStatus(const MockRead& status, 370 int expected_status); 371 372 void ConnectStatusHelper(const MockRead& status); 373 374 void BypassHostCacheOnRefreshHelper(int load_flags); 375 376 void CheckErrorIsPassedBack(int error, IoMode mode); 377 378 SpdyTestUtil spdy_util_; 379 SpdySessionDependencies session_deps_; 380 381 // Original socket limits. Some tests set these. Safest to always restore 382 // them once each test has been run. 383 int old_max_group_sockets_; 384 int old_max_pool_sockets_; 385 }; 386 387 INSTANTIATE_TEST_CASE_P( 388 NextProto, 389 HttpNetworkTransactionTest, 390 testing::Values(kProtoDeprecatedSPDY2, 391 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, 392 kProtoHTTP2Draft04)); 393 394 namespace { 395 396 // Fill |str| with a long header list that consumes >= |size| bytes. 397 void FillLargeHeadersString(std::string* str, int size) { 398 const char* row = 399 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; 400 const int sizeof_row = strlen(row); 401 const int num_rows = static_cast<int>( 402 ceil(static_cast<float>(size) / sizeof_row)); 403 const int sizeof_data = num_rows * sizeof_row; 404 DCHECK(sizeof_data >= size); 405 str->reserve(sizeof_data); 406 407 for (int i = 0; i < num_rows; ++i) 408 str->append(row, sizeof_row); 409 } 410 411 // Alternative functions that eliminate randomness and dependency on the local 412 // host name so that the generated NTLM messages are reproducible. 413 void MockGenerateRandom1(uint8* output, size_t n) { 414 static const uint8 bytes[] = { 415 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54 416 }; 417 static size_t current_byte = 0; 418 for (size_t i = 0; i < n; ++i) { 419 output[i] = bytes[current_byte++]; 420 current_byte %= arraysize(bytes); 421 } 422 } 423 424 void MockGenerateRandom2(uint8* output, size_t n) { 425 static const uint8 bytes[] = { 426 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1, 427 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f 428 }; 429 static size_t current_byte = 0; 430 for (size_t i = 0; i < n; ++i) { 431 output[i] = bytes[current_byte++]; 432 current_byte %= arraysize(bytes); 433 } 434 } 435 436 std::string MockGetHostName() { 437 return "WTC-WIN7"; 438 } 439 440 template<typename ParentPool> 441 class CaptureGroupNameSocketPool : public ParentPool { 442 public: 443 CaptureGroupNameSocketPool(HostResolver* host_resolver, 444 CertVerifier* cert_verifier); 445 446 const std::string last_group_name_received() const { 447 return last_group_name_; 448 } 449 450 virtual int RequestSocket(const std::string& group_name, 451 const void* socket_params, 452 RequestPriority priority, 453 ClientSocketHandle* handle, 454 const CompletionCallback& callback, 455 const BoundNetLog& net_log) { 456 last_group_name_ = group_name; 457 return ERR_IO_PENDING; 458 } 459 virtual void CancelRequest(const std::string& group_name, 460 ClientSocketHandle* handle) {} 461 virtual void ReleaseSocket(const std::string& group_name, 462 scoped_ptr<StreamSocket> socket, 463 int id) {} 464 virtual void CloseIdleSockets() {} 465 virtual int IdleSocketCount() const { 466 return 0; 467 } 468 virtual int IdleSocketCountInGroup(const std::string& group_name) const { 469 return 0; 470 } 471 virtual LoadState GetLoadState(const std::string& group_name, 472 const ClientSocketHandle* handle) const { 473 return LOAD_STATE_IDLE; 474 } 475 virtual base::TimeDelta ConnectionTimeout() const { 476 return base::TimeDelta(); 477 } 478 479 private: 480 std::string last_group_name_; 481 }; 482 483 typedef CaptureGroupNameSocketPool<TransportClientSocketPool> 484 CaptureGroupNameTransportSocketPool; 485 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool> 486 CaptureGroupNameHttpProxySocketPool; 487 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool> 488 CaptureGroupNameSOCKSSocketPool; 489 typedef CaptureGroupNameSocketPool<SSLClientSocketPool> 490 CaptureGroupNameSSLSocketPool; 491 492 template<typename ParentPool> 493 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool( 494 HostResolver* host_resolver, 495 CertVerifier* /* cert_verifier */) 496 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {} 497 498 template<> 499 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool( 500 HostResolver* host_resolver, 501 CertVerifier* /* cert_verifier */) 502 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {} 503 504 template <> 505 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool( 506 HostResolver* host_resolver, 507 CertVerifier* cert_verifier) 508 : SSLClientSocketPool(0, 509 0, 510 NULL, 511 host_resolver, 512 cert_verifier, 513 NULL, 514 NULL, 515 NULL, 516 std::string(), 517 NULL, 518 NULL, 519 NULL, 520 NULL, 521 NULL, 522 NULL) {} 523 524 //----------------------------------------------------------------------------- 525 526 // Helper functions for validating that AuthChallengeInfo's are correctly 527 // configured for common cases. 528 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) { 529 if (!auth_challenge) 530 return false; 531 EXPECT_FALSE(auth_challenge->is_proxy); 532 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString()); 533 EXPECT_EQ("MyRealm1", auth_challenge->realm); 534 EXPECT_EQ("basic", auth_challenge->scheme); 535 return true; 536 } 537 538 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) { 539 if (!auth_challenge) 540 return false; 541 EXPECT_TRUE(auth_challenge->is_proxy); 542 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString()); 543 EXPECT_EQ("MyRealm1", auth_challenge->realm); 544 EXPECT_EQ("basic", auth_challenge->scheme); 545 return true; 546 } 547 548 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) { 549 if (!auth_challenge) 550 return false; 551 EXPECT_FALSE(auth_challenge->is_proxy); 552 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString()); 553 EXPECT_EQ("digestive", auth_challenge->realm); 554 EXPECT_EQ("digest", auth_challenge->scheme); 555 return true; 556 } 557 558 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) { 559 if (!auth_challenge) 560 return false; 561 EXPECT_FALSE(auth_challenge->is_proxy); 562 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString()); 563 EXPECT_EQ(std::string(), auth_challenge->realm); 564 EXPECT_EQ("ntlm", auth_challenge->scheme); 565 return true; 566 } 567 568 } // namespace 569 570 TEST_P(HttpNetworkTransactionTest, Basic) { 571 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 572 scoped_ptr<HttpTransaction> trans( 573 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 574 } 575 576 TEST_P(HttpNetworkTransactionTest, SimpleGET) { 577 MockRead data_reads[] = { 578 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 579 MockRead("hello world"), 580 MockRead(SYNCHRONOUS, OK), 581 }; 582 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 583 arraysize(data_reads)); 584 EXPECT_EQ(OK, out.rv); 585 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 586 EXPECT_EQ("hello world", out.response_data); 587 } 588 589 // Response with no status line. 590 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) { 591 MockRead data_reads[] = { 592 MockRead("hello world"), 593 MockRead(SYNCHRONOUS, OK), 594 }; 595 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 596 arraysize(data_reads)); 597 EXPECT_EQ(OK, out.rv); 598 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 599 EXPECT_EQ("hello world", out.response_data); 600 } 601 602 // Allow up to 4 bytes of junk to precede status line. 603 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) { 604 MockRead data_reads[] = { 605 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 606 MockRead(SYNCHRONOUS, OK), 607 }; 608 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 609 arraysize(data_reads)); 610 EXPECT_EQ(OK, out.rv); 611 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 612 EXPECT_EQ("DATA", out.response_data); 613 } 614 615 // Allow up to 4 bytes of junk to precede status line. 616 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { 617 MockRead data_reads[] = { 618 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 619 MockRead(SYNCHRONOUS, OK), 620 }; 621 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 622 arraysize(data_reads)); 623 EXPECT_EQ(OK, out.rv); 624 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 625 EXPECT_EQ("DATA", out.response_data); 626 } 627 628 // Beyond 4 bytes of slop and it should fail to find a status line. 629 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { 630 MockRead data_reads[] = { 631 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"), 632 MockRead(SYNCHRONOUS, OK), 633 }; 634 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 635 arraysize(data_reads)); 636 EXPECT_EQ(OK, out.rv); 637 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 638 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); 639 } 640 641 // Same as StatusLineJunk4Bytes, except the read chunks are smaller. 642 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { 643 MockRead data_reads[] = { 644 MockRead("\n"), 645 MockRead("\n"), 646 MockRead("Q"), 647 MockRead("J"), 648 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 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 404 Not Found", out.status_line); 655 EXPECT_EQ("DATA", out.response_data); 656 } 657 658 // Close the connection before enough bytes to have a status line. 659 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) { 660 MockRead data_reads[] = { 661 MockRead("HTT"), 662 MockRead(SYNCHRONOUS, OK), 663 }; 664 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 665 arraysize(data_reads)); 666 EXPECT_EQ(OK, out.rv); 667 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 668 EXPECT_EQ("HTT", out.response_data); 669 } 670 671 // Simulate a 204 response, lacking a Content-Length header, sent over a 672 // persistent connection. The response should still terminate since a 204 673 // cannot have a response body. 674 TEST_P(HttpNetworkTransactionTest, StopsReading204) { 675 MockRead data_reads[] = { 676 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 677 MockRead("junk"), // Should not be read!! 678 MockRead(SYNCHRONOUS, OK), 679 }; 680 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 681 arraysize(data_reads)); 682 EXPECT_EQ(OK, out.rv); 683 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); 684 EXPECT_EQ("", out.response_data); 685 } 686 687 // A simple request using chunked encoding with some extra data after. 688 // (Like might be seen in a pipelined response.) 689 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) { 690 MockRead data_reads[] = { 691 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"), 692 MockRead("5\r\nHello\r\n"), 693 MockRead("1\r\n"), 694 MockRead(" \r\n"), 695 MockRead("5\r\nworld\r\n"), 696 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"), 697 MockRead(SYNCHRONOUS, OK), 698 }; 699 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 700 arraysize(data_reads)); 701 EXPECT_EQ(OK, out.rv); 702 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 703 EXPECT_EQ("Hello world", out.response_data); 704 } 705 706 // Next tests deal with http://crbug.com/56344. 707 708 TEST_P(HttpNetworkTransactionTest, 709 MultipleContentLengthHeadersNoTransferEncoding) { 710 MockRead data_reads[] = { 711 MockRead("HTTP/1.1 200 OK\r\n"), 712 MockRead("Content-Length: 10\r\n"), 713 MockRead("Content-Length: 5\r\n\r\n"), 714 }; 715 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 716 arraysize(data_reads)); 717 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 718 } 719 720 TEST_P(HttpNetworkTransactionTest, 721 DuplicateContentLengthHeadersNoTransferEncoding) { 722 MockRead data_reads[] = { 723 MockRead("HTTP/1.1 200 OK\r\n"), 724 MockRead("Content-Length: 5\r\n"), 725 MockRead("Content-Length: 5\r\n\r\n"), 726 MockRead("Hello"), 727 }; 728 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 729 arraysize(data_reads)); 730 EXPECT_EQ(OK, out.rv); 731 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 732 EXPECT_EQ("Hello", out.response_data); 733 } 734 735 TEST_P(HttpNetworkTransactionTest, 736 ComplexContentLengthHeadersNoTransferEncoding) { 737 // More than 2 dupes. 738 { 739 MockRead data_reads[] = { 740 MockRead("HTTP/1.1 200 OK\r\n"), 741 MockRead("Content-Length: 5\r\n"), 742 MockRead("Content-Length: 5\r\n"), 743 MockRead("Content-Length: 5\r\n\r\n"), 744 MockRead("Hello"), 745 }; 746 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 747 arraysize(data_reads)); 748 EXPECT_EQ(OK, out.rv); 749 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 750 EXPECT_EQ("Hello", out.response_data); 751 } 752 // HTTP/1.0 753 { 754 MockRead data_reads[] = { 755 MockRead("HTTP/1.0 200 OK\r\n"), 756 MockRead("Content-Length: 5\r\n"), 757 MockRead("Content-Length: 5\r\n"), 758 MockRead("Content-Length: 5\r\n\r\n"), 759 MockRead("Hello"), 760 }; 761 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 762 arraysize(data_reads)); 763 EXPECT_EQ(OK, out.rv); 764 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 765 EXPECT_EQ("Hello", out.response_data); 766 } 767 // 2 dupes and one mismatched. 768 { 769 MockRead data_reads[] = { 770 MockRead("HTTP/1.1 200 OK\r\n"), 771 MockRead("Content-Length: 10\r\n"), 772 MockRead("Content-Length: 10\r\n"), 773 MockRead("Content-Length: 5\r\n\r\n"), 774 }; 775 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 776 arraysize(data_reads)); 777 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 778 } 779 } 780 781 TEST_P(HttpNetworkTransactionTest, 782 MultipleContentLengthHeadersTransferEncoding) { 783 MockRead data_reads[] = { 784 MockRead("HTTP/1.1 200 OK\r\n"), 785 MockRead("Content-Length: 666\r\n"), 786 MockRead("Content-Length: 1337\r\n"), 787 MockRead("Transfer-Encoding: chunked\r\n\r\n"), 788 MockRead("5\r\nHello\r\n"), 789 MockRead("1\r\n"), 790 MockRead(" \r\n"), 791 MockRead("5\r\nworld\r\n"), 792 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"), 793 MockRead(SYNCHRONOUS, OK), 794 }; 795 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 796 arraysize(data_reads)); 797 EXPECT_EQ(OK, out.rv); 798 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 799 EXPECT_EQ("Hello world", out.response_data); 800 } 801 802 // Next tests deal with http://crbug.com/98895. 803 804 // Checks that a single Content-Disposition header results in no error. 805 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) { 806 MockRead data_reads[] = { 807 MockRead("HTTP/1.1 200 OK\r\n"), 808 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"), 809 MockRead("Content-Length: 5\r\n\r\n"), 810 MockRead("Hello"), 811 }; 812 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 813 arraysize(data_reads)); 814 EXPECT_EQ(OK, out.rv); 815 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 816 EXPECT_EQ("Hello", out.response_data); 817 } 818 819 // Checks that two identical Content-Disposition headers result in no error. 820 TEST_P(HttpNetworkTransactionTest, 821 TwoIdenticalContentDispositionHeaders) { 822 MockRead data_reads[] = { 823 MockRead("HTTP/1.1 200 OK\r\n"), 824 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 825 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 826 MockRead("Content-Length: 5\r\n\r\n"), 827 MockRead("Hello"), 828 }; 829 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 830 arraysize(data_reads)); 831 EXPECT_EQ(OK, out.rv); 832 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 833 EXPECT_EQ("Hello", out.response_data); 834 } 835 836 // Checks that two distinct Content-Disposition headers result in an error. 837 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) { 838 MockRead data_reads[] = { 839 MockRead("HTTP/1.1 200 OK\r\n"), 840 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 841 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"), 842 MockRead("Content-Length: 5\r\n\r\n"), 843 MockRead("Hello"), 844 }; 845 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 846 arraysize(data_reads)); 847 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv); 848 } 849 850 // Checks that two identical Location headers result in no error. 851 // Also tests Location header behavior. 852 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) { 853 MockRead data_reads[] = { 854 MockRead("HTTP/1.1 302 Redirect\r\n"), 855 MockRead("Location: http://good.com/\r\n"), 856 MockRead("Location: http://good.com/\r\n"), 857 MockRead("Content-Length: 0\r\n\r\n"), 858 MockRead(SYNCHRONOUS, OK), 859 }; 860 861 HttpRequestInfo request; 862 request.method = "GET"; 863 request.url = GURL("http://redirect.com/"); 864 request.load_flags = 0; 865 866 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 867 scoped_ptr<HttpTransaction> trans( 868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 869 870 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 871 session_deps_.socket_factory->AddSocketDataProvider(&data); 872 873 TestCompletionCallback callback; 874 875 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 876 EXPECT_EQ(ERR_IO_PENDING, rv); 877 878 EXPECT_EQ(OK, callback.WaitForResult()); 879 880 const HttpResponseInfo* response = trans->GetResponseInfo(); 881 ASSERT_TRUE(response != NULL && response->headers.get() != NULL); 882 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine()); 883 std::string url; 884 EXPECT_TRUE(response->headers->IsRedirect(&url)); 885 EXPECT_EQ("http://good.com/", url); 886 } 887 888 // Checks that two distinct Location headers result in an error. 889 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) { 890 MockRead data_reads[] = { 891 MockRead("HTTP/1.1 302 Redirect\r\n"), 892 MockRead("Location: http://good.com/\r\n"), 893 MockRead("Location: http://evil.com/\r\n"), 894 MockRead("Content-Length: 0\r\n\r\n"), 895 MockRead(SYNCHRONOUS, OK), 896 }; 897 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 898 arraysize(data_reads)); 899 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv); 900 } 901 902 // Do a request using the HEAD method. Verify that we don't try to read the 903 // message body (since HEAD has none). 904 TEST_P(HttpNetworkTransactionTest, Head) { 905 HttpRequestInfo request; 906 request.method = "HEAD"; 907 request.url = GURL("http://www.google.com/"); 908 request.load_flags = 0; 909 910 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 911 scoped_ptr<HttpTransaction> trans( 912 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 913 914 MockWrite data_writes1[] = { 915 MockWrite("HEAD / HTTP/1.1\r\n" 916 "Host: www.google.com\r\n" 917 "Connection: keep-alive\r\n" 918 "Content-Length: 0\r\n\r\n"), 919 }; 920 MockRead data_reads1[] = { 921 MockRead("HTTP/1.1 404 Not Found\r\n"), 922 MockRead("Server: Blah\r\n"), 923 MockRead("Content-Length: 1234\r\n\r\n"), 924 925 // No response body because the test stops reading here. 926 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 927 }; 928 929 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 930 data_writes1, arraysize(data_writes1)); 931 session_deps_.socket_factory->AddSocketDataProvider(&data1); 932 933 TestCompletionCallback callback1; 934 935 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 936 EXPECT_EQ(ERR_IO_PENDING, rv); 937 938 rv = callback1.WaitForResult(); 939 EXPECT_EQ(OK, rv); 940 941 const HttpResponseInfo* response = trans->GetResponseInfo(); 942 ASSERT_TRUE(response != NULL); 943 944 // Check that the headers got parsed. 945 EXPECT_TRUE(response->headers.get() != NULL); 946 EXPECT_EQ(1234, response->headers->GetContentLength()); 947 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine()); 948 949 std::string server_header; 950 void* iter = NULL; 951 bool has_server_header = response->headers->EnumerateHeader( 952 &iter, "Server", &server_header); 953 EXPECT_TRUE(has_server_header); 954 EXPECT_EQ("Blah", server_header); 955 956 // Reading should give EOF right away, since there is no message body 957 // (despite non-zero content-length). 958 std::string response_data; 959 rv = ReadTransaction(trans.get(), &response_data); 960 EXPECT_EQ(OK, rv); 961 EXPECT_EQ("", response_data); 962 } 963 964 TEST_P(HttpNetworkTransactionTest, ReuseConnection) { 965 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 966 967 MockRead data_reads[] = { 968 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 969 MockRead("hello"), 970 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 971 MockRead("world"), 972 MockRead(SYNCHRONOUS, OK), 973 }; 974 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 975 session_deps_.socket_factory->AddSocketDataProvider(&data); 976 977 const char* const kExpectedResponseData[] = { 978 "hello", "world" 979 }; 980 981 for (int i = 0; i < 2; ++i) { 982 HttpRequestInfo request; 983 request.method = "GET"; 984 request.url = GURL("http://www.google.com/"); 985 request.load_flags = 0; 986 987 scoped_ptr<HttpTransaction> trans( 988 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 989 990 TestCompletionCallback callback; 991 992 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 993 EXPECT_EQ(ERR_IO_PENDING, rv); 994 995 rv = callback.WaitForResult(); 996 EXPECT_EQ(OK, rv); 997 998 const HttpResponseInfo* response = trans->GetResponseInfo(); 999 ASSERT_TRUE(response != NULL); 1000 1001 EXPECT_TRUE(response->headers.get() != NULL); 1002 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1003 1004 std::string response_data; 1005 rv = ReadTransaction(trans.get(), &response_data); 1006 EXPECT_EQ(OK, rv); 1007 EXPECT_EQ(kExpectedResponseData[i], response_data); 1008 } 1009 } 1010 1011 TEST_P(HttpNetworkTransactionTest, Ignores100) { 1012 ScopedVector<UploadElementReader> element_readers; 1013 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 1014 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 1015 1016 HttpRequestInfo request; 1017 request.method = "POST"; 1018 request.url = GURL("http://www.foo.com/"); 1019 request.upload_data_stream = &upload_data_stream; 1020 request.load_flags = 0; 1021 1022 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1023 scoped_ptr<HttpTransaction> trans( 1024 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1025 1026 MockRead data_reads[] = { 1027 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 1028 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 1029 MockRead("hello world"), 1030 MockRead(SYNCHRONOUS, OK), 1031 }; 1032 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1033 session_deps_.socket_factory->AddSocketDataProvider(&data); 1034 1035 TestCompletionCallback callback; 1036 1037 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1038 EXPECT_EQ(ERR_IO_PENDING, rv); 1039 1040 rv = callback.WaitForResult(); 1041 EXPECT_EQ(OK, rv); 1042 1043 const HttpResponseInfo* response = trans->GetResponseInfo(); 1044 ASSERT_TRUE(response != NULL); 1045 1046 EXPECT_TRUE(response->headers.get() != NULL); 1047 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 1048 1049 std::string response_data; 1050 rv = ReadTransaction(trans.get(), &response_data); 1051 EXPECT_EQ(OK, rv); 1052 EXPECT_EQ("hello world", response_data); 1053 } 1054 1055 // This test is almost the same as Ignores100 above, but the response contains 1056 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is 1057 // HTTP/1.1 and the two status headers are read in one read. 1058 TEST_P(HttpNetworkTransactionTest, Ignores1xx) { 1059 HttpRequestInfo request; 1060 request.method = "GET"; 1061 request.url = GURL("http://www.foo.com/"); 1062 request.load_flags = 0; 1063 1064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1065 scoped_ptr<HttpTransaction> trans( 1066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1067 1068 MockRead data_reads[] = { 1069 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n" 1070 "HTTP/1.1 200 OK\r\n\r\n"), 1071 MockRead("hello world"), 1072 MockRead(SYNCHRONOUS, OK), 1073 }; 1074 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1075 session_deps_.socket_factory->AddSocketDataProvider(&data); 1076 1077 TestCompletionCallback callback; 1078 1079 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1080 EXPECT_EQ(ERR_IO_PENDING, rv); 1081 1082 rv = callback.WaitForResult(); 1083 EXPECT_EQ(OK, rv); 1084 1085 const HttpResponseInfo* response = trans->GetResponseInfo(); 1086 ASSERT_TRUE(response != NULL); 1087 1088 EXPECT_TRUE(response->headers.get() != NULL); 1089 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1090 1091 std::string response_data; 1092 rv = ReadTransaction(trans.get(), &response_data); 1093 EXPECT_EQ(OK, rv); 1094 EXPECT_EQ("hello world", response_data); 1095 } 1096 1097 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) { 1098 HttpRequestInfo request; 1099 request.method = "POST"; 1100 request.url = GURL("http://www.foo.com/"); 1101 request.load_flags = 0; 1102 1103 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1104 scoped_ptr<HttpTransaction> trans( 1105 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1106 1107 MockRead data_reads[] = { 1108 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"), 1109 MockRead(ASYNC, 0), 1110 }; 1111 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1112 session_deps_.socket_factory->AddSocketDataProvider(&data); 1113 1114 TestCompletionCallback callback; 1115 1116 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1117 EXPECT_EQ(ERR_IO_PENDING, rv); 1118 1119 rv = callback.WaitForResult(); 1120 EXPECT_EQ(OK, rv); 1121 1122 std::string response_data; 1123 rv = ReadTransaction(trans.get(), &response_data); 1124 EXPECT_EQ(OK, rv); 1125 EXPECT_EQ("", response_data); 1126 } 1127 1128 TEST_P(HttpNetworkTransactionTest, EmptyResponse) { 1129 HttpRequestInfo request; 1130 request.method = "POST"; 1131 request.url = GURL("http://www.foo.com/"); 1132 request.load_flags = 0; 1133 1134 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1135 scoped_ptr<HttpTransaction> trans( 1136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1137 1138 1139 MockRead data_reads[] = { 1140 MockRead(ASYNC, 0), 1141 }; 1142 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1143 session_deps_.socket_factory->AddSocketDataProvider(&data); 1144 1145 TestCompletionCallback callback; 1146 1147 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1148 EXPECT_EQ(ERR_IO_PENDING, rv); 1149 1150 rv = callback.WaitForResult(); 1151 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 1152 } 1153 1154 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest( 1155 const MockWrite* write_failure, 1156 const MockRead* read_failure) { 1157 HttpRequestInfo request; 1158 request.method = "GET"; 1159 request.url = GURL("http://www.foo.com/"); 1160 request.load_flags = 0; 1161 1162 CapturingNetLog net_log; 1163 session_deps_.net_log = &net_log; 1164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1165 1166 // Written data for successfully sending both requests. 1167 MockWrite data1_writes[] = { 1168 MockWrite("GET / HTTP/1.1\r\n" 1169 "Host: www.foo.com\r\n" 1170 "Connection: keep-alive\r\n\r\n"), 1171 MockWrite("GET / HTTP/1.1\r\n" 1172 "Host: www.foo.com\r\n" 1173 "Connection: keep-alive\r\n\r\n") 1174 }; 1175 1176 // Read results for the first request. 1177 MockRead data1_reads[] = { 1178 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1179 MockRead("hello"), 1180 MockRead(ASYNC, OK), 1181 }; 1182 1183 if (write_failure) { 1184 ASSERT_TRUE(!read_failure); 1185 data1_writes[1] = *write_failure; 1186 } else { 1187 ASSERT_TRUE(read_failure); 1188 data1_reads[2] = *read_failure; 1189 } 1190 1191 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), 1192 data1_writes, arraysize(data1_writes)); 1193 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1194 1195 MockRead data2_reads[] = { 1196 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1197 MockRead("world"), 1198 MockRead(ASYNC, OK), 1199 }; 1200 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 1201 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1202 1203 const char* kExpectedResponseData[] = { 1204 "hello", "world" 1205 }; 1206 1207 uint32 first_socket_log_id = NetLog::Source::kInvalidId; 1208 for (int i = 0; i < 2; ++i) { 1209 TestCompletionCallback callback; 1210 1211 scoped_ptr<HttpTransaction> trans( 1212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1213 1214 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1215 EXPECT_EQ(ERR_IO_PENDING, rv); 1216 1217 rv = callback.WaitForResult(); 1218 EXPECT_EQ(OK, rv); 1219 1220 LoadTimingInfo load_timing_info; 1221 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1222 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 1223 if (i == 0) { 1224 first_socket_log_id = load_timing_info.socket_log_id; 1225 } else { 1226 // The second request should be using a new socket. 1227 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id); 1228 } 1229 1230 const HttpResponseInfo* response = trans->GetResponseInfo(); 1231 ASSERT_TRUE(response != NULL); 1232 1233 EXPECT_TRUE(response->headers.get() != NULL); 1234 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1235 1236 std::string response_data; 1237 rv = ReadTransaction(trans.get(), &response_data); 1238 EXPECT_EQ(OK, rv); 1239 EXPECT_EQ(kExpectedResponseData[i], response_data); 1240 } 1241 } 1242 1243 TEST_P(HttpNetworkTransactionTest, 1244 KeepAliveConnectionNotConnectedOnWrite) { 1245 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1246 KeepAliveConnectionResendRequestTest(&write_failure, NULL); 1247 } 1248 1249 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) { 1250 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1251 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1252 } 1253 1254 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { 1255 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1256 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1257 } 1258 1259 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { 1260 HttpRequestInfo request; 1261 request.method = "GET"; 1262 request.url = GURL("http://www.google.com/"); 1263 request.load_flags = 0; 1264 1265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1266 scoped_ptr<HttpTransaction> trans( 1267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1268 1269 MockRead data_reads[] = { 1270 MockRead(ASYNC, ERR_CONNECTION_RESET), 1271 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 1272 MockRead("hello world"), 1273 MockRead(SYNCHRONOUS, OK), 1274 }; 1275 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1276 session_deps_.socket_factory->AddSocketDataProvider(&data); 1277 1278 TestCompletionCallback callback; 1279 1280 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1281 EXPECT_EQ(ERR_IO_PENDING, rv); 1282 1283 rv = callback.WaitForResult(); 1284 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1285 1286 const HttpResponseInfo* response = trans->GetResponseInfo(); 1287 EXPECT_TRUE(response == NULL); 1288 } 1289 1290 // What do various browsers do when the server closes a non-keepalive 1291 // connection without sending any response header or body? 1292 // 1293 // IE7: error page 1294 // Safari 3.1.2 (Windows): error page 1295 // Firefox 3.0.1: blank page 1296 // Opera 9.52: after five attempts, blank page 1297 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE) 1298 // Us: error page (EMPTY_RESPONSE) 1299 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { 1300 MockRead data_reads[] = { 1301 MockRead(SYNCHRONOUS, OK), // EOF 1302 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 1303 MockRead("hello world"), 1304 MockRead(SYNCHRONOUS, OK), 1305 }; 1306 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 1307 arraysize(data_reads)); 1308 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); 1309 } 1310 1311 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression 1312 // tests. There was a bug causing HttpNetworkTransaction to hang in the 1313 // destructor in such situations. 1314 // See http://crbug.com/154712 and http://crbug.com/156609. 1315 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) { 1316 HttpRequestInfo request; 1317 request.method = "GET"; 1318 request.url = GURL("http://www.google.com/"); 1319 request.load_flags = 0; 1320 1321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1322 scoped_ptr<HttpTransaction> trans( 1323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1324 1325 MockRead data_reads[] = { 1326 MockRead("HTTP/1.0 200 OK\r\n"), 1327 MockRead("Connection: keep-alive\r\n"), 1328 MockRead("Content-Length: 100\r\n\r\n"), 1329 MockRead("hello"), 1330 MockRead(SYNCHRONOUS, 0), 1331 }; 1332 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1333 session_deps_.socket_factory->AddSocketDataProvider(&data); 1334 1335 TestCompletionCallback callback; 1336 1337 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1338 EXPECT_EQ(ERR_IO_PENDING, rv); 1339 1340 rv = callback.WaitForResult(); 1341 EXPECT_EQ(OK, rv); 1342 1343 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1344 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1345 if (rv == ERR_IO_PENDING) 1346 rv = callback.WaitForResult(); 1347 EXPECT_EQ(5, rv); 1348 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1349 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 1350 1351 trans.reset(); 1352 base::MessageLoop::current()->RunUntilIdle(); 1353 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 1354 } 1355 1356 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) { 1357 HttpRequestInfo request; 1358 request.method = "GET"; 1359 request.url = GURL("http://www.google.com/"); 1360 request.load_flags = 0; 1361 1362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1363 scoped_ptr<HttpTransaction> trans( 1364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1365 1366 MockRead data_reads[] = { 1367 MockRead("HTTP/1.0 200 OK\r\n"), 1368 MockRead("Connection: keep-alive\r\n"), 1369 MockRead("Content-Length: 100\r\n\r\n"), 1370 MockRead(SYNCHRONOUS, 0), 1371 }; 1372 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1373 session_deps_.socket_factory->AddSocketDataProvider(&data); 1374 1375 TestCompletionCallback callback; 1376 1377 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1378 EXPECT_EQ(ERR_IO_PENDING, rv); 1379 1380 rv = callback.WaitForResult(); 1381 EXPECT_EQ(OK, rv); 1382 1383 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1384 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1385 if (rv == ERR_IO_PENDING) 1386 rv = callback.WaitForResult(); 1387 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 1388 1389 trans.reset(); 1390 base::MessageLoop::current()->RunUntilIdle(); 1391 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 1392 } 1393 1394 // Test that we correctly reuse a keep-alive connection after not explicitly 1395 // reading the body. 1396 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { 1397 HttpRequestInfo request; 1398 request.method = "GET"; 1399 request.url = GURL("http://www.foo.com/"); 1400 request.load_flags = 0; 1401 1402 CapturingNetLog net_log; 1403 session_deps_.net_log = &net_log; 1404 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1405 1406 // Note that because all these reads happen in the same 1407 // StaticSocketDataProvider, it shows that the same socket is being reused for 1408 // all transactions. 1409 MockRead data1_reads[] = { 1410 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 1411 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"), 1412 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"), 1413 MockRead("HTTP/1.1 302 Found\r\n" 1414 "Content-Length: 0\r\n\r\n"), 1415 MockRead("HTTP/1.1 302 Found\r\n" 1416 "Content-Length: 5\r\n\r\n" 1417 "hello"), 1418 MockRead("HTTP/1.1 301 Moved Permanently\r\n" 1419 "Content-Length: 0\r\n\r\n"), 1420 MockRead("HTTP/1.1 301 Moved Permanently\r\n" 1421 "Content-Length: 5\r\n\r\n" 1422 "hello"), 1423 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1424 MockRead("hello"), 1425 }; 1426 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0); 1427 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1428 1429 MockRead data2_reads[] = { 1430 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 1431 }; 1432 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 1433 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1434 1435 const int kNumUnreadBodies = arraysize(data1_reads) - 2; 1436 std::string response_lines[kNumUnreadBodies]; 1437 1438 uint32 first_socket_log_id = NetLog::Source::kInvalidId; 1439 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) { 1440 TestCompletionCallback callback; 1441 1442 scoped_ptr<HttpTransaction> trans( 1443 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1444 1445 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1446 EXPECT_EQ(ERR_IO_PENDING, rv); 1447 1448 rv = callback.WaitForResult(); 1449 EXPECT_EQ(OK, rv); 1450 1451 LoadTimingInfo load_timing_info; 1452 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1453 if (i == 0) { 1454 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 1455 first_socket_log_id = load_timing_info.socket_log_id; 1456 } else { 1457 TestLoadTimingReused(load_timing_info); 1458 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id); 1459 } 1460 1461 const HttpResponseInfo* response = trans->GetResponseInfo(); 1462 ASSERT_TRUE(response != NULL); 1463 1464 ASSERT_TRUE(response->headers.get() != NULL); 1465 response_lines[i] = response->headers->GetStatusLine(); 1466 1467 // We intentionally don't read the response bodies. 1468 } 1469 1470 const char* const kStatusLines[] = { 1471 "HTTP/1.1 204 No Content", 1472 "HTTP/1.1 205 Reset Content", 1473 "HTTP/1.1 304 Not Modified", 1474 "HTTP/1.1 302 Found", 1475 "HTTP/1.1 302 Found", 1476 "HTTP/1.1 301 Moved Permanently", 1477 "HTTP/1.1 301 Moved Permanently", 1478 }; 1479 1480 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines), 1481 forgot_to_update_kStatusLines); 1482 1483 for (int i = 0; i < kNumUnreadBodies; ++i) 1484 EXPECT_EQ(kStatusLines[i], response_lines[i]); 1485 1486 TestCompletionCallback callback; 1487 scoped_ptr<HttpTransaction> trans( 1488 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1489 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1490 EXPECT_EQ(ERR_IO_PENDING, rv); 1491 rv = callback.WaitForResult(); 1492 EXPECT_EQ(OK, rv); 1493 const HttpResponseInfo* response = trans->GetResponseInfo(); 1494 ASSERT_TRUE(response != NULL); 1495 ASSERT_TRUE(response->headers.get() != NULL); 1496 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1497 std::string response_data; 1498 rv = ReadTransaction(trans.get(), &response_data); 1499 EXPECT_EQ(OK, rv); 1500 EXPECT_EQ("hello", response_data); 1501 } 1502 1503 // Test the request-challenge-retry sequence for basic auth. 1504 // (basic auth is the easiest to mock, because it has no randomness). 1505 TEST_P(HttpNetworkTransactionTest, BasicAuth) { 1506 HttpRequestInfo request; 1507 request.method = "GET"; 1508 request.url = GURL("http://www.google.com/"); 1509 request.load_flags = 0; 1510 1511 CapturingNetLog log; 1512 session_deps_.net_log = &log; 1513 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1514 scoped_ptr<HttpTransaction> trans( 1515 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1516 1517 MockWrite data_writes1[] = { 1518 MockWrite("GET / HTTP/1.1\r\n" 1519 "Host: www.google.com\r\n" 1520 "Connection: keep-alive\r\n\r\n"), 1521 }; 1522 1523 MockRead data_reads1[] = { 1524 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1525 // Give a couple authenticate options (only the middle one is actually 1526 // supported). 1527 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed. 1528 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1529 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 1530 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1531 // Large content-length -- won't matter, as connection will be reset. 1532 MockRead("Content-Length: 10000\r\n\r\n"), 1533 MockRead(SYNCHRONOUS, ERR_FAILED), 1534 }; 1535 1536 // After calling trans->RestartWithAuth(), this is the request we should 1537 // be issuing -- the final header line contains the credentials. 1538 MockWrite data_writes2[] = { 1539 MockWrite("GET / HTTP/1.1\r\n" 1540 "Host: www.google.com\r\n" 1541 "Connection: keep-alive\r\n" 1542 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1543 }; 1544 1545 // Lastly, the server responds with the actual content. 1546 MockRead data_reads2[] = { 1547 MockRead("HTTP/1.0 200 OK\r\n"), 1548 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1549 MockRead("Content-Length: 100\r\n\r\n"), 1550 MockRead(SYNCHRONOUS, OK), 1551 }; 1552 1553 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1554 data_writes1, arraysize(data_writes1)); 1555 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1556 data_writes2, arraysize(data_writes2)); 1557 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1558 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1559 1560 TestCompletionCallback callback1; 1561 1562 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1563 EXPECT_EQ(ERR_IO_PENDING, rv); 1564 1565 rv = callback1.WaitForResult(); 1566 EXPECT_EQ(OK, rv); 1567 1568 LoadTimingInfo load_timing_info1; 1569 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); 1570 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); 1571 1572 const HttpResponseInfo* response = trans->GetResponseInfo(); 1573 ASSERT_TRUE(response != NULL); 1574 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 1575 1576 TestCompletionCallback callback2; 1577 1578 rv = trans->RestartWithAuth( 1579 AuthCredentials(kFoo, kBar), callback2.callback()); 1580 EXPECT_EQ(ERR_IO_PENDING, rv); 1581 1582 rv = callback2.WaitForResult(); 1583 EXPECT_EQ(OK, rv); 1584 1585 LoadTimingInfo load_timing_info2; 1586 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); 1587 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES); 1588 // The load timing after restart should have a new socket ID, and times after 1589 // those of the first load timing. 1590 EXPECT_LE(load_timing_info1.receive_headers_end, 1591 load_timing_info2.connect_timing.connect_start); 1592 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 1593 1594 response = trans->GetResponseInfo(); 1595 ASSERT_TRUE(response != NULL); 1596 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1597 EXPECT_EQ(100, response->headers->GetContentLength()); 1598 } 1599 1600 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) { 1601 HttpRequestInfo request; 1602 request.method = "GET"; 1603 request.url = GURL("http://www.google.com/"); 1604 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 1605 1606 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1607 scoped_ptr<HttpTransaction> trans( 1608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1609 1610 MockWrite data_writes[] = { 1611 MockWrite("GET / HTTP/1.1\r\n" 1612 "Host: www.google.com\r\n" 1613 "Connection: keep-alive\r\n\r\n"), 1614 }; 1615 1616 MockRead data_reads[] = { 1617 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1618 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1619 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1620 // Large content-length -- won't matter, as connection will be reset. 1621 MockRead("Content-Length: 10000\r\n\r\n"), 1622 MockRead(SYNCHRONOUS, ERR_FAILED), 1623 }; 1624 1625 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 1626 data_writes, arraysize(data_writes)); 1627 session_deps_.socket_factory->AddSocketDataProvider(&data); 1628 TestCompletionCallback callback; 1629 1630 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1631 EXPECT_EQ(ERR_IO_PENDING, rv); 1632 1633 rv = callback.WaitForResult(); 1634 EXPECT_EQ(0, rv); 1635 1636 const HttpResponseInfo* response = trans->GetResponseInfo(); 1637 ASSERT_TRUE(response != NULL); 1638 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1639 } 1640 1641 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 1642 // connection. 1643 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) { 1644 HttpRequestInfo request; 1645 request.method = "GET"; 1646 request.url = GURL("http://www.google.com/"); 1647 request.load_flags = 0; 1648 1649 CapturingNetLog log; 1650 session_deps_.net_log = &log; 1651 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1652 1653 MockWrite data_writes1[] = { 1654 MockWrite("GET / HTTP/1.1\r\n" 1655 "Host: www.google.com\r\n" 1656 "Connection: keep-alive\r\n\r\n"), 1657 1658 // After calling trans->RestartWithAuth(), this is the request we should 1659 // be issuing -- the final header line contains the credentials. 1660 MockWrite("GET / HTTP/1.1\r\n" 1661 "Host: www.google.com\r\n" 1662 "Connection: keep-alive\r\n" 1663 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1664 }; 1665 1666 MockRead data_reads1[] = { 1667 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1668 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1669 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1670 MockRead("Content-Length: 14\r\n\r\n"), 1671 MockRead("Unauthorized\r\n"), 1672 1673 // Lastly, the server responds with the actual content. 1674 MockRead("HTTP/1.1 200 OK\r\n"), 1675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1676 MockRead("Content-Length: 5\r\n\r\n"), 1677 MockRead("Hello"), 1678 }; 1679 1680 // If there is a regression where we disconnect a Keep-Alive 1681 // connection during an auth roundtrip, we'll end up reading this. 1682 MockRead data_reads2[] = { 1683 MockRead(SYNCHRONOUS, ERR_FAILED), 1684 }; 1685 1686 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1687 data_writes1, arraysize(data_writes1)); 1688 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1689 NULL, 0); 1690 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1691 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1692 1693 TestCompletionCallback callback1; 1694 1695 scoped_ptr<HttpTransaction> trans( 1696 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1697 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1698 EXPECT_EQ(ERR_IO_PENDING, rv); 1699 1700 rv = callback1.WaitForResult(); 1701 EXPECT_EQ(OK, rv); 1702 1703 LoadTimingInfo load_timing_info1; 1704 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); 1705 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); 1706 1707 const HttpResponseInfo* response = trans->GetResponseInfo(); 1708 ASSERT_TRUE(response != NULL); 1709 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 1710 1711 TestCompletionCallback callback2; 1712 1713 rv = trans->RestartWithAuth( 1714 AuthCredentials(kFoo, kBar), callback2.callback()); 1715 EXPECT_EQ(ERR_IO_PENDING, rv); 1716 1717 rv = callback2.WaitForResult(); 1718 EXPECT_EQ(OK, rv); 1719 1720 LoadTimingInfo load_timing_info2; 1721 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); 1722 TestLoadTimingReused(load_timing_info2); 1723 // The load timing after restart should have the same socket ID, and times 1724 // those of the first load timing. 1725 EXPECT_LE(load_timing_info1.receive_headers_end, 1726 load_timing_info2.send_start); 1727 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 1728 1729 response = trans->GetResponseInfo(); 1730 ASSERT_TRUE(response != NULL); 1731 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1732 EXPECT_EQ(5, response->headers->GetContentLength()); 1733 } 1734 1735 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 1736 // connection and with no response body to drain. 1737 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { 1738 HttpRequestInfo request; 1739 request.method = "GET"; 1740 request.url = GURL("http://www.google.com/"); 1741 request.load_flags = 0; 1742 1743 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1744 1745 MockWrite data_writes1[] = { 1746 MockWrite("GET / HTTP/1.1\r\n" 1747 "Host: www.google.com\r\n" 1748 "Connection: keep-alive\r\n\r\n"), 1749 1750 // After calling trans->RestartWithAuth(), this is the request we should 1751 // be issuing -- the final header line contains the credentials. 1752 MockWrite("GET / HTTP/1.1\r\n" 1753 "Host: www.google.com\r\n" 1754 "Connection: keep-alive\r\n" 1755 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1756 }; 1757 1758 MockRead data_reads1[] = { 1759 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1760 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1761 MockRead("Content-Length: 0\r\n\r\n"), // No response body. 1762 1763 // Lastly, the server responds with the actual content. 1764 MockRead("HTTP/1.1 200 OK\r\n"), 1765 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1766 MockRead("Content-Length: 5\r\n\r\n"), 1767 MockRead("hello"), 1768 }; 1769 1770 // An incorrect reconnect would cause this to be read. 1771 MockRead data_reads2[] = { 1772 MockRead(SYNCHRONOUS, ERR_FAILED), 1773 }; 1774 1775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1776 data_writes1, arraysize(data_writes1)); 1777 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1778 NULL, 0); 1779 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1780 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1781 1782 TestCompletionCallback callback1; 1783 1784 scoped_ptr<HttpTransaction> trans( 1785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1786 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1787 EXPECT_EQ(ERR_IO_PENDING, rv); 1788 1789 rv = callback1.WaitForResult(); 1790 EXPECT_EQ(OK, rv); 1791 1792 const HttpResponseInfo* response = trans->GetResponseInfo(); 1793 ASSERT_TRUE(response != NULL); 1794 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 1795 1796 TestCompletionCallback callback2; 1797 1798 rv = trans->RestartWithAuth( 1799 AuthCredentials(kFoo, kBar), callback2.callback()); 1800 EXPECT_EQ(ERR_IO_PENDING, rv); 1801 1802 rv = callback2.WaitForResult(); 1803 EXPECT_EQ(OK, rv); 1804 1805 response = trans->GetResponseInfo(); 1806 ASSERT_TRUE(response != NULL); 1807 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1808 EXPECT_EQ(5, response->headers->GetContentLength()); 1809 } 1810 1811 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 1812 // connection and with a large response body to drain. 1813 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { 1814 HttpRequestInfo request; 1815 request.method = "GET"; 1816 request.url = GURL("http://www.google.com/"); 1817 request.load_flags = 0; 1818 1819 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1820 1821 MockWrite data_writes1[] = { 1822 MockWrite("GET / HTTP/1.1\r\n" 1823 "Host: www.google.com\r\n" 1824 "Connection: keep-alive\r\n\r\n"), 1825 1826 // After calling trans->RestartWithAuth(), this is the request we should 1827 // be issuing -- the final header line contains the credentials. 1828 MockWrite("GET / HTTP/1.1\r\n" 1829 "Host: www.google.com\r\n" 1830 "Connection: keep-alive\r\n" 1831 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1832 }; 1833 1834 // Respond with 5 kb of response body. 1835 std::string large_body_string("Unauthorized"); 1836 large_body_string.append(5 * 1024, ' '); 1837 large_body_string.append("\r\n"); 1838 1839 MockRead data_reads1[] = { 1840 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1841 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1842 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1843 // 5134 = 12 + 5 * 1024 + 2 1844 MockRead("Content-Length: 5134\r\n\r\n"), 1845 MockRead(ASYNC, large_body_string.data(), large_body_string.size()), 1846 1847 // Lastly, the server responds with the actual content. 1848 MockRead("HTTP/1.1 200 OK\r\n"), 1849 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1850 MockRead("Content-Length: 5\r\n\r\n"), 1851 MockRead("hello"), 1852 }; 1853 1854 // An incorrect reconnect would cause this to be read. 1855 MockRead data_reads2[] = { 1856 MockRead(SYNCHRONOUS, ERR_FAILED), 1857 }; 1858 1859 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1860 data_writes1, arraysize(data_writes1)); 1861 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1862 NULL, 0); 1863 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1864 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1865 1866 TestCompletionCallback callback1; 1867 1868 scoped_ptr<HttpTransaction> trans( 1869 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1870 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1871 EXPECT_EQ(ERR_IO_PENDING, rv); 1872 1873 rv = callback1.WaitForResult(); 1874 EXPECT_EQ(OK, rv); 1875 1876 const HttpResponseInfo* response = trans->GetResponseInfo(); 1877 ASSERT_TRUE(response != NULL); 1878 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 1879 1880 TestCompletionCallback callback2; 1881 1882 rv = trans->RestartWithAuth( 1883 AuthCredentials(kFoo, kBar), callback2.callback()); 1884 EXPECT_EQ(ERR_IO_PENDING, rv); 1885 1886 rv = callback2.WaitForResult(); 1887 EXPECT_EQ(OK, rv); 1888 1889 response = trans->GetResponseInfo(); 1890 ASSERT_TRUE(response != NULL); 1891 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1892 EXPECT_EQ(5, response->headers->GetContentLength()); 1893 } 1894 1895 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 1896 // connection, but the server gets impatient and closes the connection. 1897 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { 1898 HttpRequestInfo request; 1899 request.method = "GET"; 1900 request.url = GURL("http://www.google.com/"); 1901 request.load_flags = 0; 1902 1903 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1904 1905 MockWrite data_writes1[] = { 1906 MockWrite("GET / HTTP/1.1\r\n" 1907 "Host: www.google.com\r\n" 1908 "Connection: keep-alive\r\n\r\n"), 1909 // This simulates the seemingly successful write to a closed connection 1910 // if the bug is not fixed. 1911 MockWrite("GET / HTTP/1.1\r\n" 1912 "Host: www.google.com\r\n" 1913 "Connection: keep-alive\r\n" 1914 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1915 }; 1916 1917 MockRead data_reads1[] = { 1918 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1919 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1920 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1921 MockRead("Content-Length: 14\r\n\r\n"), 1922 // Tell MockTCPClientSocket to simulate the server closing the connection. 1923 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 1924 MockRead("Unauthorized\r\n"), 1925 MockRead(SYNCHRONOUS, OK), // The server closes the connection. 1926 }; 1927 1928 // After calling trans->RestartWithAuth(), this is the request we should 1929 // be issuing -- the final header line contains the credentials. 1930 MockWrite data_writes2[] = { 1931 MockWrite("GET / HTTP/1.1\r\n" 1932 "Host: www.google.com\r\n" 1933 "Connection: keep-alive\r\n" 1934 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1935 }; 1936 1937 // Lastly, the server responds with the actual content. 1938 MockRead data_reads2[] = { 1939 MockRead("HTTP/1.1 200 OK\r\n"), 1940 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1941 MockRead("Content-Length: 5\r\n\r\n"), 1942 MockRead("hello"), 1943 }; 1944 1945 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1946 data_writes1, arraysize(data_writes1)); 1947 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1948 data_writes2, arraysize(data_writes2)); 1949 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1950 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1951 1952 TestCompletionCallback callback1; 1953 1954 scoped_ptr<HttpTransaction> trans( 1955 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1956 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1957 EXPECT_EQ(ERR_IO_PENDING, rv); 1958 1959 rv = callback1.WaitForResult(); 1960 EXPECT_EQ(OK, rv); 1961 1962 const HttpResponseInfo* response = trans->GetResponseInfo(); 1963 ASSERT_TRUE(response != NULL); 1964 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 1965 1966 TestCompletionCallback callback2; 1967 1968 rv = trans->RestartWithAuth( 1969 AuthCredentials(kFoo, kBar), callback2.callback()); 1970 EXPECT_EQ(ERR_IO_PENDING, rv); 1971 1972 rv = callback2.WaitForResult(); 1973 EXPECT_EQ(OK, rv); 1974 1975 response = trans->GetResponseInfo(); 1976 ASSERT_TRUE(response != NULL); 1977 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1978 EXPECT_EQ(5, response->headers->GetContentLength()); 1979 } 1980 1981 // Test the request-challenge-retry sequence for basic auth, over a connection 1982 // that requires a restart when setting up an SSL tunnel. 1983 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { 1984 HttpRequestInfo request; 1985 request.method = "GET"; 1986 request.url = GURL("https://www.google.com/"); 1987 // when the no authentication data flag is set. 1988 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 1989 1990 // Configure against proxy server "myproxy:70". 1991 session_deps_.proxy_service.reset( 1992 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 1993 CapturingBoundNetLog log; 1994 session_deps_.net_log = log.bound().net_log(); 1995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1996 1997 // Since we have proxy, should try to establish tunnel. 1998 MockWrite data_writes1[] = { 1999 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2000 "Host: www.google.com\r\n" 2001 "Proxy-Connection: keep-alive\r\n\r\n"), 2002 2003 // After calling trans->RestartWithAuth(), this is the request we should 2004 // be issuing -- the final header line contains the credentials. 2005 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2006 "Host: www.google.com\r\n" 2007 "Proxy-Connection: keep-alive\r\n" 2008 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2009 2010 MockWrite("GET / HTTP/1.1\r\n" 2011 "Host: www.google.com\r\n" 2012 "Connection: keep-alive\r\n\r\n"), 2013 }; 2014 2015 // The proxy responds to the connect with a 407, using a persistent 2016 // connection. 2017 MockRead data_reads1[] = { 2018 // No credentials. 2019 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2020 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2021 MockRead("Proxy-Connection: close\r\n\r\n"), 2022 2023 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2024 2025 MockRead("HTTP/1.1 200 OK\r\n"), 2026 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2027 MockRead("Content-Length: 5\r\n\r\n"), 2028 MockRead(SYNCHRONOUS, "hello"), 2029 }; 2030 2031 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2032 data_writes1, arraysize(data_writes1)); 2033 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2034 SSLSocketDataProvider ssl(ASYNC, OK); 2035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2036 2037 TestCompletionCallback callback1; 2038 2039 scoped_ptr<HttpTransaction> trans( 2040 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2041 2042 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2043 EXPECT_EQ(ERR_IO_PENDING, rv); 2044 2045 rv = callback1.WaitForResult(); 2046 EXPECT_EQ(OK, rv); 2047 net::CapturingNetLog::CapturedEntryList entries; 2048 log.GetEntries(&entries); 2049 size_t pos = ExpectLogContainsSomewhere( 2050 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2051 NetLog::PHASE_NONE); 2052 ExpectLogContainsSomewhere( 2053 entries, pos, 2054 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2055 NetLog::PHASE_NONE); 2056 2057 const HttpResponseInfo* response = trans->GetResponseInfo(); 2058 ASSERT_TRUE(response != NULL); 2059 ASSERT_FALSE(response->headers.get() == NULL); 2060 EXPECT_EQ(407, response->headers->response_code()); 2061 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2062 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2063 2064 LoadTimingInfo load_timing_info; 2065 // CONNECT requests and responses are handled at the connect job level, so 2066 // the transaction does not yet have a connection. 2067 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); 2068 2069 TestCompletionCallback callback2; 2070 2071 rv = trans->RestartWithAuth( 2072 AuthCredentials(kFoo, kBar), callback2.callback()); 2073 EXPECT_EQ(ERR_IO_PENDING, rv); 2074 2075 rv = callback2.WaitForResult(); 2076 EXPECT_EQ(OK, rv); 2077 2078 response = trans->GetResponseInfo(); 2079 ASSERT_TRUE(response != NULL); 2080 2081 EXPECT_TRUE(response->headers->IsKeepAlive()); 2082 EXPECT_EQ(200, response->headers->response_code()); 2083 EXPECT_EQ(5, response->headers->GetContentLength()); 2084 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2085 2086 // The password prompt info should not be set. 2087 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2088 2089 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2090 TestLoadTimingNotReusedWithPac(load_timing_info, 2091 CONNECT_TIMING_HAS_SSL_TIMES); 2092 2093 trans.reset(); 2094 session->CloseAllConnections(); 2095 } 2096 2097 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2098 // proxy connection, when setting up an SSL tunnel. 2099 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { 2100 HttpRequestInfo request; 2101 request.method = "GET"; 2102 request.url = GURL("https://www.google.com/"); 2103 // Ensure that proxy authentication is attempted even 2104 // when the no authentication data flag is set. 2105 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 2106 2107 // Configure against proxy server "myproxy:70". 2108 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2109 CapturingBoundNetLog log; 2110 session_deps_.net_log = log.bound().net_log(); 2111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2112 2113 scoped_ptr<HttpTransaction> trans( 2114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2115 2116 // Since we have proxy, should try to establish tunnel. 2117 MockWrite data_writes1[] = { 2118 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2119 "Host: www.google.com\r\n" 2120 "Proxy-Connection: keep-alive\r\n\r\n"), 2121 2122 // After calling trans->RestartWithAuth(), this is the request we should 2123 // be issuing -- the final header line contains the credentials. 2124 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2125 "Host: www.google.com\r\n" 2126 "Proxy-Connection: keep-alive\r\n" 2127 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 2128 }; 2129 2130 // The proxy responds to the connect with a 407, using a persistent 2131 // connection. 2132 MockRead data_reads1[] = { 2133 // No credentials. 2134 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2135 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2136 MockRead("Content-Length: 10\r\n\r\n"), 2137 MockRead("0123456789"), 2138 2139 // Wrong credentials (wrong password). 2140 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2141 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2142 MockRead("Content-Length: 10\r\n\r\n"), 2143 // No response body because the test stops reading here. 2144 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 2145 }; 2146 2147 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2148 data_writes1, arraysize(data_writes1)); 2149 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2150 2151 TestCompletionCallback callback1; 2152 2153 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2154 EXPECT_EQ(ERR_IO_PENDING, rv); 2155 2156 rv = callback1.WaitForResult(); 2157 EXPECT_EQ(OK, rv); 2158 net::CapturingNetLog::CapturedEntryList entries; 2159 log.GetEntries(&entries); 2160 size_t pos = ExpectLogContainsSomewhere( 2161 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2162 NetLog::PHASE_NONE); 2163 ExpectLogContainsSomewhere( 2164 entries, pos, 2165 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2166 NetLog::PHASE_NONE); 2167 2168 const HttpResponseInfo* response = trans->GetResponseInfo(); 2169 ASSERT_TRUE(response != NULL); 2170 ASSERT_FALSE(response->headers.get() == NULL); 2171 EXPECT_TRUE(response->headers->IsKeepAlive()); 2172 EXPECT_EQ(407, response->headers->response_code()); 2173 EXPECT_EQ(10, response->headers->GetContentLength()); 2174 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2175 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2176 2177 TestCompletionCallback callback2; 2178 2179 // Wrong password (should be "bar"). 2180 rv = trans->RestartWithAuth( 2181 AuthCredentials(kFoo, kBaz), callback2.callback()); 2182 EXPECT_EQ(ERR_IO_PENDING, rv); 2183 2184 rv = callback2.WaitForResult(); 2185 EXPECT_EQ(OK, rv); 2186 2187 response = trans->GetResponseInfo(); 2188 ASSERT_TRUE(response != NULL); 2189 ASSERT_FALSE(response->headers.get() == NULL); 2190 EXPECT_TRUE(response->headers->IsKeepAlive()); 2191 EXPECT_EQ(407, response->headers->response_code()); 2192 EXPECT_EQ(10, response->headers->GetContentLength()); 2193 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2194 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2195 2196 // Flush the idle socket before the NetLog and HttpNetworkTransaction go 2197 // out of scope. 2198 session->CloseAllConnections(); 2199 } 2200 2201 // Test that we don't read the response body when we fail to establish a tunnel, 2202 // even if the user cancels the proxy's auth attempt. 2203 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { 2204 HttpRequestInfo request; 2205 request.method = "GET"; 2206 request.url = GURL("https://www.google.com/"); 2207 request.load_flags = 0; 2208 2209 // Configure against proxy server "myproxy:70". 2210 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2211 2212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2213 2214 scoped_ptr<HttpTransaction> trans( 2215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2216 2217 // Since we have proxy, should try to establish tunnel. 2218 MockWrite data_writes[] = { 2219 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2220 "Host: www.google.com\r\n" 2221 "Proxy-Connection: keep-alive\r\n\r\n"), 2222 }; 2223 2224 // The proxy responds to the connect with a 407. 2225 MockRead data_reads[] = { 2226 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2227 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2228 MockRead("Content-Length: 10\r\n\r\n"), 2229 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 2230 }; 2231 2232 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 2233 data_writes, arraysize(data_writes)); 2234 session_deps_.socket_factory->AddSocketDataProvider(&data); 2235 2236 TestCompletionCallback callback; 2237 2238 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 2239 EXPECT_EQ(ERR_IO_PENDING, rv); 2240 2241 rv = callback.WaitForResult(); 2242 EXPECT_EQ(OK, rv); 2243 2244 const HttpResponseInfo* response = trans->GetResponseInfo(); 2245 ASSERT_TRUE(response != NULL); 2246 2247 EXPECT_TRUE(response->headers->IsKeepAlive()); 2248 EXPECT_EQ(407, response->headers->response_code()); 2249 EXPECT_EQ(10, response->headers->GetContentLength()); 2250 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2251 2252 std::string response_data; 2253 rv = ReadTransaction(trans.get(), &response_data); 2254 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 2255 2256 // Flush the idle socket before the HttpNetworkTransaction goes out of scope. 2257 session->CloseAllConnections(); 2258 } 2259 2260 // Test when a server (non-proxy) returns a 407 (proxy-authenticate). 2261 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH. 2262 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) { 2263 HttpRequestInfo request; 2264 request.method = "GET"; 2265 request.url = GURL("http://www.google.com/"); 2266 request.load_flags = 0; 2267 2268 // We are using a DIRECT connection (i.e. no proxy) for this session. 2269 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2270 scoped_ptr<HttpTransaction> trans( 2271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 2272 2273 MockWrite data_writes1[] = { 2274 MockWrite("GET / HTTP/1.1\r\n" 2275 "Host: www.google.com\r\n" 2276 "Connection: keep-alive\r\n\r\n"), 2277 }; 2278 2279 MockRead data_reads1[] = { 2280 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"), 2281 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2282 // Large content-length -- won't matter, as connection will be reset. 2283 MockRead("Content-Length: 10000\r\n\r\n"), 2284 MockRead(SYNCHRONOUS, ERR_FAILED), 2285 }; 2286 2287 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2288 data_writes1, arraysize(data_writes1)); 2289 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2290 2291 TestCompletionCallback callback; 2292 2293 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 2294 EXPECT_EQ(ERR_IO_PENDING, rv); 2295 2296 rv = callback.WaitForResult(); 2297 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 2298 } 2299 2300 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication) 2301 // through a non-authenticating proxy. The request should fail with 2302 // ERR_UNEXPECTED_PROXY_AUTH. 2303 // Note that it is impossible to detect if an HTTP server returns a 407 through 2304 // a non-authenticating proxy - there is nothing to indicate whether the 2305 // response came from the proxy or the server, so it is treated as if the proxy 2306 // issued the challenge. 2307 TEST_P(HttpNetworkTransactionTest, 2308 HttpsServerRequestsProxyAuthThroughProxy) { 2309 HttpRequestInfo request; 2310 request.method = "GET"; 2311 request.url = GURL("https://www.google.com/"); 2312 2313 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2314 CapturingBoundNetLog log; 2315 session_deps_.net_log = log.bound().net_log(); 2316 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2317 2318 // Since we have proxy, should try to establish tunnel. 2319 MockWrite data_writes1[] = { 2320 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2321 "Host: www.google.com\r\n" 2322 "Proxy-Connection: keep-alive\r\n\r\n"), 2323 2324 MockWrite("GET / HTTP/1.1\r\n" 2325 "Host: www.google.com\r\n" 2326 "Connection: keep-alive\r\n\r\n"), 2327 }; 2328 2329 MockRead data_reads1[] = { 2330 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2331 2332 MockRead("HTTP/1.1 407 Unauthorized\r\n"), 2333 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2334 MockRead("\r\n"), 2335 MockRead(SYNCHRONOUS, OK), 2336 }; 2337 2338 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2339 data_writes1, arraysize(data_writes1)); 2340 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2341 SSLSocketDataProvider ssl(ASYNC, OK); 2342 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2343 2344 TestCompletionCallback callback1; 2345 2346 scoped_ptr<HttpTransaction> trans( 2347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2348 2349 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2350 EXPECT_EQ(ERR_IO_PENDING, rv); 2351 2352 rv = callback1.WaitForResult(); 2353 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 2354 net::CapturingNetLog::CapturedEntryList entries; 2355 log.GetEntries(&entries); 2356 size_t pos = ExpectLogContainsSomewhere( 2357 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2358 NetLog::PHASE_NONE); 2359 ExpectLogContainsSomewhere( 2360 entries, pos, 2361 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2362 NetLog::PHASE_NONE); 2363 } 2364 2365 // Test the load timing for HTTPS requests with an HTTP proxy. 2366 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) { 2367 HttpRequestInfo request1; 2368 request1.method = "GET"; 2369 request1.url = GURL("https://www.google.com/1"); 2370 2371 HttpRequestInfo request2; 2372 request2.method = "GET"; 2373 request2.url = GURL("https://www.google.com/2"); 2374 2375 // Configure against proxy server "myproxy:70". 2376 session_deps_.proxy_service.reset( 2377 ProxyService::CreateFixed("PROXY myproxy:70")); 2378 CapturingBoundNetLog log; 2379 session_deps_.net_log = log.bound().net_log(); 2380 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2381 2382 // Since we have proxy, should try to establish tunnel. 2383 MockWrite data_writes1[] = { 2384 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2385 "Host: www.google.com\r\n" 2386 "Proxy-Connection: keep-alive\r\n\r\n"), 2387 2388 MockWrite("GET /1 HTTP/1.1\r\n" 2389 "Host: www.google.com\r\n" 2390 "Connection: keep-alive\r\n\r\n"), 2391 2392 MockWrite("GET /2 HTTP/1.1\r\n" 2393 "Host: www.google.com\r\n" 2394 "Connection: keep-alive\r\n\r\n"), 2395 }; 2396 2397 // The proxy responds to the connect with a 407, using a persistent 2398 // connection. 2399 MockRead data_reads1[] = { 2400 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2401 2402 MockRead("HTTP/1.1 200 OK\r\n"), 2403 MockRead("Content-Length: 1\r\n\r\n"), 2404 MockRead(SYNCHRONOUS, "1"), 2405 2406 MockRead("HTTP/1.1 200 OK\r\n"), 2407 MockRead("Content-Length: 2\r\n\r\n"), 2408 MockRead(SYNCHRONOUS, "22"), 2409 }; 2410 2411 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2412 data_writes1, arraysize(data_writes1)); 2413 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2414 SSLSocketDataProvider ssl(ASYNC, OK); 2415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2416 2417 TestCompletionCallback callback1; 2418 scoped_ptr<HttpTransaction> trans1( 2419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2420 2421 int rv = trans1->Start(&request1, callback1.callback(), log.bound()); 2422 EXPECT_EQ(ERR_IO_PENDING, rv); 2423 2424 rv = callback1.WaitForResult(); 2425 EXPECT_EQ(OK, rv); 2426 2427 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 2428 ASSERT_TRUE(response1 != NULL); 2429 ASSERT_TRUE(response1->headers.get() != NULL); 2430 EXPECT_EQ(1, response1->headers->GetContentLength()); 2431 2432 LoadTimingInfo load_timing_info1; 2433 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1)); 2434 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES); 2435 2436 trans1.reset(); 2437 2438 TestCompletionCallback callback2; 2439 scoped_ptr<HttpTransaction> trans2( 2440 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2441 2442 rv = trans2->Start(&request2, callback2.callback(), log.bound()); 2443 EXPECT_EQ(ERR_IO_PENDING, rv); 2444 2445 rv = callback2.WaitForResult(); 2446 EXPECT_EQ(OK, rv); 2447 2448 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 2449 ASSERT_TRUE(response2 != NULL); 2450 ASSERT_TRUE(response2->headers.get() != NULL); 2451 EXPECT_EQ(2, response2->headers->GetContentLength()); 2452 2453 LoadTimingInfo load_timing_info2; 2454 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 2455 TestLoadTimingReused(load_timing_info2); 2456 2457 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2458 2459 trans2.reset(); 2460 session->CloseAllConnections(); 2461 } 2462 2463 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script. 2464 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) { 2465 HttpRequestInfo request1; 2466 request1.method = "GET"; 2467 request1.url = GURL("https://www.google.com/1"); 2468 2469 HttpRequestInfo request2; 2470 request2.method = "GET"; 2471 request2.url = GURL("https://www.google.com/2"); 2472 2473 // Configure against proxy server "myproxy:70". 2474 session_deps_.proxy_service.reset( 2475 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 2476 CapturingBoundNetLog log; 2477 session_deps_.net_log = log.bound().net_log(); 2478 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2479 2480 // Since we have proxy, should try to establish tunnel. 2481 MockWrite data_writes1[] = { 2482 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2483 "Host: www.google.com\r\n" 2484 "Proxy-Connection: keep-alive\r\n\r\n"), 2485 2486 MockWrite("GET /1 HTTP/1.1\r\n" 2487 "Host: www.google.com\r\n" 2488 "Connection: keep-alive\r\n\r\n"), 2489 2490 MockWrite("GET /2 HTTP/1.1\r\n" 2491 "Host: www.google.com\r\n" 2492 "Connection: keep-alive\r\n\r\n"), 2493 }; 2494 2495 // The proxy responds to the connect with a 407, using a persistent 2496 // connection. 2497 MockRead data_reads1[] = { 2498 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2499 2500 MockRead("HTTP/1.1 200 OK\r\n"), 2501 MockRead("Content-Length: 1\r\n\r\n"), 2502 MockRead(SYNCHRONOUS, "1"), 2503 2504 MockRead("HTTP/1.1 200 OK\r\n"), 2505 MockRead("Content-Length: 2\r\n\r\n"), 2506 MockRead(SYNCHRONOUS, "22"), 2507 }; 2508 2509 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2510 data_writes1, arraysize(data_writes1)); 2511 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2512 SSLSocketDataProvider ssl(ASYNC, OK); 2513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2514 2515 TestCompletionCallback callback1; 2516 scoped_ptr<HttpTransaction> trans1( 2517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2518 2519 int rv = trans1->Start(&request1, callback1.callback(), log.bound()); 2520 EXPECT_EQ(ERR_IO_PENDING, rv); 2521 2522 rv = callback1.WaitForResult(); 2523 EXPECT_EQ(OK, rv); 2524 2525 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 2526 ASSERT_TRUE(response1 != NULL); 2527 ASSERT_TRUE(response1->headers.get() != NULL); 2528 EXPECT_EQ(1, response1->headers->GetContentLength()); 2529 2530 LoadTimingInfo load_timing_info1; 2531 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1)); 2532 TestLoadTimingNotReusedWithPac(load_timing_info1, 2533 CONNECT_TIMING_HAS_SSL_TIMES); 2534 2535 trans1.reset(); 2536 2537 TestCompletionCallback callback2; 2538 scoped_ptr<HttpTransaction> trans2( 2539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2540 2541 rv = trans2->Start(&request2, callback2.callback(), log.bound()); 2542 EXPECT_EQ(ERR_IO_PENDING, rv); 2543 2544 rv = callback2.WaitForResult(); 2545 EXPECT_EQ(OK, rv); 2546 2547 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 2548 ASSERT_TRUE(response2 != NULL); 2549 ASSERT_TRUE(response2->headers.get() != NULL); 2550 EXPECT_EQ(2, response2->headers->GetContentLength()); 2551 2552 LoadTimingInfo load_timing_info2; 2553 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 2554 TestLoadTimingReusedWithPac(load_timing_info2); 2555 2556 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2557 2558 trans2.reset(); 2559 session->CloseAllConnections(); 2560 } 2561 2562 // Test a simple get through an HTTPS Proxy. 2563 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) { 2564 HttpRequestInfo request; 2565 request.method = "GET"; 2566 request.url = GURL("http://www.google.com/"); 2567 2568 // Configure against https proxy server "proxy:70". 2569 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2570 "https://proxy:70")); 2571 CapturingBoundNetLog log; 2572 session_deps_.net_log = log.bound().net_log(); 2573 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2574 2575 // Since we have proxy, should use full url 2576 MockWrite data_writes1[] = { 2577 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 2578 "Host: www.google.com\r\n" 2579 "Proxy-Connection: keep-alive\r\n\r\n"), 2580 }; 2581 2582 MockRead data_reads1[] = { 2583 MockRead("HTTP/1.1 200 OK\r\n"), 2584 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2585 MockRead("Content-Length: 100\r\n\r\n"), 2586 MockRead(SYNCHRONOUS, OK), 2587 }; 2588 2589 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2590 data_writes1, arraysize(data_writes1)); 2591 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2592 SSLSocketDataProvider ssl(ASYNC, OK); 2593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2594 2595 TestCompletionCallback callback1; 2596 2597 scoped_ptr<HttpTransaction> trans( 2598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2599 2600 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2601 EXPECT_EQ(ERR_IO_PENDING, rv); 2602 2603 rv = callback1.WaitForResult(); 2604 EXPECT_EQ(OK, rv); 2605 2606 LoadTimingInfo load_timing_info; 2607 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2608 TestLoadTimingNotReused(load_timing_info, 2609 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 2610 2611 const HttpResponseInfo* response = trans->GetResponseInfo(); 2612 ASSERT_TRUE(response != NULL); 2613 2614 EXPECT_TRUE(response->headers->IsKeepAlive()); 2615 EXPECT_EQ(200, response->headers->response_code()); 2616 EXPECT_EQ(100, response->headers->GetContentLength()); 2617 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2618 2619 // The password prompt info should not be set. 2620 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2621 } 2622 2623 // Test a SPDY get through an HTTPS Proxy. 2624 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) { 2625 HttpRequestInfo request; 2626 request.method = "GET"; 2627 request.url = GURL("http://www.google.com/"); 2628 request.load_flags = 0; 2629 2630 // Configure against https proxy server "proxy:70". 2631 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2632 "https://proxy:70")); 2633 CapturingBoundNetLog log; 2634 session_deps_.net_log = log.bound().net_log(); 2635 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2636 2637 // fetch http://www.google.com/ via SPDY 2638 scoped_ptr<SpdyFrame> req( 2639 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 2640 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 2641 2642 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2643 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2644 MockRead spdy_reads[] = { 2645 CreateMockRead(*resp), 2646 CreateMockRead(*data), 2647 MockRead(ASYNC, 0, 0), 2648 }; 2649 2650 DelayedSocketData spdy_data( 2651 1, // wait for one write to finish before reading. 2652 spdy_reads, arraysize(spdy_reads), 2653 spdy_writes, arraysize(spdy_writes)); 2654 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 2655 2656 SSLSocketDataProvider ssl(ASYNC, OK); 2657 ssl.SetNextProto(GetParam()); 2658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2659 2660 TestCompletionCallback callback1; 2661 2662 scoped_ptr<HttpTransaction> trans( 2663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2664 2665 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2666 EXPECT_EQ(ERR_IO_PENDING, rv); 2667 2668 rv = callback1.WaitForResult(); 2669 EXPECT_EQ(OK, rv); 2670 2671 LoadTimingInfo load_timing_info; 2672 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2673 TestLoadTimingNotReused(load_timing_info, 2674 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 2675 2676 const HttpResponseInfo* response = trans->GetResponseInfo(); 2677 ASSERT_TRUE(response != NULL); 2678 ASSERT_TRUE(response->headers.get() != NULL); 2679 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 2680 2681 std::string response_data; 2682 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 2683 EXPECT_EQ(kUploadData, response_data); 2684 } 2685 2686 // Test a SPDY get through an HTTPS Proxy. 2687 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) { 2688 HttpRequestInfo request; 2689 request.method = "GET"; 2690 request.url = GURL("http://www.google.com/"); 2691 request.load_flags = 0; 2692 2693 // Configure against https proxy server "myproxy:70". 2694 session_deps_.proxy_service.reset( 2695 ProxyService::CreateFixed("https://myproxy:70")); 2696 CapturingBoundNetLog log; 2697 session_deps_.net_log = log.bound().net_log(); 2698 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2699 2700 // The first request will be a bare GET, the second request will be a 2701 // GET with a Proxy-Authorization header. 2702 scoped_ptr<SpdyFrame> req_get( 2703 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 2704 const char* const kExtraAuthorizationHeaders[] = { 2705 "proxy-authorization", "Basic Zm9vOmJhcg==" 2706 }; 2707 scoped_ptr<SpdyFrame> req_get_authorization( 2708 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders, 2709 arraysize(kExtraAuthorizationHeaders) / 2, 2710 false, 2711 3, 2712 LOWEST, 2713 false)); 2714 MockWrite spdy_writes[] = { 2715 CreateMockWrite(*req_get, 1), 2716 CreateMockWrite(*req_get_authorization, 4), 2717 }; 2718 2719 // The first response is a 407 proxy authentication challenge, and the second 2720 // response will be a 200 response since the second request includes a valid 2721 // Authorization header. 2722 const char* const kExtraAuthenticationHeaders[] = { 2723 "proxy-authenticate", "Basic realm=\"MyRealm1\"" 2724 }; 2725 scoped_ptr<SpdyFrame> resp_authentication( 2726 spdy_util_.ConstructSpdySynReplyError( 2727 "407 Proxy Authentication Required", 2728 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2, 2729 1)); 2730 scoped_ptr<SpdyFrame> body_authentication( 2731 spdy_util_.ConstructSpdyBodyFrame(1, true)); 2732 scoped_ptr<SpdyFrame> resp_data( 2733 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 2734 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true)); 2735 MockRead spdy_reads[] = { 2736 CreateMockRead(*resp_authentication, 2), 2737 CreateMockRead(*body_authentication, 3), 2738 CreateMockRead(*resp_data, 5), 2739 CreateMockRead(*body_data, 6), 2740 MockRead(ASYNC, 0, 7), 2741 }; 2742 2743 OrderedSocketData data( 2744 spdy_reads, arraysize(spdy_reads), 2745 spdy_writes, arraysize(spdy_writes)); 2746 session_deps_.socket_factory->AddSocketDataProvider(&data); 2747 2748 SSLSocketDataProvider ssl(ASYNC, OK); 2749 ssl.SetNextProto(GetParam()); 2750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2751 2752 TestCompletionCallback callback1; 2753 2754 scoped_ptr<HttpTransaction> trans( 2755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2756 2757 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2758 EXPECT_EQ(ERR_IO_PENDING, rv); 2759 2760 rv = callback1.WaitForResult(); 2761 EXPECT_EQ(OK, rv); 2762 2763 const HttpResponseInfo* const response = trans->GetResponseInfo(); 2764 2765 ASSERT_TRUE(response != NULL); 2766 ASSERT_TRUE(response->headers.get() != NULL); 2767 EXPECT_EQ(407, response->headers->response_code()); 2768 EXPECT_TRUE(response->was_fetched_via_spdy); 2769 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2770 2771 TestCompletionCallback callback2; 2772 2773 rv = trans->RestartWithAuth( 2774 AuthCredentials(kFoo, kBar), callback2.callback()); 2775 EXPECT_EQ(ERR_IO_PENDING, rv); 2776 2777 rv = callback2.WaitForResult(); 2778 EXPECT_EQ(OK, rv); 2779 2780 const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 2781 2782 ASSERT_TRUE(response_restart != NULL); 2783 ASSERT_TRUE(response_restart->headers.get() != NULL); 2784 EXPECT_EQ(200, response_restart->headers->response_code()); 2785 // The password prompt info should not be set. 2786 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 2787 } 2788 2789 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server. 2790 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) { 2791 HttpRequestInfo request; 2792 request.method = "GET"; 2793 request.url = GURL("https://www.google.com/"); 2794 request.load_flags = 0; 2795 2796 // Configure against https proxy server "proxy:70". 2797 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2798 "https://proxy:70")); 2799 CapturingBoundNetLog log; 2800 session_deps_.net_log = log.bound().net_log(); 2801 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2802 2803 scoped_ptr<HttpTransaction> trans( 2804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2805 2806 // CONNECT to www.google.com:443 via SPDY 2807 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 2808 LOWEST)); 2809 // fetch https://www.google.com/ via HTTP 2810 2811 const char get[] = "GET / HTTP/1.1\r\n" 2812 "Host: www.google.com\r\n" 2813 "Connection: keep-alive\r\n\r\n"; 2814 scoped_ptr<SpdyFrame> wrapped_get( 2815 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false)); 2816 scoped_ptr<SpdyFrame> conn_resp( 2817 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2818 const char resp[] = "HTTP/1.1 200 OK\r\n" 2819 "Content-Length: 10\r\n\r\n"; 2820 scoped_ptr<SpdyFrame> wrapped_get_resp( 2821 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false)); 2822 scoped_ptr<SpdyFrame> wrapped_body( 2823 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false)); 2824 scoped_ptr<SpdyFrame> window_update( 2825 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size())); 2826 2827 MockWrite spdy_writes[] = { 2828 CreateMockWrite(*connect, 1), 2829 CreateMockWrite(*wrapped_get, 3), 2830 CreateMockWrite(*window_update, 5), 2831 }; 2832 2833 MockRead spdy_reads[] = { 2834 CreateMockRead(*conn_resp, 2, ASYNC), 2835 CreateMockRead(*wrapped_get_resp, 4, ASYNC), 2836 CreateMockRead(*wrapped_body, 6, ASYNC), 2837 CreateMockRead(*wrapped_body, 7, ASYNC), 2838 MockRead(ASYNC, 0, 8), 2839 }; 2840 2841 OrderedSocketData spdy_data( 2842 spdy_reads, arraysize(spdy_reads), 2843 spdy_writes, arraysize(spdy_writes)); 2844 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 2845 2846 SSLSocketDataProvider ssl(ASYNC, OK); 2847 ssl.SetNextProto(GetParam()); 2848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2849 SSLSocketDataProvider ssl2(ASYNC, OK); 2850 ssl2.was_npn_negotiated = false; 2851 ssl2.protocol_negotiated = kProtoUnknown; 2852 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 2853 2854 TestCompletionCallback callback1; 2855 2856 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2857 EXPECT_EQ(ERR_IO_PENDING, rv); 2858 2859 rv = callback1.WaitForResult(); 2860 EXPECT_EQ(OK, rv); 2861 2862 LoadTimingInfo load_timing_info; 2863 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2864 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 2865 2866 const HttpResponseInfo* response = trans->GetResponseInfo(); 2867 ASSERT_TRUE(response != NULL); 2868 ASSERT_TRUE(response->headers.get() != NULL); 2869 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 2870 2871 std::string response_data; 2872 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 2873 EXPECT_EQ("1234567890", response_data); 2874 } 2875 2876 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server. 2877 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) { 2878 HttpRequestInfo request; 2879 request.method = "GET"; 2880 request.url = GURL("https://www.google.com/"); 2881 request.load_flags = 0; 2882 2883 // Configure against https proxy server "proxy:70". 2884 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2885 "https://proxy:70")); 2886 CapturingBoundNetLog log; 2887 session_deps_.net_log = log.bound().net_log(); 2888 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2889 2890 scoped_ptr<HttpTransaction> trans( 2891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2892 2893 // CONNECT to www.google.com:443 via SPDY 2894 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 2895 LOWEST)); 2896 // fetch https://www.google.com/ via SPDY 2897 const char* const kMyUrl = "https://www.google.com/"; 2898 scoped_ptr<SpdyFrame> get( 2899 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST)); 2900 scoped_ptr<SpdyFrame> wrapped_get( 2901 spdy_util_.ConstructWrappedSpdyFrame(get, 1)); 2902 scoped_ptr<SpdyFrame> conn_resp( 2903 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2904 scoped_ptr<SpdyFrame> get_resp( 2905 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2906 scoped_ptr<SpdyFrame> wrapped_get_resp( 2907 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1)); 2908 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2909 scoped_ptr<SpdyFrame> wrapped_body( 2910 spdy_util_.ConstructWrappedSpdyFrame(body, 1)); 2911 scoped_ptr<SpdyFrame> window_update_get_resp( 2912 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size())); 2913 scoped_ptr<SpdyFrame> window_update_body( 2914 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size())); 2915 2916 MockWrite spdy_writes[] = { 2917 CreateMockWrite(*connect, 1), 2918 CreateMockWrite(*wrapped_get, 3), 2919 CreateMockWrite(*window_update_get_resp, 5), 2920 CreateMockWrite(*window_update_body, 7), 2921 }; 2922 2923 MockRead spdy_reads[] = { 2924 CreateMockRead(*conn_resp, 2, ASYNC), 2925 CreateMockRead(*wrapped_get_resp, 4, ASYNC), 2926 CreateMockRead(*wrapped_body, 6, ASYNC), 2927 MockRead(ASYNC, 0, 8), 2928 }; 2929 2930 OrderedSocketData spdy_data( 2931 spdy_reads, arraysize(spdy_reads), 2932 spdy_writes, arraysize(spdy_writes)); 2933 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 2934 2935 SSLSocketDataProvider ssl(ASYNC, OK); 2936 ssl.SetNextProto(GetParam()); 2937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2938 SSLSocketDataProvider ssl2(ASYNC, OK); 2939 ssl2.SetNextProto(GetParam()); 2940 ssl2.protocol_negotiated = GetParam(); 2941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 2942 2943 TestCompletionCallback callback1; 2944 2945 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2946 EXPECT_EQ(ERR_IO_PENDING, rv); 2947 2948 rv = callback1.WaitForResult(); 2949 EXPECT_EQ(OK, rv); 2950 2951 LoadTimingInfo load_timing_info; 2952 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2953 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 2954 2955 const HttpResponseInfo* response = trans->GetResponseInfo(); 2956 ASSERT_TRUE(response != NULL); 2957 ASSERT_TRUE(response->headers.get() != NULL); 2958 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 2959 2960 std::string response_data; 2961 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 2962 EXPECT_EQ(kUploadData, response_data); 2963 } 2964 2965 // Test a SPDY CONNECT failure through an HTTPS Proxy. 2966 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) { 2967 HttpRequestInfo request; 2968 request.method = "GET"; 2969 request.url = GURL("https://www.google.com/"); 2970 request.load_flags = 0; 2971 2972 // Configure against https proxy server "proxy:70". 2973 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2974 "https://proxy:70")); 2975 CapturingBoundNetLog log; 2976 session_deps_.net_log = log.bound().net_log(); 2977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2978 2979 scoped_ptr<HttpTransaction> trans( 2980 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2981 2982 // CONNECT to www.google.com:443 via SPDY 2983 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 2984 LOWEST)); 2985 scoped_ptr<SpdyFrame> get( 2986 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 2987 2988 MockWrite spdy_writes[] = { 2989 CreateMockWrite(*connect, 1), 2990 CreateMockWrite(*get, 3), 2991 }; 2992 2993 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1)); 2994 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2995 MockRead spdy_reads[] = { 2996 CreateMockRead(*resp, 2, ASYNC), 2997 MockRead(ASYNC, 0, 4), 2998 }; 2999 3000 OrderedSocketData spdy_data( 3001 spdy_reads, arraysize(spdy_reads), 3002 spdy_writes, arraysize(spdy_writes)); 3003 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3004 3005 SSLSocketDataProvider ssl(ASYNC, OK); 3006 ssl.SetNextProto(GetParam()); 3007 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3008 SSLSocketDataProvider ssl2(ASYNC, OK); 3009 ssl2.SetNextProto(GetParam()); 3010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 3011 3012 TestCompletionCallback callback1; 3013 3014 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3015 EXPECT_EQ(ERR_IO_PENDING, rv); 3016 3017 rv = callback1.WaitForResult(); 3018 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 3019 3020 // TODO(ttuttle): Anything else to check here? 3021 } 3022 3023 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY 3024 // HTTPS Proxy to different servers. 3025 TEST_P(HttpNetworkTransactionTest, 3026 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) { 3027 // Configure against https proxy server "proxy:70". 3028 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3029 "https://proxy:70")); 3030 CapturingBoundNetLog log; 3031 session_deps_.net_log = log.bound().net_log(); 3032 scoped_refptr<HttpNetworkSession> session( 3033 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3034 3035 HttpRequestInfo request1; 3036 request1.method = "GET"; 3037 request1.url = GURL("https://www.google.com/"); 3038 request1.load_flags = 0; 3039 3040 HttpRequestInfo request2; 3041 request2.method = "GET"; 3042 request2.url = GURL("https://news.google.com/"); 3043 request2.load_flags = 0; 3044 3045 // CONNECT to www.google.com:443 via SPDY. 3046 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3047 LOWEST)); 3048 scoped_ptr<SpdyFrame> conn_resp1( 3049 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3050 3051 // Fetch https://www.google.com/ via HTTP. 3052 const char get1[] = "GET / HTTP/1.1\r\n" 3053 "Host: www.google.com\r\n" 3054 "Connection: keep-alive\r\n\r\n"; 3055 scoped_ptr<SpdyFrame> wrapped_get1( 3056 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false)); 3057 const char resp1[] = "HTTP/1.1 200 OK\r\n" 3058 "Content-Length: 1\r\n\r\n"; 3059 scoped_ptr<SpdyFrame> wrapped_get_resp1( 3060 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false)); 3061 scoped_ptr<SpdyFrame> wrapped_body1( 3062 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false)); 3063 scoped_ptr<SpdyFrame> window_update( 3064 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size())); 3065 3066 // CONNECT to news.google.com:443 via SPDY. 3067 const char* const kConnectHeaders2[] = { 3068 spdy_util_.GetMethodKey(), "CONNECT", 3069 spdy_util_.GetPathKey(), "news.google.com:443", 3070 spdy_util_.GetHostKey(), "news.google.com", 3071 spdy_util_.GetVersionKey(), "HTTP/1.1", 3072 }; 3073 scoped_ptr<SpdyFrame> connect2( 3074 spdy_util_.ConstructSpdyControlFrame(NULL, 3075 0, 3076 /*compressed*/ false, 3077 3, 3078 LOWEST, 3079 SYN_STREAM, 3080 CONTROL_FLAG_NONE, 3081 kConnectHeaders2, 3082 arraysize(kConnectHeaders2), 3083 0)); 3084 scoped_ptr<SpdyFrame> conn_resp2( 3085 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3086 3087 // Fetch https://news.google.com/ via HTTP. 3088 const char get2[] = "GET / HTTP/1.1\r\n" 3089 "Host: news.google.com\r\n" 3090 "Connection: keep-alive\r\n\r\n"; 3091 scoped_ptr<SpdyFrame> wrapped_get2( 3092 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false)); 3093 const char resp2[] = "HTTP/1.1 200 OK\r\n" 3094 "Content-Length: 2\r\n\r\n"; 3095 scoped_ptr<SpdyFrame> wrapped_get_resp2( 3096 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false)); 3097 scoped_ptr<SpdyFrame> wrapped_body2( 3098 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false)); 3099 3100 MockWrite spdy_writes[] = { 3101 CreateMockWrite(*connect1, 0), 3102 CreateMockWrite(*wrapped_get1, 2), 3103 CreateMockWrite(*connect2, 5), 3104 CreateMockWrite(*wrapped_get2, 7), 3105 }; 3106 3107 MockRead spdy_reads[] = { 3108 CreateMockRead(*conn_resp1, 1, ASYNC), 3109 CreateMockRead(*wrapped_get_resp1, 3, ASYNC), 3110 CreateMockRead(*wrapped_body1, 4, ASYNC), 3111 CreateMockRead(*conn_resp2, 6, ASYNC), 3112 CreateMockRead(*wrapped_get_resp2, 8, ASYNC), 3113 CreateMockRead(*wrapped_body2, 9, ASYNC), 3114 MockRead(ASYNC, 0, 10), 3115 }; 3116 3117 DeterministicSocketData spdy_data( 3118 spdy_reads, arraysize(spdy_reads), 3119 spdy_writes, arraysize(spdy_writes)); 3120 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3121 3122 SSLSocketDataProvider ssl(ASYNC, OK); 3123 ssl.SetNextProto(GetParam()); 3124 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3125 SSLSocketDataProvider ssl2(ASYNC, OK); 3126 ssl2.was_npn_negotiated = false; 3127 ssl2.protocol_negotiated = kProtoUnknown; 3128 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 3129 SSLSocketDataProvider ssl3(ASYNC, OK); 3130 ssl3.was_npn_negotiated = false; 3131 ssl3.protocol_negotiated = kProtoUnknown; 3132 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3); 3133 3134 TestCompletionCallback callback; 3135 3136 scoped_ptr<HttpTransaction> trans( 3137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3138 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3139 EXPECT_EQ(ERR_IO_PENDING, rv); 3140 // The first connect and request, each of their responses, and the body. 3141 spdy_data.RunFor(5); 3142 3143 rv = callback.WaitForResult(); 3144 EXPECT_EQ(OK, rv); 3145 3146 LoadTimingInfo load_timing_info; 3147 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3148 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3149 3150 const HttpResponseInfo* response = trans->GetResponseInfo(); 3151 ASSERT_TRUE(response != NULL); 3152 ASSERT_TRUE(response->headers.get() != NULL); 3153 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3154 3155 std::string response_data; 3156 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3157 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback())); 3158 3159 scoped_ptr<HttpTransaction> trans2( 3160 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3161 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3162 EXPECT_EQ(ERR_IO_PENDING, rv); 3163 3164 // The second connect and request, each of their responses, and the body. 3165 spdy_data.RunFor(5); 3166 rv = callback.WaitForResult(); 3167 EXPECT_EQ(OK, rv); 3168 3169 LoadTimingInfo load_timing_info2; 3170 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3171 // Even though the SPDY connection is reused, a new tunnelled connection has 3172 // to be created, so the socket's load timing looks like a fresh connection. 3173 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES); 3174 3175 // The requests should have different IDs, since they each are using their own 3176 // separate stream. 3177 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3178 3179 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback())); 3180 } 3181 3182 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY 3183 // HTTPS Proxy to the same server. 3184 TEST_P(HttpNetworkTransactionTest, 3185 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) { 3186 // Configure against https proxy server "proxy:70". 3187 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3188 "https://proxy:70")); 3189 CapturingBoundNetLog log; 3190 session_deps_.net_log = log.bound().net_log(); 3191 scoped_refptr<HttpNetworkSession> session( 3192 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3193 3194 HttpRequestInfo request1; 3195 request1.method = "GET"; 3196 request1.url = GURL("https://www.google.com/"); 3197 request1.load_flags = 0; 3198 3199 HttpRequestInfo request2; 3200 request2.method = "GET"; 3201 request2.url = GURL("https://www.google.com/2"); 3202 request2.load_flags = 0; 3203 3204 // CONNECT to www.google.com:443 via SPDY. 3205 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3206 LOWEST)); 3207 scoped_ptr<SpdyFrame> conn_resp1( 3208 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3209 3210 // Fetch https://www.google.com/ via HTTP. 3211 const char get1[] = "GET / HTTP/1.1\r\n" 3212 "Host: www.google.com\r\n" 3213 "Connection: keep-alive\r\n\r\n"; 3214 scoped_ptr<SpdyFrame> wrapped_get1( 3215 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false)); 3216 const char resp1[] = "HTTP/1.1 200 OK\r\n" 3217 "Content-Length: 1\r\n\r\n"; 3218 scoped_ptr<SpdyFrame> wrapped_get_resp1( 3219 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false)); 3220 scoped_ptr<SpdyFrame> wrapped_body1( 3221 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false)); 3222 scoped_ptr<SpdyFrame> window_update( 3223 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size())); 3224 3225 // Fetch https://www.google.com/2 via HTTP. 3226 const char get2[] = "GET /2 HTTP/1.1\r\n" 3227 "Host: www.google.com\r\n" 3228 "Connection: keep-alive\r\n\r\n"; 3229 scoped_ptr<SpdyFrame> wrapped_get2( 3230 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false)); 3231 const char resp2[] = "HTTP/1.1 200 OK\r\n" 3232 "Content-Length: 2\r\n\r\n"; 3233 scoped_ptr<SpdyFrame> wrapped_get_resp2( 3234 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false)); 3235 scoped_ptr<SpdyFrame> wrapped_body2( 3236 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false)); 3237 3238 MockWrite spdy_writes[] = { 3239 CreateMockWrite(*connect1, 0), 3240 CreateMockWrite(*wrapped_get1, 2), 3241 CreateMockWrite(*wrapped_get2, 5), 3242 }; 3243 3244 MockRead spdy_reads[] = { 3245 CreateMockRead(*conn_resp1, 1, ASYNC), 3246 CreateMockRead(*wrapped_get_resp1, 3, ASYNC), 3247 CreateMockRead(*wrapped_body1, 4, ASYNC), 3248 CreateMockRead(*wrapped_get_resp2, 6, ASYNC), 3249 CreateMockRead(*wrapped_body2, 7, ASYNC), 3250 MockRead(ASYNC, 0, 8), 3251 }; 3252 3253 DeterministicSocketData spdy_data( 3254 spdy_reads, arraysize(spdy_reads), 3255 spdy_writes, arraysize(spdy_writes)); 3256 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3257 3258 SSLSocketDataProvider ssl(ASYNC, OK); 3259 ssl.SetNextProto(GetParam()); 3260 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3261 SSLSocketDataProvider ssl2(ASYNC, OK); 3262 ssl2.was_npn_negotiated = false; 3263 ssl2.protocol_negotiated = kProtoUnknown; 3264 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 3265 3266 TestCompletionCallback callback; 3267 3268 scoped_ptr<HttpTransaction> trans( 3269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3270 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3271 EXPECT_EQ(ERR_IO_PENDING, rv); 3272 // The first connect and request, each of their responses, and the body. 3273 spdy_data.RunFor(5); 3274 3275 rv = callback.WaitForResult(); 3276 EXPECT_EQ(OK, rv); 3277 3278 LoadTimingInfo load_timing_info; 3279 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3280 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3281 3282 const HttpResponseInfo* response = trans->GetResponseInfo(); 3283 ASSERT_TRUE(response != NULL); 3284 ASSERT_TRUE(response->headers.get() != NULL); 3285 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3286 3287 std::string response_data; 3288 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3289 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback())); 3290 trans.reset(); 3291 3292 scoped_ptr<HttpTransaction> trans2( 3293 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3294 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3295 EXPECT_EQ(ERR_IO_PENDING, rv); 3296 3297 // The second request, response, and body. There should not be a second 3298 // connect. 3299 spdy_data.RunFor(3); 3300 rv = callback.WaitForResult(); 3301 EXPECT_EQ(OK, rv); 3302 3303 LoadTimingInfo load_timing_info2; 3304 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3305 TestLoadTimingReused(load_timing_info2); 3306 3307 // The requests should have the same ID. 3308 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3309 3310 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback())); 3311 } 3312 3313 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS 3314 // Proxy to different servers. 3315 TEST_P(HttpNetworkTransactionTest, 3316 HttpsProxySpdyLoadTimingTwoHttpRequests) { 3317 // Configure against https proxy server "proxy:70". 3318 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3319 "https://proxy:70")); 3320 CapturingBoundNetLog log; 3321 session_deps_.net_log = log.bound().net_log(); 3322 scoped_refptr<HttpNetworkSession> session( 3323 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3324 3325 HttpRequestInfo request1; 3326 request1.method = "GET"; 3327 request1.url = GURL("http://www.google.com/"); 3328 request1.load_flags = 0; 3329 3330 HttpRequestInfo request2; 3331 request2.method = "GET"; 3332 request2.url = GURL("http://news.google.com/"); 3333 request2.load_flags = 0; 3334 3335 // http://www.google.com/ 3336 scoped_ptr<SpdyHeaderBlock> headers( 3337 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/")); 3338 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame( 3339 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0)); 3340 scoped_ptr<SpdyFrame> get_resp1( 3341 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3342 scoped_ptr<SpdyFrame> body1( 3343 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true)); 3344 3345 // http://news.google.com/ 3346 scoped_ptr<SpdyHeaderBlock> headers2( 3347 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/")); 3348 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame( 3349 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0)); 3350 scoped_ptr<SpdyFrame> get_resp2( 3351 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3352 scoped_ptr<SpdyFrame> body2( 3353 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true)); 3354 3355 MockWrite spdy_writes[] = { 3356 CreateMockWrite(*get1, 0), 3357 CreateMockWrite(*get2, 3), 3358 }; 3359 3360 MockRead spdy_reads[] = { 3361 CreateMockRead(*get_resp1, 1, ASYNC), 3362 CreateMockRead(*body1, 2, ASYNC), 3363 CreateMockRead(*get_resp2, 4, ASYNC), 3364 CreateMockRead(*body2, 5, ASYNC), 3365 MockRead(ASYNC, 0, 6), 3366 }; 3367 3368 DeterministicSocketData spdy_data( 3369 spdy_reads, arraysize(spdy_reads), 3370 spdy_writes, arraysize(spdy_writes)); 3371 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3372 3373 SSLSocketDataProvider ssl(ASYNC, OK); 3374 ssl.SetNextProto(GetParam()); 3375 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3376 3377 TestCompletionCallback callback; 3378 3379 scoped_ptr<HttpTransaction> trans( 3380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3381 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3382 EXPECT_EQ(ERR_IO_PENDING, rv); 3383 spdy_data.RunFor(2); 3384 3385 rv = callback.WaitForResult(); 3386 EXPECT_EQ(OK, rv); 3387 3388 LoadTimingInfo load_timing_info; 3389 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3390 TestLoadTimingNotReused(load_timing_info, 3391 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3392 3393 const HttpResponseInfo* response = trans->GetResponseInfo(); 3394 ASSERT_TRUE(response != NULL); 3395 ASSERT_TRUE(response->headers.get() != NULL); 3396 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3397 3398 std::string response_data; 3399 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3400 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback())); 3401 spdy_data.RunFor(1); 3402 EXPECT_EQ(1, callback.WaitForResult()); 3403 // Delete the first request, so the second one can reuse the socket. 3404 trans.reset(); 3405 3406 scoped_ptr<HttpTransaction> trans2( 3407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3408 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3409 EXPECT_EQ(ERR_IO_PENDING, rv); 3410 3411 spdy_data.RunFor(2); 3412 rv = callback.WaitForResult(); 3413 EXPECT_EQ(OK, rv); 3414 3415 LoadTimingInfo load_timing_info2; 3416 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3417 TestLoadTimingReused(load_timing_info2); 3418 3419 // The requests should have the same ID. 3420 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3421 3422 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback())); 3423 spdy_data.RunFor(1); 3424 EXPECT_EQ(2, callback.WaitForResult()); 3425 } 3426 3427 // Test the challenge-response-retry sequence through an HTTPS Proxy 3428 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { 3429 HttpRequestInfo request; 3430 request.method = "GET"; 3431 request.url = GURL("http://www.google.com/"); 3432 // when the no authentication data flag is set. 3433 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 3434 3435 // Configure against https proxy server "myproxy:70". 3436 session_deps_.proxy_service.reset( 3437 ProxyService::CreateFixed("https://myproxy:70")); 3438 CapturingBoundNetLog log; 3439 session_deps_.net_log = log.bound().net_log(); 3440 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3441 3442 // Since we have proxy, should use full url 3443 MockWrite data_writes1[] = { 3444 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3445 "Host: www.google.com\r\n" 3446 "Proxy-Connection: keep-alive\r\n\r\n"), 3447 3448 // After calling trans->RestartWithAuth(), this is the request we should 3449 // be issuing -- the final header line contains the credentials. 3450 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3451 "Host: www.google.com\r\n" 3452 "Proxy-Connection: keep-alive\r\n" 3453 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3454 }; 3455 3456 // The proxy responds to the GET with a 407, using a persistent 3457 // connection. 3458 MockRead data_reads1[] = { 3459 // No credentials. 3460 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 3461 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3462 MockRead("Proxy-Connection: keep-alive\r\n"), 3463 MockRead("Content-Length: 0\r\n\r\n"), 3464 3465 MockRead("HTTP/1.1 200 OK\r\n"), 3466 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 3467 MockRead("Content-Length: 100\r\n\r\n"), 3468 MockRead(SYNCHRONOUS, OK), 3469 }; 3470 3471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3472 data_writes1, arraysize(data_writes1)); 3473 session_deps_.socket_factory->AddSocketDataProvider(&data1); 3474 SSLSocketDataProvider ssl(ASYNC, OK); 3475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3476 3477 TestCompletionCallback callback1; 3478 3479 scoped_ptr<HttpTransaction> trans( 3480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3481 3482 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3483 EXPECT_EQ(ERR_IO_PENDING, rv); 3484 3485 rv = callback1.WaitForResult(); 3486 EXPECT_EQ(OK, rv); 3487 3488 LoadTimingInfo load_timing_info; 3489 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3490 TestLoadTimingNotReused(load_timing_info, 3491 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3492 3493 const HttpResponseInfo* response = trans->GetResponseInfo(); 3494 ASSERT_TRUE(response != NULL); 3495 ASSERT_FALSE(response->headers.get() == NULL); 3496 EXPECT_EQ(407, response->headers->response_code()); 3497 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 3498 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 3499 3500 TestCompletionCallback callback2; 3501 3502 rv = trans->RestartWithAuth( 3503 AuthCredentials(kFoo, kBar), callback2.callback()); 3504 EXPECT_EQ(ERR_IO_PENDING, rv); 3505 3506 rv = callback2.WaitForResult(); 3507 EXPECT_EQ(OK, rv); 3508 3509 load_timing_info = LoadTimingInfo(); 3510 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3511 // Retrying with HTTP AUTH is considered to be reusing a socket. 3512 TestLoadTimingReused(load_timing_info); 3513 3514 response = trans->GetResponseInfo(); 3515 ASSERT_TRUE(response != NULL); 3516 3517 EXPECT_TRUE(response->headers->IsKeepAlive()); 3518 EXPECT_EQ(200, response->headers->response_code()); 3519 EXPECT_EQ(100, response->headers->GetContentLength()); 3520 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 3521 3522 // The password prompt info should not be set. 3523 EXPECT_TRUE(response->auth_challenge.get() == NULL); 3524 } 3525 3526 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( 3527 const MockRead& status, int expected_status) { 3528 HttpRequestInfo request; 3529 request.method = "GET"; 3530 request.url = GURL("https://www.google.com/"); 3531 request.load_flags = 0; 3532 3533 // Configure against proxy server "myproxy:70". 3534 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 3535 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3536 3537 // Since we have proxy, should try to establish tunnel. 3538 MockWrite data_writes[] = { 3539 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 3540 "Host: www.google.com\r\n" 3541 "Proxy-Connection: keep-alive\r\n\r\n"), 3542 }; 3543 3544 MockRead data_reads[] = { 3545 status, 3546 MockRead("Content-Length: 10\r\n\r\n"), 3547 // No response body because the test stops reading here. 3548 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 3549 }; 3550 3551 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 3552 data_writes, arraysize(data_writes)); 3553 session_deps_.socket_factory->AddSocketDataProvider(&data); 3554 3555 TestCompletionCallback callback; 3556 3557 scoped_ptr<HttpTransaction> trans( 3558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3559 3560 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 3561 EXPECT_EQ(ERR_IO_PENDING, rv); 3562 3563 rv = callback.WaitForResult(); 3564 EXPECT_EQ(expected_status, rv); 3565 } 3566 3567 void HttpNetworkTransactionTest::ConnectStatusHelper( 3568 const MockRead& status) { 3569 ConnectStatusHelperWithExpectedStatus( 3570 status, ERR_TUNNEL_CONNECTION_FAILED); 3571 } 3572 3573 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) { 3574 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n")); 3575 } 3576 3577 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) { 3578 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n")); 3579 } 3580 3581 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) { 3582 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n")); 3583 } 3584 3585 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) { 3586 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n")); 3587 } 3588 3589 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) { 3590 ConnectStatusHelper( 3591 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n")); 3592 } 3593 3594 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) { 3595 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n")); 3596 } 3597 3598 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) { 3599 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n")); 3600 } 3601 3602 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) { 3603 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n")); 3604 } 3605 3606 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) { 3607 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n")); 3608 } 3609 3610 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) { 3611 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n")); 3612 } 3613 3614 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) { 3615 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n")); 3616 } 3617 3618 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) { 3619 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n")); 3620 } 3621 3622 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) { 3623 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n")); 3624 } 3625 3626 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) { 3627 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n")); 3628 } 3629 3630 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) { 3631 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n")); 3632 } 3633 3634 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) { 3635 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n")); 3636 } 3637 3638 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) { 3639 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n")); 3640 } 3641 3642 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) { 3643 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n")); 3644 } 3645 3646 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) { 3647 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n")); 3648 } 3649 3650 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) { 3651 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n")); 3652 } 3653 3654 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) { 3655 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n")); 3656 } 3657 3658 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) { 3659 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n")); 3660 } 3661 3662 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) { 3663 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n")); 3664 } 3665 3666 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) { 3667 ConnectStatusHelperWithExpectedStatus( 3668 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 3669 ERR_PROXY_AUTH_UNSUPPORTED); 3670 } 3671 3672 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) { 3673 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n")); 3674 } 3675 3676 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) { 3677 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n")); 3678 } 3679 3680 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) { 3681 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n")); 3682 } 3683 3684 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) { 3685 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n")); 3686 } 3687 3688 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) { 3689 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n")); 3690 } 3691 3692 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) { 3693 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n")); 3694 } 3695 3696 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) { 3697 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n")); 3698 } 3699 3700 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) { 3701 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n")); 3702 } 3703 3704 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) { 3705 ConnectStatusHelper( 3706 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n")); 3707 } 3708 3709 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) { 3710 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n")); 3711 } 3712 3713 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) { 3714 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n")); 3715 } 3716 3717 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) { 3718 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n")); 3719 } 3720 3721 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) { 3722 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n")); 3723 } 3724 3725 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) { 3726 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n")); 3727 } 3728 3729 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) { 3730 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n")); 3731 } 3732 3733 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) { 3734 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n")); 3735 } 3736 3737 // Test the flow when both the proxy server AND origin server require 3738 // authentication. Again, this uses basic auth for both since that is 3739 // the simplest to mock. 3740 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { 3741 HttpRequestInfo request; 3742 request.method = "GET"; 3743 request.url = GURL("http://www.google.com/"); 3744 request.load_flags = 0; 3745 3746 // Configure against proxy server "myproxy:70". 3747 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 3748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3749 3750 scoped_ptr<HttpTransaction> trans( 3751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 3752 3753 MockWrite data_writes1[] = { 3754 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3755 "Host: www.google.com\r\n" 3756 "Proxy-Connection: keep-alive\r\n\r\n"), 3757 }; 3758 3759 MockRead data_reads1[] = { 3760 MockRead("HTTP/1.0 407 Unauthorized\r\n"), 3761 // Give a couple authenticate options (only the middle one is actually 3762 // supported). 3763 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed. 3764 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3765 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 3766 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 3767 // Large content-length -- won't matter, as connection will be reset. 3768 MockRead("Content-Length: 10000\r\n\r\n"), 3769 MockRead(SYNCHRONOUS, ERR_FAILED), 3770 }; 3771 3772 // After calling trans->RestartWithAuth() the first time, this is the 3773 // request we should be issuing -- the final header line contains the 3774 // proxy's credentials. 3775 MockWrite data_writes2[] = { 3776 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3777 "Host: www.google.com\r\n" 3778 "Proxy-Connection: keep-alive\r\n" 3779 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3780 }; 3781 3782 // Now the proxy server lets the request pass through to origin server. 3783 // The origin server responds with a 401. 3784 MockRead data_reads2[] = { 3785 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 3786 // Note: We are using the same realm-name as the proxy server. This is 3787 // completely valid, as realms are unique across hosts. 3788 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3789 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 3790 MockRead("Content-Length: 2000\r\n\r\n"), 3791 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached. 3792 }; 3793 3794 // After calling trans->RestartWithAuth() the second time, we should send 3795 // the credentials for both the proxy and origin server. 3796 MockWrite data_writes3[] = { 3797 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3798 "Host: www.google.com\r\n" 3799 "Proxy-Connection: keep-alive\r\n" 3800 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n" 3801 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 3802 }; 3803 3804 // Lastly we get the desired content. 3805 MockRead data_reads3[] = { 3806 MockRead("HTTP/1.0 200 OK\r\n"), 3807 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 3808 MockRead("Content-Length: 100\r\n\r\n"), 3809 MockRead(SYNCHRONOUS, OK), 3810 }; 3811 3812 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3813 data_writes1, arraysize(data_writes1)); 3814 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3815 data_writes2, arraysize(data_writes2)); 3816 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 3817 data_writes3, arraysize(data_writes3)); 3818 session_deps_.socket_factory->AddSocketDataProvider(&data1); 3819 session_deps_.socket_factory->AddSocketDataProvider(&data2); 3820 session_deps_.socket_factory->AddSocketDataProvider(&data3); 3821 3822 TestCompletionCallback callback1; 3823 3824 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 3825 EXPECT_EQ(ERR_IO_PENDING, rv); 3826 3827 rv = callback1.WaitForResult(); 3828 EXPECT_EQ(OK, rv); 3829 3830 const HttpResponseInfo* response = trans->GetResponseInfo(); 3831 ASSERT_TRUE(response != NULL); 3832 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 3833 3834 TestCompletionCallback callback2; 3835 3836 rv = trans->RestartWithAuth( 3837 AuthCredentials(kFoo, kBar), callback2.callback()); 3838 EXPECT_EQ(ERR_IO_PENDING, rv); 3839 3840 rv = callback2.WaitForResult(); 3841 EXPECT_EQ(OK, rv); 3842 3843 response = trans->GetResponseInfo(); 3844 ASSERT_TRUE(response != NULL); 3845 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 3846 3847 TestCompletionCallback callback3; 3848 3849 rv = trans->RestartWithAuth( 3850 AuthCredentials(kFoo2, kBar2), callback3.callback()); 3851 EXPECT_EQ(ERR_IO_PENDING, rv); 3852 3853 rv = callback3.WaitForResult(); 3854 EXPECT_EQ(OK, rv); 3855 3856 response = trans->GetResponseInfo(); 3857 EXPECT_TRUE(response->auth_challenge.get() == NULL); 3858 EXPECT_EQ(100, response->headers->GetContentLength()); 3859 } 3860 3861 // For the NTLM implementation using SSPI, we skip the NTLM tests since we 3862 // can't hook into its internals to cause it to generate predictable NTLM 3863 // authorization headers. 3864 #if defined(NTLM_PORTABLE) 3865 // The NTLM authentication unit tests were generated by capturing the HTTP 3866 // requests and responses using Fiddler 2 and inspecting the generated random 3867 // bytes in the debugger. 3868 3869 // Enter the correct password and authenticate successfully. 3870 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) { 3871 HttpRequestInfo request; 3872 request.method = "GET"; 3873 request.url = GURL("http://172.22.68.17/kids/login.aspx"); 3874 3875 // Ensure load is not disrupted by flags which suppress behaviour specific 3876 // to other auth schemes. 3877 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; 3878 3879 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, 3880 MockGetHostName); 3881 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3882 3883 MockWrite data_writes1[] = { 3884 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 3885 "Host: 172.22.68.17\r\n" 3886 "Connection: keep-alive\r\n\r\n"), 3887 }; 3888 3889 MockRead data_reads1[] = { 3890 MockRead("HTTP/1.1 401 Access Denied\r\n"), 3891 // Negotiate and NTLM are often requested together. However, we only want 3892 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 3893 // the header that requests Negotiate for this test. 3894 MockRead("WWW-Authenticate: NTLM\r\n"), 3895 MockRead("Connection: close\r\n"), 3896 MockRead("Content-Length: 42\r\n"), 3897 MockRead("Content-Type: text/html\r\n\r\n"), 3898 // Missing content -- won't matter, as connection will be reset. 3899 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 3900 }; 3901 3902 MockWrite data_writes2[] = { 3903 // After restarting with a null identity, this is the 3904 // request we should be issuing -- the final header line contains a Type 3905 // 1 message. 3906 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 3907 "Host: 172.22.68.17\r\n" 3908 "Connection: keep-alive\r\n" 3909 "Authorization: NTLM " 3910 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 3911 3912 // After calling trans->RestartWithAuth(), we should send a Type 3 message 3913 // (the credentials for the origin server). The second request continues 3914 // on the same connection. 3915 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 3916 "Host: 172.22.68.17\r\n" 3917 "Connection: keep-alive\r\n" 3918 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 3919 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 3920 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW" 3921 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX" 3922 "ahlhx5I=\r\n\r\n"), 3923 }; 3924 3925 MockRead data_reads2[] = { 3926 // The origin server responds with a Type 2 message. 3927 MockRead("HTTP/1.1 401 Access Denied\r\n"), 3928 MockRead("WWW-Authenticate: NTLM " 3929 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo" 3930 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 3931 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 3932 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 3933 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 3934 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 3935 "BtAAAAAAA=\r\n"), 3936 MockRead("Content-Length: 42\r\n"), 3937 MockRead("Content-Type: text/html\r\n\r\n"), 3938 MockRead("You are not authorized to view this page\r\n"), 3939 3940 // Lastly we get the desired content. 3941 MockRead("HTTP/1.1 200 OK\r\n"), 3942 MockRead("Content-Type: text/html; charset=utf-8\r\n"), 3943 MockRead("Content-Length: 13\r\n\r\n"), 3944 MockRead("Please Login\r\n"), 3945 MockRead(SYNCHRONOUS, OK), 3946 }; 3947 3948 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3949 data_writes1, arraysize(data_writes1)); 3950 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3951 data_writes2, arraysize(data_writes2)); 3952 session_deps_.socket_factory->AddSocketDataProvider(&data1); 3953 session_deps_.socket_factory->AddSocketDataProvider(&data2); 3954 3955 TestCompletionCallback callback1; 3956 3957 scoped_ptr<HttpTransaction> trans( 3958 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3959 3960 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 3961 EXPECT_EQ(ERR_IO_PENDING, rv); 3962 3963 rv = callback1.WaitForResult(); 3964 EXPECT_EQ(OK, rv); 3965 3966 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 3967 3968 const HttpResponseInfo* response = trans->GetResponseInfo(); 3969 ASSERT_FALSE(response == NULL); 3970 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 3971 3972 TestCompletionCallback callback2; 3973 3974 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), 3975 callback2.callback()); 3976 EXPECT_EQ(ERR_IO_PENDING, rv); 3977 3978 rv = callback2.WaitForResult(); 3979 EXPECT_EQ(OK, rv); 3980 3981 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 3982 3983 response = trans->GetResponseInfo(); 3984 ASSERT_TRUE(response != NULL); 3985 EXPECT_TRUE(response->auth_challenge.get() == NULL); 3986 3987 TestCompletionCallback callback3; 3988 3989 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); 3990 EXPECT_EQ(ERR_IO_PENDING, rv); 3991 3992 rv = callback3.WaitForResult(); 3993 EXPECT_EQ(OK, rv); 3994 3995 response = trans->GetResponseInfo(); 3996 ASSERT_TRUE(response != NULL); 3997 EXPECT_TRUE(response->auth_challenge.get() == NULL); 3998 EXPECT_EQ(13, response->headers->GetContentLength()); 3999 } 4000 4001 // Enter a wrong password, and then the correct one. 4002 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) { 4003 HttpRequestInfo request; 4004 request.method = "GET"; 4005 request.url = GURL("http://172.22.68.17/kids/login.aspx"); 4006 request.load_flags = 0; 4007 4008 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2, 4009 MockGetHostName); 4010 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4011 4012 MockWrite data_writes1[] = { 4013 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4014 "Host: 172.22.68.17\r\n" 4015 "Connection: keep-alive\r\n\r\n"), 4016 }; 4017 4018 MockRead data_reads1[] = { 4019 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4020 // Negotiate and NTLM are often requested together. However, we only want 4021 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 4022 // the header that requests Negotiate for this test. 4023 MockRead("WWW-Authenticate: NTLM\r\n"), 4024 MockRead("Connection: close\r\n"), 4025 MockRead("Content-Length: 42\r\n"), 4026 MockRead("Content-Type: text/html\r\n\r\n"), 4027 // Missing content -- won't matter, as connection will be reset. 4028 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4029 }; 4030 4031 MockWrite data_writes2[] = { 4032 // After restarting with a null identity, this is the 4033 // request we should be issuing -- the final header line contains a Type 4034 // 1 message. 4035 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4036 "Host: 172.22.68.17\r\n" 4037 "Connection: keep-alive\r\n" 4038 "Authorization: NTLM " 4039 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4040 4041 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4042 // (the credentials for the origin server). The second request continues 4043 // on the same connection. 4044 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4045 "Host: 172.22.68.17\r\n" 4046 "Connection: keep-alive\r\n" 4047 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4048 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4049 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY" 4050 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj" 4051 "4Ww7b7E=\r\n\r\n"), 4052 }; 4053 4054 MockRead data_reads2[] = { 4055 // The origin server responds with a Type 2 message. 4056 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4057 MockRead("WWW-Authenticate: NTLM " 4058 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo" 4059 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4060 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4061 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4062 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4063 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4064 "BtAAAAAAA=\r\n"), 4065 MockRead("Content-Length: 42\r\n"), 4066 MockRead("Content-Type: text/html\r\n\r\n"), 4067 MockRead("You are not authorized to view this page\r\n"), 4068 4069 // Wrong password. 4070 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4071 MockRead("WWW-Authenticate: NTLM\r\n"), 4072 MockRead("Connection: close\r\n"), 4073 MockRead("Content-Length: 42\r\n"), 4074 MockRead("Content-Type: text/html\r\n\r\n"), 4075 // Missing content -- won't matter, as connection will be reset. 4076 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4077 }; 4078 4079 MockWrite data_writes3[] = { 4080 // After restarting with a null identity, this is the 4081 // request we should be issuing -- the final header line contains a Type 4082 // 1 message. 4083 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4084 "Host: 172.22.68.17\r\n" 4085 "Connection: keep-alive\r\n" 4086 "Authorization: NTLM " 4087 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4088 4089 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4090 // (the credentials for the origin server). The second request continues 4091 // on the same connection. 4092 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4093 "Host: 172.22.68.17\r\n" 4094 "Connection: keep-alive\r\n" 4095 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4096 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4097 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54" 4098 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI" 4099 "+4MUm7c=\r\n\r\n"), 4100 }; 4101 4102 MockRead data_reads3[] = { 4103 // The origin server responds with a Type 2 message. 4104 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4105 MockRead("WWW-Authenticate: NTLM " 4106 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo" 4107 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4108 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4109 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4110 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4111 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4112 "BtAAAAAAA=\r\n"), 4113 MockRead("Content-Length: 42\r\n"), 4114 MockRead("Content-Type: text/html\r\n\r\n"), 4115 MockRead("You are not authorized to view this page\r\n"), 4116 4117 // Lastly we get the desired content. 4118 MockRead("HTTP/1.1 200 OK\r\n"), 4119 MockRead("Content-Type: text/html; charset=utf-8\r\n"), 4120 MockRead("Content-Length: 13\r\n\r\n"), 4121 MockRead("Please Login\r\n"), 4122 MockRead(SYNCHRONOUS, OK), 4123 }; 4124 4125 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4126 data_writes1, arraysize(data_writes1)); 4127 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4128 data_writes2, arraysize(data_writes2)); 4129 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4130 data_writes3, arraysize(data_writes3)); 4131 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4132 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4133 session_deps_.socket_factory->AddSocketDataProvider(&data3); 4134 4135 TestCompletionCallback callback1; 4136 4137 scoped_ptr<HttpTransaction> trans( 4138 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4139 4140 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4141 EXPECT_EQ(ERR_IO_PENDING, rv); 4142 4143 rv = callback1.WaitForResult(); 4144 EXPECT_EQ(OK, rv); 4145 4146 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4147 4148 const HttpResponseInfo* response = trans->GetResponseInfo(); 4149 ASSERT_TRUE(response != NULL); 4150 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4151 4152 TestCompletionCallback callback2; 4153 4154 // Enter the wrong password. 4155 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword), 4156 callback2.callback()); 4157 EXPECT_EQ(ERR_IO_PENDING, rv); 4158 4159 rv = callback2.WaitForResult(); 4160 EXPECT_EQ(OK, rv); 4161 4162 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4163 TestCompletionCallback callback3; 4164 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); 4165 EXPECT_EQ(ERR_IO_PENDING, rv); 4166 rv = callback3.WaitForResult(); 4167 EXPECT_EQ(OK, rv); 4168 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4169 4170 response = trans->GetResponseInfo(); 4171 ASSERT_FALSE(response == NULL); 4172 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4173 4174 TestCompletionCallback callback4; 4175 4176 // Now enter the right password. 4177 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), 4178 callback4.callback()); 4179 EXPECT_EQ(ERR_IO_PENDING, rv); 4180 4181 rv = callback4.WaitForResult(); 4182 EXPECT_EQ(OK, rv); 4183 4184 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4185 4186 TestCompletionCallback callback5; 4187 4188 // One more roundtrip 4189 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback()); 4190 EXPECT_EQ(ERR_IO_PENDING, rv); 4191 4192 rv = callback5.WaitForResult(); 4193 EXPECT_EQ(OK, rv); 4194 4195 response = trans->GetResponseInfo(); 4196 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4197 EXPECT_EQ(13, response->headers->GetContentLength()); 4198 } 4199 #endif // NTLM_PORTABLE 4200 4201 // Test reading a server response which has only headers, and no body. 4202 // After some maximum number of bytes is consumed, the transaction should 4203 // fail with ERR_RESPONSE_HEADERS_TOO_BIG. 4204 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) { 4205 HttpRequestInfo request; 4206 request.method = "GET"; 4207 request.url = GURL("http://www.google.com/"); 4208 request.load_flags = 0; 4209 4210 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4211 scoped_ptr<HttpTransaction> trans( 4212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 4213 4214 // Respond with 300 kb of headers (we should fail after 256 kb). 4215 std::string large_headers_string; 4216 FillLargeHeadersString(&large_headers_string, 300 * 1024); 4217 4218 MockRead data_reads[] = { 4219 MockRead("HTTP/1.0 200 OK\r\n"), 4220 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()), 4221 MockRead("\r\nBODY"), 4222 MockRead(SYNCHRONOUS, OK), 4223 }; 4224 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4225 session_deps_.socket_factory->AddSocketDataProvider(&data); 4226 4227 TestCompletionCallback callback; 4228 4229 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4230 EXPECT_EQ(ERR_IO_PENDING, rv); 4231 4232 rv = callback.WaitForResult(); 4233 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv); 4234 4235 const HttpResponseInfo* response = trans->GetResponseInfo(); 4236 EXPECT_TRUE(response == NULL); 4237 } 4238 4239 // Make sure that we don't try to reuse a TCPClientSocket when failing to 4240 // establish tunnel. 4241 // http://code.google.com/p/chromium/issues/detail?id=3772 4242 TEST_P(HttpNetworkTransactionTest, 4243 DontRecycleTransportSocketForSSLTunnel) { 4244 HttpRequestInfo request; 4245 request.method = "GET"; 4246 request.url = GURL("https://www.google.com/"); 4247 request.load_flags = 0; 4248 4249 // Configure against proxy server "myproxy:70". 4250 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 4251 4252 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4253 4254 scoped_ptr<HttpTransaction> trans( 4255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4256 4257 // Since we have proxy, should try to establish tunnel. 4258 MockWrite data_writes1[] = { 4259 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 4260 "Host: www.google.com\r\n" 4261 "Proxy-Connection: keep-alive\r\n\r\n"), 4262 }; 4263 4264 // The proxy responds to the connect with a 404, using a persistent 4265 // connection. Usually a proxy would return 501 (not implemented), 4266 // or 200 (tunnel established). 4267 MockRead data_reads1[] = { 4268 MockRead("HTTP/1.1 404 Not Found\r\n"), 4269 MockRead("Content-Length: 10\r\n\r\n"), 4270 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 4271 }; 4272 4273 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4274 data_writes1, arraysize(data_writes1)); 4275 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4276 4277 TestCompletionCallback callback1; 4278 4279 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4280 EXPECT_EQ(ERR_IO_PENDING, rv); 4281 4282 rv = callback1.WaitForResult(); 4283 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 4284 4285 const HttpResponseInfo* response = trans->GetResponseInfo(); 4286 EXPECT_TRUE(response == NULL); 4287 4288 // Empty the current queue. This is necessary because idle sockets are 4289 // added to the connection pool asynchronously with a PostTask. 4290 base::MessageLoop::current()->RunUntilIdle(); 4291 4292 // We now check to make sure the TCPClientSocket was not added back to 4293 // the pool. 4294 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4295 trans.reset(); 4296 base::MessageLoop::current()->RunUntilIdle(); 4297 // Make sure that the socket didn't get recycled after calling the destructor. 4298 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4299 } 4300 4301 // Make sure that we recycle a socket after reading all of the response body. 4302 TEST_P(HttpNetworkTransactionTest, RecycleSocket) { 4303 HttpRequestInfo request; 4304 request.method = "GET"; 4305 request.url = GURL("http://www.google.com/"); 4306 request.load_flags = 0; 4307 4308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4309 4310 scoped_ptr<HttpTransaction> trans( 4311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4312 4313 MockRead data_reads[] = { 4314 // A part of the response body is received with the response headers. 4315 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"), 4316 // The rest of the response body is received in two parts. 4317 MockRead("lo"), 4318 MockRead(" world"), 4319 MockRead("junk"), // Should not be read!! 4320 MockRead(SYNCHRONOUS, OK), 4321 }; 4322 4323 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4324 session_deps_.socket_factory->AddSocketDataProvider(&data); 4325 4326 TestCompletionCallback callback; 4327 4328 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4329 EXPECT_EQ(ERR_IO_PENDING, rv); 4330 4331 rv = callback.WaitForResult(); 4332 EXPECT_EQ(OK, rv); 4333 4334 const HttpResponseInfo* response = trans->GetResponseInfo(); 4335 ASSERT_TRUE(response != NULL); 4336 4337 EXPECT_TRUE(response->headers.get() != NULL); 4338 std::string status_line = response->headers->GetStatusLine(); 4339 EXPECT_EQ("HTTP/1.1 200 OK", status_line); 4340 4341 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4342 4343 std::string response_data; 4344 rv = ReadTransaction(trans.get(), &response_data); 4345 EXPECT_EQ(OK, rv); 4346 EXPECT_EQ("hello world", response_data); 4347 4348 // Empty the current queue. This is necessary because idle sockets are 4349 // added to the connection pool asynchronously with a PostTask. 4350 base::MessageLoop::current()->RunUntilIdle(); 4351 4352 // We now check to make sure the socket was added back to the pool. 4353 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 4354 } 4355 4356 // Make sure that we recycle a SSL socket after reading all of the response 4357 // body. 4358 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) { 4359 HttpRequestInfo request; 4360 request.method = "GET"; 4361 request.url = GURL("https://www.google.com/"); 4362 request.load_flags = 0; 4363 4364 MockWrite data_writes[] = { 4365 MockWrite("GET / HTTP/1.1\r\n" 4366 "Host: www.google.com\r\n" 4367 "Connection: keep-alive\r\n\r\n"), 4368 }; 4369 4370 MockRead data_reads[] = { 4371 MockRead("HTTP/1.1 200 OK\r\n"), 4372 MockRead("Content-Length: 11\r\n\r\n"), 4373 MockRead("hello world"), 4374 MockRead(SYNCHRONOUS, OK), 4375 }; 4376 4377 SSLSocketDataProvider ssl(ASYNC, OK); 4378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 4379 4380 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4381 data_writes, arraysize(data_writes)); 4382 session_deps_.socket_factory->AddSocketDataProvider(&data); 4383 4384 TestCompletionCallback callback; 4385 4386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4387 scoped_ptr<HttpTransaction> trans( 4388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4389 4390 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4391 4392 EXPECT_EQ(ERR_IO_PENDING, rv); 4393 EXPECT_EQ(OK, callback.WaitForResult()); 4394 4395 const HttpResponseInfo* response = trans->GetResponseInfo(); 4396 ASSERT_TRUE(response != NULL); 4397 ASSERT_TRUE(response->headers.get() != NULL); 4398 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4399 4400 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4401 4402 std::string response_data; 4403 rv = ReadTransaction(trans.get(), &response_data); 4404 EXPECT_EQ(OK, rv); 4405 EXPECT_EQ("hello world", response_data); 4406 4407 // Empty the current queue. This is necessary because idle sockets are 4408 // added to the connection pool asynchronously with a PostTask. 4409 base::MessageLoop::current()->RunUntilIdle(); 4410 4411 // We now check to make sure the socket was added back to the pool. 4412 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4413 } 4414 4415 // Grab a SSL socket, use it, and put it back into the pool. Then, reuse it 4416 // from the pool and make sure that we recover okay. 4417 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) { 4418 HttpRequestInfo request; 4419 request.method = "GET"; 4420 request.url = GURL("https://www.google.com/"); 4421 request.load_flags = 0; 4422 4423 MockWrite data_writes[] = { 4424 MockWrite("GET / HTTP/1.1\r\n" 4425 "Host: www.google.com\r\n" 4426 "Connection: keep-alive\r\n\r\n"), 4427 MockWrite("GET / HTTP/1.1\r\n" 4428 "Host: www.google.com\r\n" 4429 "Connection: keep-alive\r\n\r\n"), 4430 }; 4431 4432 MockRead data_reads[] = { 4433 MockRead("HTTP/1.1 200 OK\r\n"), 4434 MockRead("Content-Length: 11\r\n\r\n"), 4435 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 4436 MockRead("hello world"), 4437 MockRead(ASYNC, 0, 0) // EOF 4438 }; 4439 4440 SSLSocketDataProvider ssl(ASYNC, OK); 4441 SSLSocketDataProvider ssl2(ASYNC, OK); 4442 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 4443 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 4444 4445 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4446 data_writes, arraysize(data_writes)); 4447 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), 4448 data_writes, arraysize(data_writes)); 4449 session_deps_.socket_factory->AddSocketDataProvider(&data); 4450 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4451 4452 TestCompletionCallback callback; 4453 4454 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4455 scoped_ptr<HttpTransaction> trans( 4456 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4457 4458 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4459 4460 EXPECT_EQ(ERR_IO_PENDING, rv); 4461 EXPECT_EQ(OK, callback.WaitForResult()); 4462 4463 const HttpResponseInfo* response = trans->GetResponseInfo(); 4464 ASSERT_TRUE(response != NULL); 4465 ASSERT_TRUE(response->headers.get() != NULL); 4466 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4467 4468 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4469 4470 std::string response_data; 4471 rv = ReadTransaction(trans.get(), &response_data); 4472 EXPECT_EQ(OK, rv); 4473 EXPECT_EQ("hello world", response_data); 4474 4475 // Empty the current queue. This is necessary because idle sockets are 4476 // added to the connection pool asynchronously with a PostTask. 4477 base::MessageLoop::current()->RunUntilIdle(); 4478 4479 // We now check to make sure the socket was added back to the pool. 4480 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4481 4482 // Now start the second transaction, which should reuse the previous socket. 4483 4484 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4485 4486 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4487 4488 EXPECT_EQ(ERR_IO_PENDING, rv); 4489 EXPECT_EQ(OK, callback.WaitForResult()); 4490 4491 response = trans->GetResponseInfo(); 4492 ASSERT_TRUE(response != NULL); 4493 ASSERT_TRUE(response->headers.get() != NULL); 4494 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4495 4496 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4497 4498 rv = ReadTransaction(trans.get(), &response_data); 4499 EXPECT_EQ(OK, rv); 4500 EXPECT_EQ("hello world", response_data); 4501 4502 // Empty the current queue. This is necessary because idle sockets are 4503 // added to the connection pool asynchronously with a PostTask. 4504 base::MessageLoop::current()->RunUntilIdle(); 4505 4506 // We now check to make sure the socket was added back to the pool. 4507 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4508 } 4509 4510 // Make sure that we recycle a socket after a zero-length response. 4511 // http://crbug.com/9880 4512 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { 4513 HttpRequestInfo request; 4514 request.method = "GET"; 4515 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&" 4516 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&" 4517 "e=17259,18167,19592,19773,19981,20133,20173,20233&" 4518 "rt=prt.2642,ol.2649,xjs.2951"); 4519 request.load_flags = 0; 4520 4521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4522 4523 scoped_ptr<HttpTransaction> trans( 4524 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4525 4526 MockRead data_reads[] = { 4527 MockRead("HTTP/1.1 204 No Content\r\n" 4528 "Content-Length: 0\r\n" 4529 "Content-Type: text/html\r\n\r\n"), 4530 MockRead("junk"), // Should not be read!! 4531 MockRead(SYNCHRONOUS, OK), 4532 }; 4533 4534 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4535 session_deps_.socket_factory->AddSocketDataProvider(&data); 4536 4537 TestCompletionCallback callback; 4538 4539 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4540 EXPECT_EQ(ERR_IO_PENDING, rv); 4541 4542 rv = callback.WaitForResult(); 4543 EXPECT_EQ(OK, rv); 4544 4545 const HttpResponseInfo* response = trans->GetResponseInfo(); 4546 ASSERT_TRUE(response != NULL); 4547 4548 EXPECT_TRUE(response->headers.get() != NULL); 4549 std::string status_line = response->headers->GetStatusLine(); 4550 EXPECT_EQ("HTTP/1.1 204 No Content", status_line); 4551 4552 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4553 4554 std::string response_data; 4555 rv = ReadTransaction(trans.get(), &response_data); 4556 EXPECT_EQ(OK, rv); 4557 EXPECT_EQ("", response_data); 4558 4559 // Empty the current queue. This is necessary because idle sockets are 4560 // added to the connection pool asynchronously with a PostTask. 4561 base::MessageLoop::current()->RunUntilIdle(); 4562 4563 // We now check to make sure the socket was added back to the pool. 4564 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 4565 } 4566 4567 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) { 4568 ScopedVector<UploadElementReader> element_readers; 4569 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 4570 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 4571 4572 HttpRequestInfo request[2]; 4573 // Transaction 1: a GET request that succeeds. The socket is recycled 4574 // after use. 4575 request[0].method = "GET"; 4576 request[0].url = GURL("http://www.google.com/"); 4577 request[0].load_flags = 0; 4578 // Transaction 2: a POST request. Reuses the socket kept alive from 4579 // transaction 1. The first attempts fails when writing the POST data. 4580 // This causes the transaction to retry with a new socket. The second 4581 // attempt succeeds. 4582 request[1].method = "POST"; 4583 request[1].url = GURL("http://www.google.com/login.cgi"); 4584 request[1].upload_data_stream = &upload_data_stream; 4585 request[1].load_flags = 0; 4586 4587 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4588 4589 // The first socket is used for transaction 1 and the first attempt of 4590 // transaction 2. 4591 4592 // The response of transaction 1. 4593 MockRead data_reads1[] = { 4594 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"), 4595 MockRead("hello world"), 4596 MockRead(SYNCHRONOUS, OK), 4597 }; 4598 // The mock write results of transaction 1 and the first attempt of 4599 // transaction 2. 4600 MockWrite data_writes1[] = { 4601 MockWrite(SYNCHRONOUS, 64), // GET 4602 MockWrite(SYNCHRONOUS, 93), // POST 4603 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data 4604 }; 4605 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4606 data_writes1, arraysize(data_writes1)); 4607 4608 // The second socket is used for the second attempt of transaction 2. 4609 4610 // The response of transaction 2. 4611 MockRead data_reads2[] = { 4612 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"), 4613 MockRead("welcome"), 4614 MockRead(SYNCHRONOUS, OK), 4615 }; 4616 // The mock write results of the second attempt of transaction 2. 4617 MockWrite data_writes2[] = { 4618 MockWrite(SYNCHRONOUS, 93), // POST 4619 MockWrite(SYNCHRONOUS, 3), // POST data 4620 }; 4621 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4622 data_writes2, arraysize(data_writes2)); 4623 4624 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4625 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4626 4627 const char* kExpectedResponseData[] = { 4628 "hello world", "welcome" 4629 }; 4630 4631 for (int i = 0; i < 2; ++i) { 4632 scoped_ptr<HttpTransaction> trans( 4633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4634 4635 TestCompletionCallback callback; 4636 4637 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog()); 4638 EXPECT_EQ(ERR_IO_PENDING, rv); 4639 4640 rv = callback.WaitForResult(); 4641 EXPECT_EQ(OK, rv); 4642 4643 const HttpResponseInfo* response = trans->GetResponseInfo(); 4644 ASSERT_TRUE(response != NULL); 4645 4646 EXPECT_TRUE(response->headers.get() != NULL); 4647 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4648 4649 std::string response_data; 4650 rv = ReadTransaction(trans.get(), &response_data); 4651 EXPECT_EQ(OK, rv); 4652 EXPECT_EQ(kExpectedResponseData[i], response_data); 4653 } 4654 } 4655 4656 // Test the request-challenge-retry sequence for basic auth when there is 4657 // an identity in the URL. The request should be sent as normal, but when 4658 // it fails the identity from the URL is used to answer the challenge. 4659 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) { 4660 HttpRequestInfo request; 4661 request.method = "GET"; 4662 request.url = GURL("http://foo:b@r@www.google.com/"); 4663 request.load_flags = LOAD_NORMAL; 4664 4665 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4666 scoped_ptr<HttpTransaction> trans( 4667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 4668 4669 // The password contains an escaped character -- for this test to pass it 4670 // will need to be unescaped by HttpNetworkTransaction. 4671 EXPECT_EQ("b%40r", request.url.password()); 4672 4673 MockWrite data_writes1[] = { 4674 MockWrite("GET / HTTP/1.1\r\n" 4675 "Host: www.google.com\r\n" 4676 "Connection: keep-alive\r\n\r\n"), 4677 }; 4678 4679 MockRead data_reads1[] = { 4680 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4681 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4682 MockRead("Content-Length: 10\r\n\r\n"), 4683 MockRead(SYNCHRONOUS, ERR_FAILED), 4684 }; 4685 4686 // After the challenge above, the transaction will be restarted using the 4687 // identity from the url (foo, b@r) to answer the challenge. 4688 MockWrite data_writes2[] = { 4689 MockWrite("GET / HTTP/1.1\r\n" 4690 "Host: www.google.com\r\n" 4691 "Connection: keep-alive\r\n" 4692 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"), 4693 }; 4694 4695 MockRead data_reads2[] = { 4696 MockRead("HTTP/1.0 200 OK\r\n"), 4697 MockRead("Content-Length: 100\r\n\r\n"), 4698 MockRead(SYNCHRONOUS, OK), 4699 }; 4700 4701 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4702 data_writes1, arraysize(data_writes1)); 4703 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4704 data_writes2, arraysize(data_writes2)); 4705 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4706 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4707 4708 TestCompletionCallback callback1; 4709 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4710 EXPECT_EQ(ERR_IO_PENDING, rv); 4711 rv = callback1.WaitForResult(); 4712 EXPECT_EQ(OK, rv); 4713 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4714 4715 TestCompletionCallback callback2; 4716 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 4717 EXPECT_EQ(ERR_IO_PENDING, rv); 4718 rv = callback2.WaitForResult(); 4719 EXPECT_EQ(OK, rv); 4720 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4721 4722 const HttpResponseInfo* response = trans->GetResponseInfo(); 4723 ASSERT_TRUE(response != NULL); 4724 4725 // There is no challenge info, since the identity in URL worked. 4726 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4727 4728 EXPECT_EQ(100, response->headers->GetContentLength()); 4729 4730 // Empty the current queue. 4731 base::MessageLoop::current()->RunUntilIdle(); 4732 } 4733 4734 // Test the request-challenge-retry sequence for basic auth when there is an 4735 // incorrect identity in the URL. The identity from the URL should be used only 4736 // once. 4737 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) { 4738 HttpRequestInfo request; 4739 request.method = "GET"; 4740 // Note: the URL has a username:password in it. The password "baz" is 4741 // wrong (should be "bar"). 4742 request.url = GURL("http://foo:baz@www.google.com/"); 4743 4744 request.load_flags = LOAD_NORMAL; 4745 4746 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4747 scoped_ptr<HttpTransaction> trans( 4748 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 4749 4750 MockWrite data_writes1[] = { 4751 MockWrite("GET / HTTP/1.1\r\n" 4752 "Host: www.google.com\r\n" 4753 "Connection: keep-alive\r\n\r\n"), 4754 }; 4755 4756 MockRead data_reads1[] = { 4757 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4758 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4759 MockRead("Content-Length: 10\r\n\r\n"), 4760 MockRead(SYNCHRONOUS, ERR_FAILED), 4761 }; 4762 4763 // After the challenge above, the transaction will be restarted using the 4764 // identity from the url (foo, baz) to answer the challenge. 4765 MockWrite data_writes2[] = { 4766 MockWrite("GET / HTTP/1.1\r\n" 4767 "Host: www.google.com\r\n" 4768 "Connection: keep-alive\r\n" 4769 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 4770 }; 4771 4772 MockRead data_reads2[] = { 4773 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4774 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4775 MockRead("Content-Length: 10\r\n\r\n"), 4776 MockRead(SYNCHRONOUS, ERR_FAILED), 4777 }; 4778 4779 // After the challenge above, the transaction will be restarted using the 4780 // identity supplied by the user (foo, bar) to answer the challenge. 4781 MockWrite data_writes3[] = { 4782 MockWrite("GET / HTTP/1.1\r\n" 4783 "Host: www.google.com\r\n" 4784 "Connection: keep-alive\r\n" 4785 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 4786 }; 4787 4788 MockRead data_reads3[] = { 4789 MockRead("HTTP/1.0 200 OK\r\n"), 4790 MockRead("Content-Length: 100\r\n\r\n"), 4791 MockRead(SYNCHRONOUS, OK), 4792 }; 4793 4794 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4795 data_writes1, arraysize(data_writes1)); 4796 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4797 data_writes2, arraysize(data_writes2)); 4798 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4799 data_writes3, arraysize(data_writes3)); 4800 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4801 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4802 session_deps_.socket_factory->AddSocketDataProvider(&data3); 4803 4804 TestCompletionCallback callback1; 4805 4806 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4807 EXPECT_EQ(ERR_IO_PENDING, rv); 4808 4809 rv = callback1.WaitForResult(); 4810 EXPECT_EQ(OK, rv); 4811 4812 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4813 TestCompletionCallback callback2; 4814 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 4815 EXPECT_EQ(ERR_IO_PENDING, rv); 4816 rv = callback2.WaitForResult(); 4817 EXPECT_EQ(OK, rv); 4818 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4819 4820 const HttpResponseInfo* response = trans->GetResponseInfo(); 4821 ASSERT_TRUE(response != NULL); 4822 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 4823 4824 TestCompletionCallback callback3; 4825 rv = trans->RestartWithAuth( 4826 AuthCredentials(kFoo, kBar), callback3.callback()); 4827 EXPECT_EQ(ERR_IO_PENDING, rv); 4828 rv = callback3.WaitForResult(); 4829 EXPECT_EQ(OK, rv); 4830 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4831 4832 response = trans->GetResponseInfo(); 4833 ASSERT_TRUE(response != NULL); 4834 4835 // There is no challenge info, since the identity worked. 4836 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4837 4838 EXPECT_EQ(100, response->headers->GetContentLength()); 4839 4840 // Empty the current queue. 4841 base::MessageLoop::current()->RunUntilIdle(); 4842 } 4843 4844 4845 // Test the request-challenge-retry sequence for basic auth when there is a 4846 // correct identity in the URL, but its use is being suppressed. The identity 4847 // from the URL should never be used. 4848 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) { 4849 HttpRequestInfo request; 4850 request.method = "GET"; 4851 request.url = GURL("http://foo:bar@www.google.com/"); 4852 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; 4853 4854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4855 scoped_ptr<HttpTransaction> trans( 4856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 4857 4858 MockWrite data_writes1[] = { 4859 MockWrite("GET / HTTP/1.1\r\n" 4860 "Host: www.google.com\r\n" 4861 "Connection: keep-alive\r\n\r\n"), 4862 }; 4863 4864 MockRead data_reads1[] = { 4865 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4866 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4867 MockRead("Content-Length: 10\r\n\r\n"), 4868 MockRead(SYNCHRONOUS, ERR_FAILED), 4869 }; 4870 4871 // After the challenge above, the transaction will be restarted using the 4872 // identity supplied by the user, not the one in the URL, to answer the 4873 // challenge. 4874 MockWrite data_writes3[] = { 4875 MockWrite("GET / HTTP/1.1\r\n" 4876 "Host: www.google.com\r\n" 4877 "Connection: keep-alive\r\n" 4878 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 4879 }; 4880 4881 MockRead data_reads3[] = { 4882 MockRead("HTTP/1.0 200 OK\r\n"), 4883 MockRead("Content-Length: 100\r\n\r\n"), 4884 MockRead(SYNCHRONOUS, OK), 4885 }; 4886 4887 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4888 data_writes1, arraysize(data_writes1)); 4889 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4890 data_writes3, arraysize(data_writes3)); 4891 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4892 session_deps_.socket_factory->AddSocketDataProvider(&data3); 4893 4894 TestCompletionCallback callback1; 4895 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4896 EXPECT_EQ(ERR_IO_PENDING, rv); 4897 rv = callback1.WaitForResult(); 4898 EXPECT_EQ(OK, rv); 4899 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4900 4901 const HttpResponseInfo* response = trans->GetResponseInfo(); 4902 ASSERT_TRUE(response != NULL); 4903 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 4904 4905 TestCompletionCallback callback3; 4906 rv = trans->RestartWithAuth( 4907 AuthCredentials(kFoo, kBar), callback3.callback()); 4908 EXPECT_EQ(ERR_IO_PENDING, rv); 4909 rv = callback3.WaitForResult(); 4910 EXPECT_EQ(OK, rv); 4911 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4912 4913 response = trans->GetResponseInfo(); 4914 ASSERT_TRUE(response != NULL); 4915 4916 // There is no challenge info, since the identity worked. 4917 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4918 EXPECT_EQ(100, response->headers->GetContentLength()); 4919 4920 // Empty the current queue. 4921 base::MessageLoop::current()->RunUntilIdle(); 4922 } 4923 4924 // Test that previously tried username/passwords for a realm get re-used. 4925 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { 4926 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4927 4928 // Transaction 1: authenticate (foo, bar) on MyRealm1 4929 { 4930 HttpRequestInfo request; 4931 request.method = "GET"; 4932 request.url = GURL("http://www.google.com/x/y/z"); 4933 request.load_flags = 0; 4934 4935 scoped_ptr<HttpTransaction> trans( 4936 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4937 4938 MockWrite data_writes1[] = { 4939 MockWrite("GET /x/y/z HTTP/1.1\r\n" 4940 "Host: www.google.com\r\n" 4941 "Connection: keep-alive\r\n\r\n"), 4942 }; 4943 4944 MockRead data_reads1[] = { 4945 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4946 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4947 MockRead("Content-Length: 10000\r\n\r\n"), 4948 MockRead(SYNCHRONOUS, ERR_FAILED), 4949 }; 4950 4951 // Resend with authorization (username=foo, password=bar) 4952 MockWrite data_writes2[] = { 4953 MockWrite("GET /x/y/z HTTP/1.1\r\n" 4954 "Host: www.google.com\r\n" 4955 "Connection: keep-alive\r\n" 4956 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 4957 }; 4958 4959 // Sever accepts the authorization. 4960 MockRead data_reads2[] = { 4961 MockRead("HTTP/1.0 200 OK\r\n"), 4962 MockRead("Content-Length: 100\r\n\r\n"), 4963 MockRead(SYNCHRONOUS, OK), 4964 }; 4965 4966 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4967 data_writes1, arraysize(data_writes1)); 4968 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4969 data_writes2, arraysize(data_writes2)); 4970 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4971 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4972 4973 TestCompletionCallback callback1; 4974 4975 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4976 EXPECT_EQ(ERR_IO_PENDING, rv); 4977 4978 rv = callback1.WaitForResult(); 4979 EXPECT_EQ(OK, rv); 4980 4981 const HttpResponseInfo* response = trans->GetResponseInfo(); 4982 ASSERT_TRUE(response != NULL); 4983 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 4984 4985 TestCompletionCallback callback2; 4986 4987 rv = trans->RestartWithAuth( 4988 AuthCredentials(kFoo, kBar), callback2.callback()); 4989 EXPECT_EQ(ERR_IO_PENDING, rv); 4990 4991 rv = callback2.WaitForResult(); 4992 EXPECT_EQ(OK, rv); 4993 4994 response = trans->GetResponseInfo(); 4995 ASSERT_TRUE(response != NULL); 4996 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4997 EXPECT_EQ(100, response->headers->GetContentLength()); 4998 } 4999 5000 // ------------------------------------------------------------------------ 5001 5002 // Transaction 2: authenticate (foo2, bar2) on MyRealm2 5003 { 5004 HttpRequestInfo request; 5005 request.method = "GET"; 5006 // Note that Transaction 1 was at /x/y/z, so this is in the same 5007 // protection space as MyRealm1. 5008 request.url = GURL("http://www.google.com/x/y/a/b"); 5009 request.load_flags = 0; 5010 5011 scoped_ptr<HttpTransaction> trans( 5012 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5013 5014 MockWrite data_writes1[] = { 5015 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5016 "Host: www.google.com\r\n" 5017 "Connection: keep-alive\r\n" 5018 // Send preemptive authorization for MyRealm1 5019 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5020 }; 5021 5022 // The server didn't like the preemptive authorization, and 5023 // challenges us for a different realm (MyRealm2). 5024 MockRead data_reads1[] = { 5025 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5026 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"), 5027 MockRead("Content-Length: 10000\r\n\r\n"), 5028 MockRead(SYNCHRONOUS, ERR_FAILED), 5029 }; 5030 5031 // Resend with authorization for MyRealm2 (username=foo2, password=bar2) 5032 MockWrite data_writes2[] = { 5033 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5034 "Host: www.google.com\r\n" 5035 "Connection: keep-alive\r\n" 5036 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 5037 }; 5038 5039 // Sever accepts the authorization. 5040 MockRead data_reads2[] = { 5041 MockRead("HTTP/1.0 200 OK\r\n"), 5042 MockRead("Content-Length: 100\r\n\r\n"), 5043 MockRead(SYNCHRONOUS, OK), 5044 }; 5045 5046 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5047 data_writes1, arraysize(data_writes1)); 5048 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5049 data_writes2, arraysize(data_writes2)); 5050 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5051 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5052 5053 TestCompletionCallback callback1; 5054 5055 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5056 EXPECT_EQ(ERR_IO_PENDING, rv); 5057 5058 rv = callback1.WaitForResult(); 5059 EXPECT_EQ(OK, rv); 5060 5061 const HttpResponseInfo* response = trans->GetResponseInfo(); 5062 ASSERT_TRUE(response != NULL); 5063 ASSERT_TRUE(response->auth_challenge.get()); 5064 EXPECT_FALSE(response->auth_challenge->is_proxy); 5065 EXPECT_EQ("www.google.com:80", 5066 response->auth_challenge->challenger.ToString()); 5067 EXPECT_EQ("MyRealm2", response->auth_challenge->realm); 5068 EXPECT_EQ("basic", response->auth_challenge->scheme); 5069 5070 TestCompletionCallback callback2; 5071 5072 rv = trans->RestartWithAuth( 5073 AuthCredentials(kFoo2, kBar2), callback2.callback()); 5074 EXPECT_EQ(ERR_IO_PENDING, rv); 5075 5076 rv = callback2.WaitForResult(); 5077 EXPECT_EQ(OK, rv); 5078 5079 response = trans->GetResponseInfo(); 5080 ASSERT_TRUE(response != NULL); 5081 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5082 EXPECT_EQ(100, response->headers->GetContentLength()); 5083 } 5084 5085 // ------------------------------------------------------------------------ 5086 5087 // Transaction 3: Resend a request in MyRealm's protection space -- 5088 // succeed with preemptive authorization. 5089 { 5090 HttpRequestInfo request; 5091 request.method = "GET"; 5092 request.url = GURL("http://www.google.com/x/y/z2"); 5093 request.load_flags = 0; 5094 5095 scoped_ptr<HttpTransaction> trans( 5096 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5097 5098 MockWrite data_writes1[] = { 5099 MockWrite("GET /x/y/z2 HTTP/1.1\r\n" 5100 "Host: www.google.com\r\n" 5101 "Connection: keep-alive\r\n" 5102 // The authorization for MyRealm1 gets sent preemptively 5103 // (since the url is in the same protection space) 5104 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5105 }; 5106 5107 // Sever accepts the preemptive authorization 5108 MockRead data_reads1[] = { 5109 MockRead("HTTP/1.0 200 OK\r\n"), 5110 MockRead("Content-Length: 100\r\n\r\n"), 5111 MockRead(SYNCHRONOUS, OK), 5112 }; 5113 5114 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5115 data_writes1, arraysize(data_writes1)); 5116 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5117 5118 TestCompletionCallback callback1; 5119 5120 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5121 EXPECT_EQ(ERR_IO_PENDING, rv); 5122 5123 rv = callback1.WaitForResult(); 5124 EXPECT_EQ(OK, rv); 5125 5126 const HttpResponseInfo* response = trans->GetResponseInfo(); 5127 ASSERT_TRUE(response != NULL); 5128 5129 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5130 EXPECT_EQ(100, response->headers->GetContentLength()); 5131 } 5132 5133 // ------------------------------------------------------------------------ 5134 5135 // Transaction 4: request another URL in MyRealm (however the 5136 // url is not known to belong to the protection space, so no pre-auth). 5137 { 5138 HttpRequestInfo request; 5139 request.method = "GET"; 5140 request.url = GURL("http://www.google.com/x/1"); 5141 request.load_flags = 0; 5142 5143 scoped_ptr<HttpTransaction> trans( 5144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5145 5146 MockWrite data_writes1[] = { 5147 MockWrite("GET /x/1 HTTP/1.1\r\n" 5148 "Host: www.google.com\r\n" 5149 "Connection: keep-alive\r\n\r\n"), 5150 }; 5151 5152 MockRead data_reads1[] = { 5153 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5154 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5155 MockRead("Content-Length: 10000\r\n\r\n"), 5156 MockRead(SYNCHRONOUS, ERR_FAILED), 5157 }; 5158 5159 // Resend with authorization from MyRealm's cache. 5160 MockWrite data_writes2[] = { 5161 MockWrite("GET /x/1 HTTP/1.1\r\n" 5162 "Host: www.google.com\r\n" 5163 "Connection: keep-alive\r\n" 5164 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5165 }; 5166 5167 // Sever accepts the authorization. 5168 MockRead data_reads2[] = { 5169 MockRead("HTTP/1.0 200 OK\r\n"), 5170 MockRead("Content-Length: 100\r\n\r\n"), 5171 MockRead(SYNCHRONOUS, OK), 5172 }; 5173 5174 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5175 data_writes1, arraysize(data_writes1)); 5176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5177 data_writes2, arraysize(data_writes2)); 5178 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5179 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5180 5181 TestCompletionCallback callback1; 5182 5183 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5184 EXPECT_EQ(ERR_IO_PENDING, rv); 5185 5186 rv = callback1.WaitForResult(); 5187 EXPECT_EQ(OK, rv); 5188 5189 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5190 TestCompletionCallback callback2; 5191 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5192 EXPECT_EQ(ERR_IO_PENDING, rv); 5193 rv = callback2.WaitForResult(); 5194 EXPECT_EQ(OK, rv); 5195 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5196 5197 const HttpResponseInfo* response = trans->GetResponseInfo(); 5198 ASSERT_TRUE(response != NULL); 5199 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5200 EXPECT_EQ(100, response->headers->GetContentLength()); 5201 } 5202 5203 // ------------------------------------------------------------------------ 5204 5205 // Transaction 5: request a URL in MyRealm, but the server rejects the 5206 // cached identity. Should invalidate and re-prompt. 5207 { 5208 HttpRequestInfo request; 5209 request.method = "GET"; 5210 request.url = GURL("http://www.google.com/p/q/t"); 5211 request.load_flags = 0; 5212 5213 scoped_ptr<HttpTransaction> trans( 5214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5215 5216 MockWrite data_writes1[] = { 5217 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5218 "Host: www.google.com\r\n" 5219 "Connection: keep-alive\r\n\r\n"), 5220 }; 5221 5222 MockRead data_reads1[] = { 5223 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5224 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5225 MockRead("Content-Length: 10000\r\n\r\n"), 5226 MockRead(SYNCHRONOUS, ERR_FAILED), 5227 }; 5228 5229 // Resend with authorization from cache for MyRealm. 5230 MockWrite data_writes2[] = { 5231 MockWrite("GET /p/q/t 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 // Sever rejects the authorization. 5238 MockRead data_reads2[] = { 5239 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5240 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5241 MockRead("Content-Length: 10000\r\n\r\n"), 5242 MockRead(SYNCHRONOUS, ERR_FAILED), 5243 }; 5244 5245 // At this point we should prompt for new credentials for MyRealm. 5246 // Restart with username=foo3, password=foo4. 5247 MockWrite data_writes3[] = { 5248 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5249 "Host: www.google.com\r\n" 5250 "Connection: keep-alive\r\n" 5251 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"), 5252 }; 5253 5254 // Sever accepts the authorization. 5255 MockRead data_reads3[] = { 5256 MockRead("HTTP/1.0 200 OK\r\n"), 5257 MockRead("Content-Length: 100\r\n\r\n"), 5258 MockRead(SYNCHRONOUS, OK), 5259 }; 5260 5261 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5262 data_writes1, arraysize(data_writes1)); 5263 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5264 data_writes2, arraysize(data_writes2)); 5265 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 5266 data_writes3, arraysize(data_writes3)); 5267 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5268 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5269 session_deps_.socket_factory->AddSocketDataProvider(&data3); 5270 5271 TestCompletionCallback callback1; 5272 5273 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5274 EXPECT_EQ(ERR_IO_PENDING, rv); 5275 5276 rv = callback1.WaitForResult(); 5277 EXPECT_EQ(OK, rv); 5278 5279 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5280 TestCompletionCallback callback2; 5281 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5282 EXPECT_EQ(ERR_IO_PENDING, rv); 5283 rv = callback2.WaitForResult(); 5284 EXPECT_EQ(OK, rv); 5285 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5286 5287 const HttpResponseInfo* response = trans->GetResponseInfo(); 5288 ASSERT_TRUE(response != NULL); 5289 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5290 5291 TestCompletionCallback callback3; 5292 5293 rv = trans->RestartWithAuth( 5294 AuthCredentials(kFoo3, kBar3), callback3.callback()); 5295 EXPECT_EQ(ERR_IO_PENDING, rv); 5296 5297 rv = callback3.WaitForResult(); 5298 EXPECT_EQ(OK, rv); 5299 5300 response = trans->GetResponseInfo(); 5301 ASSERT_TRUE(response != NULL); 5302 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5303 EXPECT_EQ(100, response->headers->GetContentLength()); 5304 } 5305 } 5306 5307 // Tests that nonce count increments when multiple auth attempts 5308 // are started with the same nonce. 5309 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) { 5310 HttpAuthHandlerDigest::Factory* digest_factory = 5311 new HttpAuthHandlerDigest::Factory(); 5312 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator = 5313 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef"); 5314 digest_factory->set_nonce_generator(nonce_generator); 5315 session_deps_.http_auth_handler_factory.reset(digest_factory); 5316 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5317 5318 // Transaction 1: authenticate (foo, bar) on MyRealm1 5319 { 5320 HttpRequestInfo request; 5321 request.method = "GET"; 5322 request.url = GURL("http://www.google.com/x/y/z"); 5323 request.load_flags = 0; 5324 5325 scoped_ptr<HttpTransaction> trans( 5326 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5327 5328 MockWrite data_writes1[] = { 5329 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5330 "Host: www.google.com\r\n" 5331 "Connection: keep-alive\r\n\r\n"), 5332 }; 5333 5334 MockRead data_reads1[] = { 5335 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5336 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", " 5337 "algorithm=MD5, qop=\"auth\"\r\n\r\n"), 5338 MockRead(SYNCHRONOUS, OK), 5339 }; 5340 5341 // Resend with authorization (username=foo, password=bar) 5342 MockWrite data_writes2[] = { 5343 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5344 "Host: www.google.com\r\n" 5345 "Connection: keep-alive\r\n" 5346 "Authorization: Digest username=\"foo\", realm=\"digestive\", " 5347 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, " 5348 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, " 5349 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"), 5350 }; 5351 5352 // Sever accepts the authorization. 5353 MockRead data_reads2[] = { 5354 MockRead("HTTP/1.0 200 OK\r\n"), 5355 MockRead(SYNCHRONOUS, OK), 5356 }; 5357 5358 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5359 data_writes1, arraysize(data_writes1)); 5360 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5361 data_writes2, arraysize(data_writes2)); 5362 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5363 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5364 5365 TestCompletionCallback callback1; 5366 5367 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5368 EXPECT_EQ(ERR_IO_PENDING, rv); 5369 5370 rv = callback1.WaitForResult(); 5371 EXPECT_EQ(OK, rv); 5372 5373 const HttpResponseInfo* response = trans->GetResponseInfo(); 5374 ASSERT_TRUE(response != NULL); 5375 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get())); 5376 5377 TestCompletionCallback callback2; 5378 5379 rv = trans->RestartWithAuth( 5380 AuthCredentials(kFoo, kBar), callback2.callback()); 5381 EXPECT_EQ(ERR_IO_PENDING, rv); 5382 5383 rv = callback2.WaitForResult(); 5384 EXPECT_EQ(OK, rv); 5385 5386 response = trans->GetResponseInfo(); 5387 ASSERT_TRUE(response != NULL); 5388 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5389 } 5390 5391 // ------------------------------------------------------------------------ 5392 5393 // Transaction 2: Request another resource in digestive's protection space. 5394 // This will preemptively add an Authorization header which should have an 5395 // "nc" value of 2 (as compared to 1 in the first use. 5396 { 5397 HttpRequestInfo request; 5398 request.method = "GET"; 5399 // Note that Transaction 1 was at /x/y/z, so this is in the same 5400 // protection space as digest. 5401 request.url = GURL("http://www.google.com/x/y/a/b"); 5402 request.load_flags = 0; 5403 5404 scoped_ptr<HttpTransaction> trans( 5405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5406 5407 MockWrite data_writes1[] = { 5408 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5409 "Host: www.google.com\r\n" 5410 "Connection: keep-alive\r\n" 5411 "Authorization: Digest username=\"foo\", realm=\"digestive\", " 5412 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, " 5413 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, " 5414 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"), 5415 }; 5416 5417 // Sever accepts the authorization. 5418 MockRead data_reads1[] = { 5419 MockRead("HTTP/1.0 200 OK\r\n"), 5420 MockRead("Content-Length: 100\r\n\r\n"), 5421 MockRead(SYNCHRONOUS, OK), 5422 }; 5423 5424 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5425 data_writes1, arraysize(data_writes1)); 5426 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5427 5428 TestCompletionCallback callback1; 5429 5430 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5431 EXPECT_EQ(ERR_IO_PENDING, rv); 5432 5433 rv = callback1.WaitForResult(); 5434 EXPECT_EQ(OK, rv); 5435 5436 const HttpResponseInfo* response = trans->GetResponseInfo(); 5437 ASSERT_TRUE(response != NULL); 5438 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5439 } 5440 } 5441 5442 // Test the ResetStateForRestart() private method. 5443 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) { 5444 // Create a transaction (the dependencies aren't important). 5445 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5446 scoped_ptr<HttpNetworkTransaction> trans( 5447 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5448 5449 // Setup some state (which we expect ResetStateForRestart() will clear). 5450 trans->read_buf_ = new IOBuffer(15); 5451 trans->read_buf_len_ = 15; 5452 trans->request_headers_.SetHeader("Authorization", "NTLM"); 5453 5454 // Setup state in response_ 5455 HttpResponseInfo* response = &trans->response_; 5456 response->auth_challenge = new AuthChallengeInfo(); 5457 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical. 5458 response->response_time = base::Time::Now(); 5459 response->was_cached = true; // (Wouldn't ever actually be true...) 5460 5461 { // Setup state for response_.vary_data 5462 HttpRequestInfo request; 5463 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n"); 5464 std::replace(temp.begin(), temp.end(), '\n', '\0'); 5465 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp)); 5466 request.extra_headers.SetHeader("Foo", "1"); 5467 request.extra_headers.SetHeader("bar", "23"); 5468 EXPECT_TRUE(response->vary_data.Init(request, *headers.get())); 5469 } 5470 5471 // Cause the above state to be reset. 5472 trans->ResetStateForRestart(); 5473 5474 // Verify that the state that needed to be reset, has been reset. 5475 EXPECT_TRUE(trans->read_buf_.get() == NULL); 5476 EXPECT_EQ(0, trans->read_buf_len_); 5477 EXPECT_TRUE(trans->request_headers_.IsEmpty()); 5478 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5479 EXPECT_TRUE(response->headers.get() == NULL); 5480 EXPECT_FALSE(response->was_cached); 5481 EXPECT_EQ(0U, response->ssl_info.cert_status); 5482 EXPECT_FALSE(response->vary_data.is_valid()); 5483 } 5484 5485 // Test HTTPS connections to a site with a bad certificate 5486 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) { 5487 HttpRequestInfo request; 5488 request.method = "GET"; 5489 request.url = GURL("https://www.google.com/"); 5490 request.load_flags = 0; 5491 5492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5493 scoped_ptr<HttpTransaction> trans( 5494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5495 5496 MockWrite data_writes[] = { 5497 MockWrite("GET / HTTP/1.1\r\n" 5498 "Host: www.google.com\r\n" 5499 "Connection: keep-alive\r\n\r\n"), 5500 }; 5501 5502 MockRead data_reads[] = { 5503 MockRead("HTTP/1.0 200 OK\r\n"), 5504 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5505 MockRead("Content-Length: 100\r\n\r\n"), 5506 MockRead(SYNCHRONOUS, OK), 5507 }; 5508 5509 StaticSocketDataProvider ssl_bad_certificate; 5510 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5511 data_writes, arraysize(data_writes)); 5512 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 5513 SSLSocketDataProvider ssl(ASYNC, OK); 5514 5515 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 5516 session_deps_.socket_factory->AddSocketDataProvider(&data); 5517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 5518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 5519 5520 TestCompletionCallback callback; 5521 5522 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5523 EXPECT_EQ(ERR_IO_PENDING, rv); 5524 5525 rv = callback.WaitForResult(); 5526 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 5527 5528 rv = trans->RestartIgnoringLastError(callback.callback()); 5529 EXPECT_EQ(ERR_IO_PENDING, rv); 5530 5531 rv = callback.WaitForResult(); 5532 EXPECT_EQ(OK, rv); 5533 5534 const HttpResponseInfo* response = trans->GetResponseInfo(); 5535 5536 ASSERT_TRUE(response != NULL); 5537 EXPECT_EQ(100, response->headers->GetContentLength()); 5538 } 5539 5540 // Test HTTPS connections to a site with a bad certificate, going through a 5541 // proxy 5542 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { 5543 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 5544 5545 HttpRequestInfo request; 5546 request.method = "GET"; 5547 request.url = GURL("https://www.google.com/"); 5548 request.load_flags = 0; 5549 5550 MockWrite proxy_writes[] = { 5551 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 5552 "Host: www.google.com\r\n" 5553 "Proxy-Connection: keep-alive\r\n\r\n"), 5554 }; 5555 5556 MockRead proxy_reads[] = { 5557 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 5558 MockRead(SYNCHRONOUS, OK) 5559 }; 5560 5561 MockWrite data_writes[] = { 5562 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 5563 "Host: www.google.com\r\n" 5564 "Proxy-Connection: keep-alive\r\n\r\n"), 5565 MockWrite("GET / HTTP/1.1\r\n" 5566 "Host: www.google.com\r\n" 5567 "Connection: keep-alive\r\n\r\n"), 5568 }; 5569 5570 MockRead data_reads[] = { 5571 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 5572 MockRead("HTTP/1.0 200 OK\r\n"), 5573 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5574 MockRead("Content-Length: 100\r\n\r\n"), 5575 MockRead(SYNCHRONOUS, OK), 5576 }; 5577 5578 StaticSocketDataProvider ssl_bad_certificate( 5579 proxy_reads, arraysize(proxy_reads), 5580 proxy_writes, arraysize(proxy_writes)); 5581 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5582 data_writes, arraysize(data_writes)); 5583 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 5584 SSLSocketDataProvider ssl(ASYNC, OK); 5585 5586 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 5587 session_deps_.socket_factory->AddSocketDataProvider(&data); 5588 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 5589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 5590 5591 TestCompletionCallback callback; 5592 5593 for (int i = 0; i < 2; i++) { 5594 session_deps_.socket_factory->ResetNextMockIndexes(); 5595 5596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5597 scoped_ptr<HttpTransaction> trans( 5598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5599 5600 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5601 EXPECT_EQ(ERR_IO_PENDING, rv); 5602 5603 rv = callback.WaitForResult(); 5604 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 5605 5606 rv = trans->RestartIgnoringLastError(callback.callback()); 5607 EXPECT_EQ(ERR_IO_PENDING, rv); 5608 5609 rv = callback.WaitForResult(); 5610 EXPECT_EQ(OK, rv); 5611 5612 const HttpResponseInfo* response = trans->GetResponseInfo(); 5613 5614 ASSERT_TRUE(response != NULL); 5615 EXPECT_EQ(100, response->headers->GetContentLength()); 5616 } 5617 } 5618 5619 5620 // Test HTTPS connections to a site, going through an HTTPS proxy 5621 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { 5622 session_deps_.proxy_service.reset( 5623 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 5624 CapturingNetLog net_log; 5625 session_deps_.net_log = &net_log; 5626 5627 HttpRequestInfo request; 5628 request.method = "GET"; 5629 request.url = GURL("https://www.google.com/"); 5630 request.load_flags = 0; 5631 5632 MockWrite data_writes[] = { 5633 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 5634 "Host: www.google.com\r\n" 5635 "Proxy-Connection: keep-alive\r\n\r\n"), 5636 MockWrite("GET / HTTP/1.1\r\n" 5637 "Host: www.google.com\r\n" 5638 "Connection: keep-alive\r\n\r\n"), 5639 }; 5640 5641 MockRead data_reads[] = { 5642 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 5643 MockRead("HTTP/1.1 200 OK\r\n"), 5644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5645 MockRead("Content-Length: 100\r\n\r\n"), 5646 MockRead(SYNCHRONOUS, OK), 5647 }; 5648 5649 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5650 data_writes, arraysize(data_writes)); 5651 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 5652 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel 5653 5654 session_deps_.socket_factory->AddSocketDataProvider(&data); 5655 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 5656 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl); 5657 5658 TestCompletionCallback callback; 5659 5660 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5661 scoped_ptr<HttpTransaction> trans( 5662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5663 5664 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5665 EXPECT_EQ(ERR_IO_PENDING, rv); 5666 5667 rv = callback.WaitForResult(); 5668 EXPECT_EQ(OK, rv); 5669 const HttpResponseInfo* response = trans->GetResponseInfo(); 5670 5671 ASSERT_TRUE(response != NULL); 5672 5673 EXPECT_TRUE(response->headers->IsKeepAlive()); 5674 EXPECT_EQ(200, response->headers->response_code()); 5675 EXPECT_EQ(100, response->headers->GetContentLength()); 5676 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 5677 5678 LoadTimingInfo load_timing_info; 5679 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 5680 TestLoadTimingNotReusedWithPac(load_timing_info, 5681 CONNECT_TIMING_HAS_SSL_TIMES); 5682 } 5683 5684 // Test an HTTPS Proxy's ability to redirect a CONNECT request 5685 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { 5686 session_deps_.proxy_service.reset( 5687 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 5688 CapturingNetLog net_log; 5689 session_deps_.net_log = &net_log; 5690 5691 HttpRequestInfo request; 5692 request.method = "GET"; 5693 request.url = GURL("https://www.google.com/"); 5694 request.load_flags = 0; 5695 5696 MockWrite data_writes[] = { 5697 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 5698 "Host: www.google.com\r\n" 5699 "Proxy-Connection: keep-alive\r\n\r\n"), 5700 }; 5701 5702 MockRead data_reads[] = { 5703 MockRead("HTTP/1.1 302 Redirect\r\n"), 5704 MockRead("Location: http://login.example.com/\r\n"), 5705 MockRead("Content-Length: 0\r\n\r\n"), 5706 MockRead(SYNCHRONOUS, OK), 5707 }; 5708 5709 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5710 data_writes, arraysize(data_writes)); 5711 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 5712 5713 session_deps_.socket_factory->AddSocketDataProvider(&data); 5714 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 5715 5716 TestCompletionCallback callback; 5717 5718 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5719 scoped_ptr<HttpTransaction> trans( 5720 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5721 5722 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5723 EXPECT_EQ(ERR_IO_PENDING, rv); 5724 5725 rv = callback.WaitForResult(); 5726 EXPECT_EQ(OK, rv); 5727 const HttpResponseInfo* response = trans->GetResponseInfo(); 5728 5729 ASSERT_TRUE(response != NULL); 5730 5731 EXPECT_EQ(302, response->headers->response_code()); 5732 std::string url; 5733 EXPECT_TRUE(response->headers->IsRedirect(&url)); 5734 EXPECT_EQ("http://login.example.com/", url); 5735 5736 // In the case of redirects from proxies, HttpNetworkTransaction returns 5737 // timing for the proxy connection instead of the connection to the host, 5738 // and no send / receive times. 5739 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse. 5740 LoadTimingInfo load_timing_info; 5741 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 5742 5743 EXPECT_FALSE(load_timing_info.socket_reused); 5744 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 5745 5746 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 5747 EXPECT_LE(load_timing_info.proxy_resolve_start, 5748 load_timing_info.proxy_resolve_end); 5749 EXPECT_LE(load_timing_info.proxy_resolve_end, 5750 load_timing_info.connect_timing.connect_start); 5751 ExpectConnectTimingHasTimes( 5752 load_timing_info.connect_timing, 5753 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES); 5754 5755 EXPECT_TRUE(load_timing_info.send_start.is_null()); 5756 EXPECT_TRUE(load_timing_info.send_end.is_null()); 5757 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 5758 } 5759 5760 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request 5761 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { 5762 session_deps_.proxy_service.reset( 5763 ProxyService::CreateFixed("https://proxy:70")); 5764 5765 HttpRequestInfo request; 5766 request.method = "GET"; 5767 request.url = GURL("https://www.google.com/"); 5768 request.load_flags = 0; 5769 5770 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 5771 LOWEST)); 5772 scoped_ptr<SpdyFrame> goaway( 5773 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 5774 MockWrite data_writes[] = { 5775 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS), 5776 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS), 5777 }; 5778 5779 static const char* const kExtraHeaders[] = { 5780 "location", 5781 "http://login.example.com/", 5782 }; 5783 scoped_ptr<SpdyFrame> resp( 5784 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders, 5785 arraysize(kExtraHeaders)/2, 1)); 5786 MockRead data_reads[] = { 5787 CreateMockRead(*resp.get(), 1, SYNCHRONOUS), 5788 MockRead(ASYNC, 0, 2), // EOF 5789 }; 5790 5791 DelayedSocketData data( 5792 1, // wait for one write to finish before reading. 5793 data_reads, arraysize(data_reads), 5794 data_writes, arraysize(data_writes)); 5795 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 5796 proxy_ssl.SetNextProto(GetParam()); 5797 5798 session_deps_.socket_factory->AddSocketDataProvider(&data); 5799 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 5800 5801 TestCompletionCallback callback; 5802 5803 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5804 scoped_ptr<HttpTransaction> trans( 5805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5806 5807 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5808 EXPECT_EQ(ERR_IO_PENDING, rv); 5809 5810 rv = callback.WaitForResult(); 5811 EXPECT_EQ(OK, rv); 5812 const HttpResponseInfo* response = trans->GetResponseInfo(); 5813 5814 ASSERT_TRUE(response != NULL); 5815 5816 EXPECT_EQ(302, response->headers->response_code()); 5817 std::string url; 5818 EXPECT_TRUE(response->headers->IsRedirect(&url)); 5819 EXPECT_EQ("http://login.example.com/", url); 5820 } 5821 5822 // Test that an HTTPS proxy's response to a CONNECT request is filtered. 5823 TEST_P(HttpNetworkTransactionTest, 5824 ErrorResponseToHttpsConnectViaHttpsProxy) { 5825 session_deps_.proxy_service.reset( 5826 ProxyService::CreateFixed("https://proxy:70")); 5827 5828 HttpRequestInfo request; 5829 request.method = "GET"; 5830 request.url = GURL("https://www.google.com/"); 5831 request.load_flags = 0; 5832 5833 MockWrite data_writes[] = { 5834 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 5835 "Host: www.google.com\r\n" 5836 "Proxy-Connection: keep-alive\r\n\r\n"), 5837 }; 5838 5839 MockRead data_reads[] = { 5840 MockRead("HTTP/1.1 404 Not Found\r\n"), 5841 MockRead("Content-Length: 23\r\n\r\n"), 5842 MockRead("The host does not exist"), 5843 MockRead(SYNCHRONOUS, OK), 5844 }; 5845 5846 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5847 data_writes, arraysize(data_writes)); 5848 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 5849 5850 session_deps_.socket_factory->AddSocketDataProvider(&data); 5851 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 5852 5853 TestCompletionCallback callback; 5854 5855 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5856 scoped_ptr<HttpTransaction> trans( 5857 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5858 5859 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5860 EXPECT_EQ(ERR_IO_PENDING, rv); 5861 5862 rv = callback.WaitForResult(); 5863 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 5864 5865 // TODO(ttuttle): Anything else to check here? 5866 } 5867 5868 // Test that a SPDY proxy's response to a CONNECT request is filtered. 5869 TEST_P(HttpNetworkTransactionTest, 5870 ErrorResponseToHttpsConnectViaSpdyProxy) { 5871 session_deps_.proxy_service.reset( 5872 ProxyService::CreateFixed("https://proxy:70")); 5873 5874 HttpRequestInfo request; 5875 request.method = "GET"; 5876 request.url = GURL("https://www.google.com/"); 5877 request.load_flags = 0; 5878 5879 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 5880 LOWEST)); 5881 scoped_ptr<SpdyFrame> rst( 5882 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 5883 MockWrite data_writes[] = { 5884 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS), 5885 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS), 5886 }; 5887 5888 static const char* const kExtraHeaders[] = { 5889 "location", 5890 "http://login.example.com/", 5891 }; 5892 scoped_ptr<SpdyFrame> resp( 5893 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders, 5894 arraysize(kExtraHeaders)/2, 1)); 5895 scoped_ptr<SpdyFrame> body( 5896 spdy_util_.ConstructSpdyBodyFrame( 5897 1, "The host does not exist", 23, true)); 5898 MockRead data_reads[] = { 5899 CreateMockRead(*resp.get(), 1, SYNCHRONOUS), 5900 CreateMockRead(*body.get(), 2, SYNCHRONOUS), 5901 MockRead(ASYNC, 0, 4), // EOF 5902 }; 5903 5904 DelayedSocketData data( 5905 1, // wait for one write to finish before reading. 5906 data_reads, arraysize(data_reads), 5907 data_writes, arraysize(data_writes)); 5908 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 5909 proxy_ssl.SetNextProto(GetParam()); 5910 5911 session_deps_.socket_factory->AddSocketDataProvider(&data); 5912 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 5913 5914 TestCompletionCallback callback; 5915 5916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5917 scoped_ptr<HttpTransaction> trans( 5918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5919 5920 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5921 EXPECT_EQ(ERR_IO_PENDING, rv); 5922 5923 rv = callback.WaitForResult(); 5924 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 5925 5926 // TODO(ttuttle): Anything else to check here? 5927 } 5928 5929 // Test the request-challenge-retry sequence for basic auth, through 5930 // a SPDY proxy over a single SPDY session. 5931 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) { 5932 HttpRequestInfo request; 5933 request.method = "GET"; 5934 request.url = GURL("https://www.google.com/"); 5935 // when the no authentication data flag is set. 5936 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 5937 5938 // Configure against https proxy server "myproxy:70". 5939 session_deps_.proxy_service.reset( 5940 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); 5941 CapturingBoundNetLog log; 5942 session_deps_.net_log = log.bound().net_log(); 5943 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5944 5945 // Since we have proxy, should try to establish tunnel. 5946 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 5947 LOWEST)); 5948 scoped_ptr<SpdyFrame> rst( 5949 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 5950 5951 // After calling trans->RestartWithAuth(), this is the request we should 5952 // be issuing -- the final header line contains the credentials. 5953 const char* const kAuthCredentials[] = { 5954 "proxy-authorization", "Basic Zm9vOmJhcg==", 5955 }; 5956 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect( 5957 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST)); 5958 // fetch https://www.google.com/ via HTTP 5959 const char get[] = "GET / HTTP/1.1\r\n" 5960 "Host: www.google.com\r\n" 5961 "Connection: keep-alive\r\n\r\n"; 5962 scoped_ptr<SpdyFrame> wrapped_get( 5963 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false)); 5964 5965 MockWrite spdy_writes[] = { 5966 CreateMockWrite(*req, 1, ASYNC), 5967 CreateMockWrite(*rst, 4, ASYNC), 5968 CreateMockWrite(*connect2, 5), 5969 CreateMockWrite(*wrapped_get, 8), 5970 }; 5971 5972 // The proxy responds to the connect with a 407, using a persistent 5973 // connection. 5974 const char* const kAuthChallenge[] = { 5975 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required", 5976 spdy_util_.GetVersionKey(), "HTTP/1.1", 5977 "proxy-authenticate", "Basic realm=\"MyRealm1\"", 5978 }; 5979 5980 scoped_ptr<SpdyFrame> conn_auth_resp( 5981 spdy_util_.ConstructSpdyControlFrame(NULL, 5982 0, 5983 false, 5984 1, 5985 LOWEST, 5986 SYN_REPLY, 5987 CONTROL_FLAG_NONE, 5988 kAuthChallenge, 5989 arraysize(kAuthChallenge), 5990 0)); 5991 5992 scoped_ptr<SpdyFrame> conn_resp( 5993 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 5994 const char resp[] = "HTTP/1.1 200 OK\r\n" 5995 "Content-Length: 5\r\n\r\n"; 5996 5997 scoped_ptr<SpdyFrame> wrapped_get_resp( 5998 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false)); 5999 scoped_ptr<SpdyFrame> wrapped_body( 6000 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false)); 6001 MockRead spdy_reads[] = { 6002 CreateMockRead(*conn_auth_resp, 2, ASYNC), 6003 CreateMockRead(*conn_resp, 6, ASYNC), 6004 CreateMockRead(*wrapped_get_resp, 9, ASYNC), 6005 CreateMockRead(*wrapped_body, 10, ASYNC), 6006 MockRead(ASYNC, OK, 11), // EOF. May or may not be read. 6007 }; 6008 6009 OrderedSocketData spdy_data( 6010 spdy_reads, arraysize(spdy_reads), 6011 spdy_writes, arraysize(spdy_writes)); 6012 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6013 // Negotiate SPDY to the proxy 6014 SSLSocketDataProvider proxy(ASYNC, OK); 6015 proxy.SetNextProto(GetParam()); 6016 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6017 // Vanilla SSL to the server 6018 SSLSocketDataProvider server(ASYNC, OK); 6019 session_deps_.socket_factory->AddSSLSocketDataProvider(&server); 6020 6021 TestCompletionCallback callback1; 6022 6023 scoped_ptr<HttpTransaction> trans( 6024 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6025 6026 int rv = trans->Start(&request, callback1.callback(), log.bound()); 6027 EXPECT_EQ(ERR_IO_PENDING, rv); 6028 6029 rv = callback1.WaitForResult(); 6030 EXPECT_EQ(OK, rv); 6031 net::CapturingNetLog::CapturedEntryList entries; 6032 log.GetEntries(&entries); 6033 size_t pos = ExpectLogContainsSomewhere( 6034 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 6035 NetLog::PHASE_NONE); 6036 ExpectLogContainsSomewhere( 6037 entries, pos, 6038 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 6039 NetLog::PHASE_NONE); 6040 6041 const HttpResponseInfo* response = trans->GetResponseInfo(); 6042 ASSERT_TRUE(response != NULL); 6043 ASSERT_FALSE(response->headers.get() == NULL); 6044 EXPECT_EQ(407, response->headers->response_code()); 6045 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6046 EXPECT_TRUE(response->auth_challenge.get() != NULL); 6047 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 6048 6049 TestCompletionCallback callback2; 6050 6051 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), 6052 callback2.callback()); 6053 EXPECT_EQ(ERR_IO_PENDING, rv); 6054 6055 rv = callback2.WaitForResult(); 6056 EXPECT_EQ(OK, rv); 6057 6058 response = trans->GetResponseInfo(); 6059 ASSERT_TRUE(response != NULL); 6060 6061 EXPECT_TRUE(response->headers->IsKeepAlive()); 6062 EXPECT_EQ(200, response->headers->response_code()); 6063 EXPECT_EQ(5, response->headers->GetContentLength()); 6064 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6065 6066 // The password prompt info should not be set. 6067 EXPECT_TRUE(response->auth_challenge.get() == NULL); 6068 6069 LoadTimingInfo load_timing_info; 6070 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6071 TestLoadTimingNotReusedWithPac(load_timing_info, 6072 CONNECT_TIMING_HAS_SSL_TIMES); 6073 6074 trans.reset(); 6075 session->CloseAllConnections(); 6076 } 6077 6078 // Test that an explicitly trusted SPDY proxy can push a resource from an 6079 // origin that is different from that of its associated resource. 6080 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) { 6081 HttpRequestInfo request; 6082 HttpRequestInfo push_request; 6083 6084 request.method = "GET"; 6085 request.url = GURL("http://www.google.com/"); 6086 push_request.method = "GET"; 6087 push_request.url = GURL("http://www.another-origin.com/foo.dat"); 6088 6089 // Configure against https proxy server "myproxy:70". 6090 session_deps_.proxy_service.reset( 6091 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); 6092 CapturingBoundNetLog log; 6093 session_deps_.net_log = log.bound().net_log(); 6094 6095 // Enable cross-origin push. 6096 session_deps_.trusted_spdy_proxy = "myproxy:70"; 6097 6098 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6099 6100 scoped_ptr<SpdyFrame> stream1_syn( 6101 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 6102 6103 MockWrite spdy_writes[] = { 6104 CreateMockWrite(*stream1_syn, 1, ASYNC), 6105 }; 6106 6107 scoped_ptr<SpdyFrame> 6108 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 6109 6110 scoped_ptr<SpdyFrame> 6111 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6112 6113 scoped_ptr<SpdyFrame> 6114 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 6115 0, 6116 2, 6117 1, 6118 "http://www.another-origin.com/foo.dat")); 6119 const char kPushedData[] = "pushed"; 6120 scoped_ptr<SpdyFrame> stream2_body( 6121 spdy_util_.ConstructSpdyBodyFrame( 6122 2, kPushedData, strlen(kPushedData), true)); 6123 6124 MockRead spdy_reads[] = { 6125 CreateMockRead(*stream1_reply, 2, ASYNC), 6126 CreateMockRead(*stream2_syn, 3, ASYNC), 6127 CreateMockRead(*stream1_body, 4, ASYNC), 6128 CreateMockRead(*stream2_body, 5, ASYNC), 6129 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 6130 }; 6131 6132 OrderedSocketData spdy_data( 6133 spdy_reads, arraysize(spdy_reads), 6134 spdy_writes, arraysize(spdy_writes)); 6135 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6136 // Negotiate SPDY to the proxy 6137 SSLSocketDataProvider proxy(ASYNC, OK); 6138 proxy.SetNextProto(GetParam()); 6139 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6140 6141 scoped_ptr<HttpTransaction> trans( 6142 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6143 TestCompletionCallback callback; 6144 int rv = trans->Start(&request, callback.callback(), log.bound()); 6145 EXPECT_EQ(ERR_IO_PENDING, rv); 6146 6147 rv = callback.WaitForResult(); 6148 EXPECT_EQ(OK, rv); 6149 const HttpResponseInfo* response = trans->GetResponseInfo(); 6150 6151 scoped_ptr<HttpTransaction> push_trans( 6152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6153 rv = push_trans->Start(&push_request, callback.callback(), log.bound()); 6154 EXPECT_EQ(ERR_IO_PENDING, rv); 6155 6156 rv = callback.WaitForResult(); 6157 EXPECT_EQ(OK, rv); 6158 const HttpResponseInfo* push_response = push_trans->GetResponseInfo(); 6159 6160 ASSERT_TRUE(response != NULL); 6161 EXPECT_TRUE(response->headers->IsKeepAlive()); 6162 6163 EXPECT_EQ(200, response->headers->response_code()); 6164 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6165 6166 std::string response_data; 6167 rv = ReadTransaction(trans.get(), &response_data); 6168 EXPECT_EQ(OK, rv); 6169 EXPECT_EQ("hello!", response_data); 6170 6171 LoadTimingInfo load_timing_info; 6172 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6173 TestLoadTimingNotReusedWithPac(load_timing_info, 6174 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 6175 6176 // Verify the pushed stream. 6177 EXPECT_TRUE(push_response->headers.get() != NULL); 6178 EXPECT_EQ(200, push_response->headers->response_code()); 6179 6180 rv = ReadTransaction(push_trans.get(), &response_data); 6181 EXPECT_EQ(OK, rv); 6182 EXPECT_EQ("pushed", response_data); 6183 6184 LoadTimingInfo push_load_timing_info; 6185 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info)); 6186 TestLoadTimingReusedWithPac(push_load_timing_info); 6187 // The transactions should share a socket ID, despite being for different 6188 // origins. 6189 EXPECT_EQ(load_timing_info.socket_log_id, 6190 push_load_timing_info.socket_log_id); 6191 6192 trans.reset(); 6193 push_trans.reset(); 6194 session->CloseAllConnections(); 6195 } 6196 6197 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content. 6198 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) { 6199 HttpRequestInfo request; 6200 6201 request.method = "GET"; 6202 request.url = GURL("http://www.google.com/"); 6203 6204 // Configure against https proxy server "myproxy:70". 6205 session_deps_.proxy_service.reset( 6206 ProxyService::CreateFixed("https://myproxy:70")); 6207 CapturingBoundNetLog log; 6208 session_deps_.net_log = log.bound().net_log(); 6209 6210 // Enable cross-origin push. 6211 session_deps_.trusted_spdy_proxy = "myproxy:70"; 6212 6213 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6214 6215 scoped_ptr<SpdyFrame> stream1_syn( 6216 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 6217 6218 scoped_ptr<SpdyFrame> push_rst( 6219 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 6220 6221 MockWrite spdy_writes[] = { 6222 CreateMockWrite(*stream1_syn, 1, ASYNC), 6223 CreateMockWrite(*push_rst, 4), 6224 }; 6225 6226 scoped_ptr<SpdyFrame> 6227 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 6228 6229 scoped_ptr<SpdyFrame> 6230 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6231 6232 scoped_ptr<SpdyFrame> 6233 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 6234 0, 6235 2, 6236 1, 6237 "https://www.another-origin.com/foo.dat")); 6238 6239 MockRead spdy_reads[] = { 6240 CreateMockRead(*stream1_reply, 2, ASYNC), 6241 CreateMockRead(*stream2_syn, 3, ASYNC), 6242 CreateMockRead(*stream1_body, 5, ASYNC), 6243 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 6244 }; 6245 6246 OrderedSocketData spdy_data( 6247 spdy_reads, arraysize(spdy_reads), 6248 spdy_writes, arraysize(spdy_writes)); 6249 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6250 // Negotiate SPDY to the proxy 6251 SSLSocketDataProvider proxy(ASYNC, OK); 6252 proxy.SetNextProto(GetParam()); 6253 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6254 6255 scoped_ptr<HttpTransaction> trans( 6256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6257 TestCompletionCallback callback; 6258 int rv = trans->Start(&request, callback.callback(), log.bound()); 6259 EXPECT_EQ(ERR_IO_PENDING, rv); 6260 6261 rv = callback.WaitForResult(); 6262 EXPECT_EQ(OK, rv); 6263 const HttpResponseInfo* response = trans->GetResponseInfo(); 6264 6265 ASSERT_TRUE(response != NULL); 6266 EXPECT_TRUE(response->headers->IsKeepAlive()); 6267 6268 EXPECT_EQ(200, response->headers->response_code()); 6269 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6270 6271 std::string response_data; 6272 rv = ReadTransaction(trans.get(), &response_data); 6273 EXPECT_EQ(OK, rv); 6274 EXPECT_EQ("hello!", response_data); 6275 6276 trans.reset(); 6277 session->CloseAllConnections(); 6278 } 6279 6280 // Test HTTPS connections to a site with a bad certificate, going through an 6281 // HTTPS proxy 6282 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) { 6283 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 6284 "https://proxy:70")); 6285 6286 HttpRequestInfo request; 6287 request.method = "GET"; 6288 request.url = GURL("https://www.google.com/"); 6289 request.load_flags = 0; 6290 6291 // Attempt to fetch the URL from a server with a bad cert 6292 MockWrite bad_cert_writes[] = { 6293 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6294 "Host: www.google.com\r\n" 6295 "Proxy-Connection: keep-alive\r\n\r\n"), 6296 }; 6297 6298 MockRead bad_cert_reads[] = { 6299 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6300 MockRead(SYNCHRONOUS, OK) 6301 }; 6302 6303 // Attempt to fetch the URL with a good cert 6304 MockWrite good_data_writes[] = { 6305 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6306 "Host: www.google.com\r\n" 6307 "Proxy-Connection: keep-alive\r\n\r\n"), 6308 MockWrite("GET / HTTP/1.1\r\n" 6309 "Host: www.google.com\r\n" 6310 "Connection: keep-alive\r\n\r\n"), 6311 }; 6312 6313 MockRead good_cert_reads[] = { 6314 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6315 MockRead("HTTP/1.0 200 OK\r\n"), 6316 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6317 MockRead("Content-Length: 100\r\n\r\n"), 6318 MockRead(SYNCHRONOUS, OK), 6319 }; 6320 6321 StaticSocketDataProvider ssl_bad_certificate( 6322 bad_cert_reads, arraysize(bad_cert_reads), 6323 bad_cert_writes, arraysize(bad_cert_writes)); 6324 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads), 6325 good_data_writes, arraysize(good_data_writes)); 6326 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 6327 SSLSocketDataProvider ssl(ASYNC, OK); 6328 6329 // SSL to the proxy, then CONNECT request, then SSL with bad certificate 6330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6331 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 6332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 6333 6334 // SSL to the proxy, then CONNECT request, then valid SSL certificate 6335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6336 session_deps_.socket_factory->AddSocketDataProvider(&data); 6337 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6338 6339 TestCompletionCallback callback; 6340 6341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6342 scoped_ptr<HttpTransaction> trans( 6343 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6344 6345 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6346 EXPECT_EQ(ERR_IO_PENDING, rv); 6347 6348 rv = callback.WaitForResult(); 6349 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 6350 6351 rv = trans->RestartIgnoringLastError(callback.callback()); 6352 EXPECT_EQ(ERR_IO_PENDING, rv); 6353 6354 rv = callback.WaitForResult(); 6355 EXPECT_EQ(OK, rv); 6356 6357 const HttpResponseInfo* response = trans->GetResponseInfo(); 6358 6359 ASSERT_TRUE(response != NULL); 6360 EXPECT_EQ(100, response->headers->GetContentLength()); 6361 } 6362 6363 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) { 6364 HttpRequestInfo request; 6365 request.method = "GET"; 6366 request.url = GURL("http://www.google.com/"); 6367 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 6368 "Chromium Ultra Awesome X Edition"); 6369 6370 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6371 scoped_ptr<HttpTransaction> trans( 6372 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6373 6374 MockWrite data_writes[] = { 6375 MockWrite("GET / HTTP/1.1\r\n" 6376 "Host: www.google.com\r\n" 6377 "Connection: keep-alive\r\n" 6378 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 6379 }; 6380 6381 // Lastly, the server responds with the actual content. 6382 MockRead data_reads[] = { 6383 MockRead("HTTP/1.0 200 OK\r\n"), 6384 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6385 MockRead("Content-Length: 100\r\n\r\n"), 6386 MockRead(SYNCHRONOUS, OK), 6387 }; 6388 6389 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6390 data_writes, arraysize(data_writes)); 6391 session_deps_.socket_factory->AddSocketDataProvider(&data); 6392 6393 TestCompletionCallback callback; 6394 6395 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6396 EXPECT_EQ(ERR_IO_PENDING, rv); 6397 6398 rv = callback.WaitForResult(); 6399 EXPECT_EQ(OK, rv); 6400 } 6401 6402 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) { 6403 HttpRequestInfo request; 6404 request.method = "GET"; 6405 request.url = GURL("https://www.google.com/"); 6406 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 6407 "Chromium Ultra Awesome X Edition"); 6408 6409 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 6410 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6411 scoped_ptr<HttpTransaction> trans( 6412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6413 6414 MockWrite data_writes[] = { 6415 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6416 "Host: www.google.com\r\n" 6417 "Proxy-Connection: keep-alive\r\n" 6418 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 6419 }; 6420 MockRead data_reads[] = { 6421 // Return an error, so the transaction stops here (this test isn't 6422 // interested in the rest). 6423 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 6424 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 6425 MockRead("Proxy-Connection: close\r\n\r\n"), 6426 }; 6427 6428 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6429 data_writes, arraysize(data_writes)); 6430 session_deps_.socket_factory->AddSocketDataProvider(&data); 6431 6432 TestCompletionCallback callback; 6433 6434 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6435 EXPECT_EQ(ERR_IO_PENDING, rv); 6436 6437 rv = callback.WaitForResult(); 6438 EXPECT_EQ(OK, rv); 6439 } 6440 6441 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) { 6442 HttpRequestInfo request; 6443 request.method = "GET"; 6444 request.url = GURL("http://www.google.com/"); 6445 request.load_flags = 0; 6446 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer, 6447 "http://the.previous.site.com/"); 6448 6449 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6450 scoped_ptr<HttpTransaction> trans( 6451 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6452 6453 MockWrite data_writes[] = { 6454 MockWrite("GET / HTTP/1.1\r\n" 6455 "Host: www.google.com\r\n" 6456 "Connection: keep-alive\r\n" 6457 "Referer: http://the.previous.site.com/\r\n\r\n"), 6458 }; 6459 6460 // Lastly, the server responds with the actual content. 6461 MockRead data_reads[] = { 6462 MockRead("HTTP/1.0 200 OK\r\n"), 6463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6464 MockRead("Content-Length: 100\r\n\r\n"), 6465 MockRead(SYNCHRONOUS, OK), 6466 }; 6467 6468 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6469 data_writes, arraysize(data_writes)); 6470 session_deps_.socket_factory->AddSocketDataProvider(&data); 6471 6472 TestCompletionCallback callback; 6473 6474 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6475 EXPECT_EQ(ERR_IO_PENDING, rv); 6476 6477 rv = callback.WaitForResult(); 6478 EXPECT_EQ(OK, rv); 6479 } 6480 6481 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) { 6482 HttpRequestInfo request; 6483 request.method = "POST"; 6484 request.url = GURL("http://www.google.com/"); 6485 6486 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6487 scoped_ptr<HttpTransaction> trans( 6488 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6489 6490 MockWrite data_writes[] = { 6491 MockWrite("POST / HTTP/1.1\r\n" 6492 "Host: www.google.com\r\n" 6493 "Connection: keep-alive\r\n" 6494 "Content-Length: 0\r\n\r\n"), 6495 }; 6496 6497 // Lastly, the server responds with the actual content. 6498 MockRead data_reads[] = { 6499 MockRead("HTTP/1.0 200 OK\r\n"), 6500 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6501 MockRead("Content-Length: 100\r\n\r\n"), 6502 MockRead(SYNCHRONOUS, OK), 6503 }; 6504 6505 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6506 data_writes, arraysize(data_writes)); 6507 session_deps_.socket_factory->AddSocketDataProvider(&data); 6508 6509 TestCompletionCallback callback; 6510 6511 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6512 EXPECT_EQ(ERR_IO_PENDING, rv); 6513 6514 rv = callback.WaitForResult(); 6515 EXPECT_EQ(OK, rv); 6516 } 6517 6518 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) { 6519 HttpRequestInfo request; 6520 request.method = "PUT"; 6521 request.url = GURL("http://www.google.com/"); 6522 6523 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6524 scoped_ptr<HttpTransaction> trans( 6525 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6526 6527 MockWrite data_writes[] = { 6528 MockWrite("PUT / HTTP/1.1\r\n" 6529 "Host: www.google.com\r\n" 6530 "Connection: keep-alive\r\n" 6531 "Content-Length: 0\r\n\r\n"), 6532 }; 6533 6534 // Lastly, the server responds with the actual content. 6535 MockRead data_reads[] = { 6536 MockRead("HTTP/1.0 200 OK\r\n"), 6537 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6538 MockRead("Content-Length: 100\r\n\r\n"), 6539 MockRead(SYNCHRONOUS, OK), 6540 }; 6541 6542 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6543 data_writes, arraysize(data_writes)); 6544 session_deps_.socket_factory->AddSocketDataProvider(&data); 6545 6546 TestCompletionCallback callback; 6547 6548 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6549 EXPECT_EQ(ERR_IO_PENDING, rv); 6550 6551 rv = callback.WaitForResult(); 6552 EXPECT_EQ(OK, rv); 6553 } 6554 6555 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) { 6556 HttpRequestInfo request; 6557 request.method = "HEAD"; 6558 request.url = GURL("http://www.google.com/"); 6559 6560 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6561 scoped_ptr<HttpTransaction> trans( 6562 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6563 6564 MockWrite data_writes[] = { 6565 MockWrite("HEAD / HTTP/1.1\r\n" 6566 "Host: www.google.com\r\n" 6567 "Connection: keep-alive\r\n" 6568 "Content-Length: 0\r\n\r\n"), 6569 }; 6570 6571 // Lastly, the server responds with the actual content. 6572 MockRead data_reads[] = { 6573 MockRead("HTTP/1.0 200 OK\r\n"), 6574 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6575 MockRead("Content-Length: 100\r\n\r\n"), 6576 MockRead(SYNCHRONOUS, OK), 6577 }; 6578 6579 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6580 data_writes, arraysize(data_writes)); 6581 session_deps_.socket_factory->AddSocketDataProvider(&data); 6582 6583 TestCompletionCallback callback; 6584 6585 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6586 EXPECT_EQ(ERR_IO_PENDING, rv); 6587 6588 rv = callback.WaitForResult(); 6589 EXPECT_EQ(OK, rv); 6590 } 6591 6592 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) { 6593 HttpRequestInfo request; 6594 request.method = "GET"; 6595 request.url = GURL("http://www.google.com/"); 6596 request.load_flags = LOAD_BYPASS_CACHE; 6597 6598 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6599 scoped_ptr<HttpTransaction> trans( 6600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6601 6602 MockWrite data_writes[] = { 6603 MockWrite("GET / HTTP/1.1\r\n" 6604 "Host: www.google.com\r\n" 6605 "Connection: keep-alive\r\n" 6606 "Pragma: no-cache\r\n" 6607 "Cache-Control: no-cache\r\n\r\n"), 6608 }; 6609 6610 // Lastly, the server responds with the actual content. 6611 MockRead data_reads[] = { 6612 MockRead("HTTP/1.0 200 OK\r\n"), 6613 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6614 MockRead("Content-Length: 100\r\n\r\n"), 6615 MockRead(SYNCHRONOUS, OK), 6616 }; 6617 6618 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6619 data_writes, arraysize(data_writes)); 6620 session_deps_.socket_factory->AddSocketDataProvider(&data); 6621 6622 TestCompletionCallback callback; 6623 6624 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6625 EXPECT_EQ(ERR_IO_PENDING, rv); 6626 6627 rv = callback.WaitForResult(); 6628 EXPECT_EQ(OK, rv); 6629 } 6630 6631 TEST_P(HttpNetworkTransactionTest, 6632 BuildRequest_CacheControlValidateCache) { 6633 HttpRequestInfo request; 6634 request.method = "GET"; 6635 request.url = GURL("http://www.google.com/"); 6636 request.load_flags = LOAD_VALIDATE_CACHE; 6637 6638 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6639 scoped_ptr<HttpTransaction> trans( 6640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6641 6642 MockWrite data_writes[] = { 6643 MockWrite("GET / HTTP/1.1\r\n" 6644 "Host: www.google.com\r\n" 6645 "Connection: keep-alive\r\n" 6646 "Cache-Control: max-age=0\r\n\r\n"), 6647 }; 6648 6649 // Lastly, the server responds with the actual content. 6650 MockRead data_reads[] = { 6651 MockRead("HTTP/1.0 200 OK\r\n"), 6652 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6653 MockRead("Content-Length: 100\r\n\r\n"), 6654 MockRead(SYNCHRONOUS, OK), 6655 }; 6656 6657 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6658 data_writes, arraysize(data_writes)); 6659 session_deps_.socket_factory->AddSocketDataProvider(&data); 6660 6661 TestCompletionCallback callback; 6662 6663 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6664 EXPECT_EQ(ERR_IO_PENDING, rv); 6665 6666 rv = callback.WaitForResult(); 6667 EXPECT_EQ(OK, rv); 6668 } 6669 6670 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) { 6671 HttpRequestInfo request; 6672 request.method = "GET"; 6673 request.url = GURL("http://www.google.com/"); 6674 request.extra_headers.SetHeader("FooHeader", "Bar"); 6675 6676 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6677 scoped_ptr<HttpTransaction> trans( 6678 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6679 6680 MockWrite data_writes[] = { 6681 MockWrite("GET / HTTP/1.1\r\n" 6682 "Host: www.google.com\r\n" 6683 "Connection: keep-alive\r\n" 6684 "FooHeader: Bar\r\n\r\n"), 6685 }; 6686 6687 // Lastly, the server responds with the actual content. 6688 MockRead data_reads[] = { 6689 MockRead("HTTP/1.0 200 OK\r\n"), 6690 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6691 MockRead("Content-Length: 100\r\n\r\n"), 6692 MockRead(SYNCHRONOUS, OK), 6693 }; 6694 6695 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6696 data_writes, arraysize(data_writes)); 6697 session_deps_.socket_factory->AddSocketDataProvider(&data); 6698 6699 TestCompletionCallback callback; 6700 6701 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6702 EXPECT_EQ(ERR_IO_PENDING, rv); 6703 6704 rv = callback.WaitForResult(); 6705 EXPECT_EQ(OK, rv); 6706 } 6707 6708 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) { 6709 HttpRequestInfo request; 6710 request.method = "GET"; 6711 request.url = GURL("http://www.google.com/"); 6712 request.extra_headers.SetHeader("referer", "www.foo.com"); 6713 request.extra_headers.SetHeader("hEllo", "Kitty"); 6714 request.extra_headers.SetHeader("FoO", "bar"); 6715 6716 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6717 scoped_ptr<HttpTransaction> trans( 6718 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6719 6720 MockWrite data_writes[] = { 6721 MockWrite("GET / HTTP/1.1\r\n" 6722 "Host: www.google.com\r\n" 6723 "Connection: keep-alive\r\n" 6724 "referer: www.foo.com\r\n" 6725 "hEllo: Kitty\r\n" 6726 "FoO: bar\r\n\r\n"), 6727 }; 6728 6729 // Lastly, the server responds with the actual content. 6730 MockRead data_reads[] = { 6731 MockRead("HTTP/1.0 200 OK\r\n"), 6732 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6733 MockRead("Content-Length: 100\r\n\r\n"), 6734 MockRead(SYNCHRONOUS, OK), 6735 }; 6736 6737 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6738 data_writes, arraysize(data_writes)); 6739 session_deps_.socket_factory->AddSocketDataProvider(&data); 6740 6741 TestCompletionCallback callback; 6742 6743 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6744 EXPECT_EQ(ERR_IO_PENDING, rv); 6745 6746 rv = callback.WaitForResult(); 6747 EXPECT_EQ(OK, rv); 6748 } 6749 6750 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) { 6751 HttpRequestInfo request; 6752 request.method = "GET"; 6753 request.url = GURL("http://www.google.com/"); 6754 request.load_flags = 0; 6755 6756 session_deps_.proxy_service.reset( 6757 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080")); 6758 CapturingNetLog net_log; 6759 session_deps_.net_log = &net_log; 6760 6761 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6762 scoped_ptr<HttpTransaction> trans( 6763 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6764 6765 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; 6766 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 6767 6768 MockWrite data_writes[] = { 6769 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)), 6770 MockWrite("GET / HTTP/1.1\r\n" 6771 "Host: www.google.com\r\n" 6772 "Connection: keep-alive\r\n\r\n") 6773 }; 6774 6775 MockRead data_reads[] = { 6776 MockRead(ASYNC, read_buffer, arraysize(read_buffer)), 6777 MockRead("HTTP/1.0 200 OK\r\n"), 6778 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 6779 MockRead("Payload"), 6780 MockRead(SYNCHRONOUS, OK) 6781 }; 6782 6783 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6784 data_writes, arraysize(data_writes)); 6785 session_deps_.socket_factory->AddSocketDataProvider(&data); 6786 6787 TestCompletionCallback callback; 6788 6789 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 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 ASSERT_TRUE(response != NULL); 6797 6798 LoadTimingInfo load_timing_info; 6799 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6800 TestLoadTimingNotReusedWithPac(load_timing_info, 6801 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 6802 6803 std::string response_text; 6804 rv = ReadTransaction(trans.get(), &response_text); 6805 EXPECT_EQ(OK, rv); 6806 EXPECT_EQ("Payload", response_text); 6807 } 6808 6809 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) { 6810 HttpRequestInfo request; 6811 request.method = "GET"; 6812 request.url = GURL("https://www.google.com/"); 6813 request.load_flags = 0; 6814 6815 session_deps_.proxy_service.reset( 6816 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080")); 6817 CapturingNetLog net_log; 6818 session_deps_.net_log = &net_log; 6819 6820 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6821 scoped_ptr<HttpTransaction> trans( 6822 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6823 6824 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 }; 6825 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 6826 6827 MockWrite data_writes[] = { 6828 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer), 6829 arraysize(write_buffer)), 6830 MockWrite("GET / HTTP/1.1\r\n" 6831 "Host: www.google.com\r\n" 6832 "Connection: keep-alive\r\n\r\n") 6833 }; 6834 6835 MockRead data_reads[] = { 6836 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer), 6837 arraysize(read_buffer)), 6838 MockRead("HTTP/1.0 200 OK\r\n"), 6839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 6840 MockRead("Payload"), 6841 MockRead(SYNCHRONOUS, OK) 6842 }; 6843 6844 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6845 data_writes, arraysize(data_writes)); 6846 session_deps_.socket_factory->AddSocketDataProvider(&data); 6847 6848 SSLSocketDataProvider ssl(ASYNC, OK); 6849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6850 6851 TestCompletionCallback callback; 6852 6853 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6854 EXPECT_EQ(ERR_IO_PENDING, rv); 6855 6856 rv = callback.WaitForResult(); 6857 EXPECT_EQ(OK, rv); 6858 6859 LoadTimingInfo load_timing_info; 6860 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6861 TestLoadTimingNotReusedWithPac(load_timing_info, 6862 CONNECT_TIMING_HAS_SSL_TIMES); 6863 6864 const HttpResponseInfo* response = trans->GetResponseInfo(); 6865 ASSERT_TRUE(response != NULL); 6866 6867 std::string response_text; 6868 rv = ReadTransaction(trans.get(), &response_text); 6869 EXPECT_EQ(OK, rv); 6870 EXPECT_EQ("Payload", response_text); 6871 } 6872 6873 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) { 6874 HttpRequestInfo request; 6875 request.method = "GET"; 6876 request.url = GURL("http://www.google.com/"); 6877 request.load_flags = 0; 6878 6879 session_deps_.proxy_service.reset( 6880 ProxyService::CreateFixed("socks4://myproxy:1080")); 6881 CapturingNetLog net_log; 6882 session_deps_.net_log = &net_log; 6883 6884 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6885 scoped_ptr<HttpTransaction> trans( 6886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6887 6888 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; 6889 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 6890 6891 MockWrite data_writes[] = { 6892 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)), 6893 MockWrite("GET / HTTP/1.1\r\n" 6894 "Host: www.google.com\r\n" 6895 "Connection: keep-alive\r\n\r\n") 6896 }; 6897 6898 MockRead data_reads[] = { 6899 MockRead(ASYNC, read_buffer, arraysize(read_buffer)), 6900 MockRead("HTTP/1.0 200 OK\r\n"), 6901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 6902 MockRead("Payload"), 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 const HttpResponseInfo* response = trans->GetResponseInfo(); 6919 ASSERT_TRUE(response != NULL); 6920 6921 LoadTimingInfo load_timing_info; 6922 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6923 TestLoadTimingNotReused(load_timing_info, 6924 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 6925 6926 std::string response_text; 6927 rv = ReadTransaction(trans.get(), &response_text); 6928 EXPECT_EQ(OK, rv); 6929 EXPECT_EQ("Payload", response_text); 6930 } 6931 6932 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) { 6933 HttpRequestInfo request; 6934 request.method = "GET"; 6935 request.url = GURL("http://www.google.com/"); 6936 request.load_flags = 0; 6937 6938 session_deps_.proxy_service.reset( 6939 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080")); 6940 CapturingNetLog net_log; 6941 session_deps_.net_log = &net_log; 6942 6943 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6944 scoped_ptr<HttpTransaction> trans( 6945 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6946 6947 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 6948 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 6949 const char kSOCKS5OkRequest[] = { 6950 0x05, // Version 6951 0x01, // Command (CONNECT) 6952 0x00, // Reserved. 6953 0x03, // Address type (DOMAINNAME). 6954 0x0E, // Length of domain (14) 6955 // Domain string: 6956 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 6957 0x00, 0x50, // 16-bit port (80) 6958 }; 6959 const char kSOCKS5OkResponse[] = 6960 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 }; 6961 6962 MockWrite data_writes[] = { 6963 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 6964 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)), 6965 MockWrite("GET / HTTP/1.1\r\n" 6966 "Host: www.google.com\r\n" 6967 "Connection: keep-alive\r\n\r\n") 6968 }; 6969 6970 MockRead data_reads[] = { 6971 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 6972 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 6973 MockRead("HTTP/1.0 200 OK\r\n"), 6974 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 6975 MockRead("Payload"), 6976 MockRead(SYNCHRONOUS, OK) 6977 }; 6978 6979 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6980 data_writes, arraysize(data_writes)); 6981 session_deps_.socket_factory->AddSocketDataProvider(&data); 6982 6983 TestCompletionCallback callback; 6984 6985 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6986 EXPECT_EQ(ERR_IO_PENDING, rv); 6987 6988 rv = callback.WaitForResult(); 6989 EXPECT_EQ(OK, rv); 6990 6991 const HttpResponseInfo* response = trans->GetResponseInfo(); 6992 ASSERT_TRUE(response != NULL); 6993 6994 LoadTimingInfo load_timing_info; 6995 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6996 TestLoadTimingNotReusedWithPac(load_timing_info, 6997 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 6998 6999 std::string response_text; 7000 rv = ReadTransaction(trans.get(), &response_text); 7001 EXPECT_EQ(OK, rv); 7002 EXPECT_EQ("Payload", response_text); 7003 } 7004 7005 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) { 7006 HttpRequestInfo request; 7007 request.method = "GET"; 7008 request.url = GURL("https://www.google.com/"); 7009 request.load_flags = 0; 7010 7011 session_deps_.proxy_service.reset( 7012 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080")); 7013 CapturingNetLog net_log; 7014 session_deps_.net_log = &net_log; 7015 7016 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7017 scoped_ptr<HttpTransaction> trans( 7018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7019 7020 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 7021 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 7022 const unsigned char kSOCKS5OkRequest[] = { 7023 0x05, // Version 7024 0x01, // Command (CONNECT) 7025 0x00, // Reserved. 7026 0x03, // Address type (DOMAINNAME). 7027 0x0E, // Length of domain (14) 7028 // Domain string: 7029 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 7030 0x01, 0xBB, // 16-bit port (443) 7031 }; 7032 7033 const char kSOCKS5OkResponse[] = 7034 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 }; 7035 7036 MockWrite data_writes[] = { 7037 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 7038 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest), 7039 arraysize(kSOCKS5OkRequest)), 7040 MockWrite("GET / HTTP/1.1\r\n" 7041 "Host: www.google.com\r\n" 7042 "Connection: keep-alive\r\n\r\n") 7043 }; 7044 7045 MockRead data_reads[] = { 7046 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 7047 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 7048 MockRead("HTTP/1.0 200 OK\r\n"), 7049 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7050 MockRead("Payload"), 7051 MockRead(SYNCHRONOUS, OK) 7052 }; 7053 7054 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7055 data_writes, arraysize(data_writes)); 7056 session_deps_.socket_factory->AddSocketDataProvider(&data); 7057 7058 SSLSocketDataProvider ssl(ASYNC, OK); 7059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 7060 7061 TestCompletionCallback callback; 7062 7063 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7064 EXPECT_EQ(ERR_IO_PENDING, rv); 7065 7066 rv = callback.WaitForResult(); 7067 EXPECT_EQ(OK, rv); 7068 7069 const HttpResponseInfo* response = trans->GetResponseInfo(); 7070 ASSERT_TRUE(response != NULL); 7071 7072 LoadTimingInfo load_timing_info; 7073 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7074 TestLoadTimingNotReusedWithPac(load_timing_info, 7075 CONNECT_TIMING_HAS_SSL_TIMES); 7076 7077 std::string response_text; 7078 rv = ReadTransaction(trans.get(), &response_text); 7079 EXPECT_EQ(OK, rv); 7080 EXPECT_EQ("Payload", response_text); 7081 } 7082 7083 namespace { 7084 7085 // Tests that for connection endpoints the group names are correctly set. 7086 7087 struct GroupNameTest { 7088 std::string proxy_server; 7089 std::string url; 7090 std::string expected_group_name; 7091 bool ssl; 7092 }; 7093 7094 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests( 7095 NextProto next_proto, 7096 SpdySessionDependencies* session_deps_) { 7097 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_)); 7098 7099 base::WeakPtr<HttpServerProperties> http_server_properties = 7100 session->http_server_properties(); 7101 http_server_properties->SetAlternateProtocol( 7102 HostPortPair("host.with.alternate", 80), 443, 7103 AlternateProtocolFromNextProto(next_proto)); 7104 7105 return session; 7106 } 7107 7108 int GroupNameTransactionHelper( 7109 const std::string& url, 7110 const scoped_refptr<HttpNetworkSession>& session) { 7111 HttpRequestInfo request; 7112 request.method = "GET"; 7113 request.url = GURL(url); 7114 request.load_flags = 0; 7115 7116 scoped_ptr<HttpTransaction> trans( 7117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7118 7119 TestCompletionCallback callback; 7120 7121 // We do not complete this request, the dtor will clean the transaction up. 7122 return trans->Start(&request, callback.callback(), BoundNetLog()); 7123 } 7124 7125 } // namespace 7126 7127 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) { 7128 const GroupNameTest tests[] = { 7129 { 7130 "", // unused 7131 "http://www.google.com/direct", 7132 "www.google.com:80", 7133 false, 7134 }, 7135 { 7136 "", // unused 7137 "http://[2001:1418:13:1::25]/direct", 7138 "[2001:1418:13:1::25]:80", 7139 false, 7140 }, 7141 7142 // SSL Tests 7143 { 7144 "", // unused 7145 "https://www.google.com/direct_ssl", 7146 "ssl/www.google.com:443", 7147 true, 7148 }, 7149 { 7150 "", // unused 7151 "https://[2001:1418:13:1::25]/direct", 7152 "ssl/[2001:1418:13:1::25]:443", 7153 true, 7154 }, 7155 { 7156 "", // unused 7157 "http://host.with.alternate/direct", 7158 "ssl/host.with.alternate:443", 7159 true, 7160 }, 7161 }; 7162 7163 HttpStreamFactory::set_use_alternate_protocols(true); 7164 7165 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7166 session_deps_.proxy_service.reset( 7167 ProxyService::CreateFixed(tests[i].proxy_server)); 7168 scoped_refptr<HttpNetworkSession> session( 7169 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7170 7171 HttpNetworkSessionPeer peer(session); 7172 CaptureGroupNameTransportSocketPool* transport_conn_pool = 7173 new CaptureGroupNameTransportSocketPool(NULL, NULL); 7174 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7175 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7176 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7177 new MockClientSocketPoolManager); 7178 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 7179 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); 7180 peer.SetClientSocketPoolManager( 7181 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7182 7183 EXPECT_EQ(ERR_IO_PENDING, 7184 GroupNameTransactionHelper(tests[i].url, session)); 7185 if (tests[i].ssl) 7186 EXPECT_EQ(tests[i].expected_group_name, 7187 ssl_conn_pool->last_group_name_received()); 7188 else 7189 EXPECT_EQ(tests[i].expected_group_name, 7190 transport_conn_pool->last_group_name_received()); 7191 } 7192 7193 } 7194 7195 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) { 7196 const GroupNameTest tests[] = { 7197 { 7198 "http_proxy", 7199 "http://www.google.com/http_proxy_normal", 7200 "www.google.com:80", 7201 false, 7202 }, 7203 7204 // SSL Tests 7205 { 7206 "http_proxy", 7207 "https://www.google.com/http_connect_ssl", 7208 "ssl/www.google.com:443", 7209 true, 7210 }, 7211 7212 { 7213 "http_proxy", 7214 "http://host.with.alternate/direct", 7215 "ssl/host.with.alternate:443", 7216 true, 7217 }, 7218 7219 { 7220 "http_proxy", 7221 "ftp://ftp.google.com/http_proxy_normal", 7222 "ftp/ftp.google.com:21", 7223 false, 7224 }, 7225 }; 7226 7227 HttpStreamFactory::set_use_alternate_protocols(true); 7228 7229 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7230 session_deps_.proxy_service.reset( 7231 ProxyService::CreateFixed(tests[i].proxy_server)); 7232 scoped_refptr<HttpNetworkSession> session( 7233 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7234 7235 HttpNetworkSessionPeer peer(session); 7236 7237 HostPortPair proxy_host("http_proxy", 80); 7238 CaptureGroupNameHttpProxySocketPool* http_proxy_pool = 7239 new CaptureGroupNameHttpProxySocketPool(NULL, NULL); 7240 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7241 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7242 7243 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7244 new MockClientSocketPoolManager); 7245 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); 7246 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 7247 peer.SetClientSocketPoolManager( 7248 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7249 7250 EXPECT_EQ(ERR_IO_PENDING, 7251 GroupNameTransactionHelper(tests[i].url, session)); 7252 if (tests[i].ssl) 7253 EXPECT_EQ(tests[i].expected_group_name, 7254 ssl_conn_pool->last_group_name_received()); 7255 else 7256 EXPECT_EQ(tests[i].expected_group_name, 7257 http_proxy_pool->last_group_name_received()); 7258 } 7259 } 7260 7261 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) { 7262 const GroupNameTest tests[] = { 7263 { 7264 "socks4://socks_proxy:1080", 7265 "http://www.google.com/socks4_direct", 7266 "socks4/www.google.com:80", 7267 false, 7268 }, 7269 { 7270 "socks5://socks_proxy:1080", 7271 "http://www.google.com/socks5_direct", 7272 "socks5/www.google.com:80", 7273 false, 7274 }, 7275 7276 // SSL Tests 7277 { 7278 "socks4://socks_proxy:1080", 7279 "https://www.google.com/socks4_ssl", 7280 "socks4/ssl/www.google.com:443", 7281 true, 7282 }, 7283 { 7284 "socks5://socks_proxy:1080", 7285 "https://www.google.com/socks5_ssl", 7286 "socks5/ssl/www.google.com:443", 7287 true, 7288 }, 7289 7290 { 7291 "socks4://socks_proxy:1080", 7292 "http://host.with.alternate/direct", 7293 "socks4/ssl/host.with.alternate:443", 7294 true, 7295 }, 7296 }; 7297 7298 HttpStreamFactory::set_use_alternate_protocols(true); 7299 7300 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7301 session_deps_.proxy_service.reset( 7302 ProxyService::CreateFixed(tests[i].proxy_server)); 7303 scoped_refptr<HttpNetworkSession> session( 7304 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7305 7306 HttpNetworkSessionPeer peer(session); 7307 7308 HostPortPair proxy_host("socks_proxy", 1080); 7309 CaptureGroupNameSOCKSSocketPool* socks_conn_pool = 7310 new CaptureGroupNameSOCKSSocketPool(NULL, NULL); 7311 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7312 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7313 7314 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7315 new MockClientSocketPoolManager); 7316 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool); 7317 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 7318 peer.SetClientSocketPoolManager( 7319 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7320 7321 scoped_ptr<HttpTransaction> trans( 7322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7323 7324 EXPECT_EQ(ERR_IO_PENDING, 7325 GroupNameTransactionHelper(tests[i].url, session)); 7326 if (tests[i].ssl) 7327 EXPECT_EQ(tests[i].expected_group_name, 7328 ssl_conn_pool->last_group_name_received()); 7329 else 7330 EXPECT_EQ(tests[i].expected_group_name, 7331 socks_conn_pool->last_group_name_received()); 7332 } 7333 } 7334 7335 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) { 7336 HttpRequestInfo request; 7337 request.method = "GET"; 7338 request.url = GURL("http://www.google.com/"); 7339 7340 session_deps_.proxy_service.reset( 7341 ProxyService::CreateFixed("myproxy:70;foobar:80")); 7342 7343 // This simulates failure resolving all hostnames; that means we will fail 7344 // connecting to both proxies (myproxy:70 and foobar:80). 7345 session_deps_.host_resolver->rules()->AddSimulatedFailure("*"); 7346 7347 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7348 scoped_ptr<HttpTransaction> trans( 7349 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7350 7351 TestCompletionCallback callback; 7352 7353 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7354 EXPECT_EQ(ERR_IO_PENDING, rv); 7355 7356 rv = callback.WaitForResult(); 7357 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv); 7358 } 7359 7360 // Base test to make sure that when the load flags for a request specify to 7361 // bypass the cache, the DNS cache is not used. 7362 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper( 7363 int load_flags) { 7364 // Issue a request, asking to bypass the cache(s). 7365 HttpRequestInfo request; 7366 request.method = "GET"; 7367 request.load_flags = load_flags; 7368 request.url = GURL("http://www.google.com/"); 7369 7370 // Select a host resolver that does caching. 7371 session_deps_.host_resolver.reset(new MockCachingHostResolver); 7372 7373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7374 scoped_ptr<HttpTransaction> trans( 7375 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7376 7377 // Warm up the host cache so it has an entry for "www.google.com". 7378 AddressList addrlist; 7379 TestCompletionCallback callback; 7380 int rv = session_deps_.host_resolver->Resolve( 7381 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), 7382 DEFAULT_PRIORITY, 7383 &addrlist, 7384 callback.callback(), 7385 NULL, 7386 BoundNetLog()); 7387 EXPECT_EQ(ERR_IO_PENDING, rv); 7388 rv = callback.WaitForResult(); 7389 EXPECT_EQ(OK, rv); 7390 7391 // Verify that it was added to host cache, by doing a subsequent async lookup 7392 // and confirming it completes synchronously. 7393 rv = session_deps_.host_resolver->Resolve( 7394 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), 7395 DEFAULT_PRIORITY, 7396 &addrlist, 7397 callback.callback(), 7398 NULL, 7399 BoundNetLog()); 7400 ASSERT_EQ(OK, rv); 7401 7402 // Inject a failure the next time that "www.google.com" is resolved. This way 7403 // we can tell if the next lookup hit the cache, or the "network". 7404 // (cache --> success, "network" --> failure). 7405 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com"); 7406 7407 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the 7408 // first read -- this won't be reached as the host resolution will fail first. 7409 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) }; 7410 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7411 session_deps_.socket_factory->AddSocketDataProvider(&data); 7412 7413 // Run the request. 7414 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7415 ASSERT_EQ(ERR_IO_PENDING, rv); 7416 rv = callback.WaitForResult(); 7417 7418 // If we bypassed the cache, we would have gotten a failure while resolving 7419 // "www.google.com". 7420 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); 7421 } 7422 7423 // There are multiple load flags that should trigger the host cache bypass. 7424 // Test each in isolation: 7425 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) { 7426 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE); 7427 } 7428 7429 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) { 7430 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE); 7431 } 7432 7433 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) { 7434 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE); 7435 } 7436 7437 // Make sure we can handle an error when writing the request. 7438 TEST_P(HttpNetworkTransactionTest, RequestWriteError) { 7439 HttpRequestInfo request; 7440 request.method = "GET"; 7441 request.url = GURL("http://www.foo.com/"); 7442 request.load_flags = 0; 7443 7444 MockWrite write_failure[] = { 7445 MockWrite(ASYNC, ERR_CONNECTION_RESET), 7446 }; 7447 StaticSocketDataProvider data(NULL, 0, 7448 write_failure, arraysize(write_failure)); 7449 session_deps_.socket_factory->AddSocketDataProvider(&data); 7450 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7451 7452 TestCompletionCallback callback; 7453 7454 scoped_ptr<HttpTransaction> trans( 7455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7456 7457 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7458 EXPECT_EQ(ERR_IO_PENDING, rv); 7459 7460 rv = callback.WaitForResult(); 7461 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 7462 } 7463 7464 // Check that a connection closed after the start of the headers finishes ok. 7465 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) { 7466 HttpRequestInfo request; 7467 request.method = "GET"; 7468 request.url = GURL("http://www.foo.com/"); 7469 request.load_flags = 0; 7470 7471 MockRead data_reads[] = { 7472 MockRead("HTTP/1."), 7473 MockRead(SYNCHRONOUS, OK), 7474 }; 7475 7476 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7477 session_deps_.socket_factory->AddSocketDataProvider(&data); 7478 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7479 7480 TestCompletionCallback callback; 7481 7482 scoped_ptr<HttpTransaction> trans( 7483 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7484 7485 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7486 EXPECT_EQ(ERR_IO_PENDING, rv); 7487 7488 rv = callback.WaitForResult(); 7489 EXPECT_EQ(OK, rv); 7490 7491 const HttpResponseInfo* response = trans->GetResponseInfo(); 7492 ASSERT_TRUE(response != NULL); 7493 7494 EXPECT_TRUE(response->headers.get() != NULL); 7495 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 7496 7497 std::string response_data; 7498 rv = ReadTransaction(trans.get(), &response_data); 7499 EXPECT_EQ(OK, rv); 7500 EXPECT_EQ("", response_data); 7501 } 7502 7503 // Make sure that a dropped connection while draining the body for auth 7504 // restart does the right thing. 7505 TEST_P(HttpNetworkTransactionTest, DrainResetOK) { 7506 HttpRequestInfo request; 7507 request.method = "GET"; 7508 request.url = GURL("http://www.google.com/"); 7509 request.load_flags = 0; 7510 7511 MockWrite data_writes1[] = { 7512 MockWrite("GET / HTTP/1.1\r\n" 7513 "Host: www.google.com\r\n" 7514 "Connection: keep-alive\r\n\r\n"), 7515 }; 7516 7517 MockRead data_reads1[] = { 7518 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 7519 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 7520 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7521 MockRead("Content-Length: 14\r\n\r\n"), 7522 MockRead("Unauth"), 7523 MockRead(ASYNC, ERR_CONNECTION_RESET), 7524 }; 7525 7526 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 7527 data_writes1, arraysize(data_writes1)); 7528 session_deps_.socket_factory->AddSocketDataProvider(&data1); 7529 7530 // After calling trans->RestartWithAuth(), this is the request we should 7531 // be issuing -- the final header line contains the credentials. 7532 MockWrite data_writes2[] = { 7533 MockWrite("GET / HTTP/1.1\r\n" 7534 "Host: www.google.com\r\n" 7535 "Connection: keep-alive\r\n" 7536 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 7537 }; 7538 7539 // Lastly, the server responds with the actual content. 7540 MockRead data_reads2[] = { 7541 MockRead("HTTP/1.1 200 OK\r\n"), 7542 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7543 MockRead("Content-Length: 100\r\n\r\n"), 7544 MockRead(SYNCHRONOUS, OK), 7545 }; 7546 7547 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 7548 data_writes2, arraysize(data_writes2)); 7549 session_deps_.socket_factory->AddSocketDataProvider(&data2); 7550 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7551 7552 TestCompletionCallback callback1; 7553 7554 scoped_ptr<HttpTransaction> trans( 7555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7556 7557 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 7558 EXPECT_EQ(ERR_IO_PENDING, rv); 7559 7560 rv = callback1.WaitForResult(); 7561 EXPECT_EQ(OK, rv); 7562 7563 const HttpResponseInfo* response = trans->GetResponseInfo(); 7564 ASSERT_TRUE(response != NULL); 7565 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 7566 7567 TestCompletionCallback callback2; 7568 7569 rv = trans->RestartWithAuth( 7570 AuthCredentials(kFoo, kBar), callback2.callback()); 7571 EXPECT_EQ(ERR_IO_PENDING, rv); 7572 7573 rv = callback2.WaitForResult(); 7574 EXPECT_EQ(OK, rv); 7575 7576 response = trans->GetResponseInfo(); 7577 ASSERT_TRUE(response != NULL); 7578 EXPECT_TRUE(response->auth_challenge.get() == NULL); 7579 EXPECT_EQ(100, response->headers->GetContentLength()); 7580 } 7581 7582 // Test HTTPS connections going through a proxy that sends extra data. 7583 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) { 7584 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 7585 7586 HttpRequestInfo request; 7587 request.method = "GET"; 7588 request.url = GURL("https://www.google.com/"); 7589 request.load_flags = 0; 7590 7591 MockRead proxy_reads[] = { 7592 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"), 7593 MockRead(SYNCHRONOUS, OK) 7594 }; 7595 7596 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0); 7597 SSLSocketDataProvider ssl(ASYNC, OK); 7598 7599 session_deps_.socket_factory->AddSocketDataProvider(&data); 7600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 7601 7602 TestCompletionCallback callback; 7603 7604 session_deps_.socket_factory->ResetNextMockIndexes(); 7605 7606 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7607 scoped_ptr<HttpTransaction> trans( 7608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7609 7610 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7611 EXPECT_EQ(ERR_IO_PENDING, rv); 7612 7613 rv = callback.WaitForResult(); 7614 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 7615 } 7616 7617 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) { 7618 HttpRequestInfo request; 7619 request.method = "GET"; 7620 request.url = GURL("http://www.google.com/"); 7621 request.load_flags = 0; 7622 7623 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7624 scoped_ptr<HttpTransaction> trans( 7625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7626 7627 MockRead data_reads[] = { 7628 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"), 7629 MockRead(SYNCHRONOUS, OK), 7630 }; 7631 7632 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7633 session_deps_.socket_factory->AddSocketDataProvider(&data); 7634 7635 TestCompletionCallback callback; 7636 7637 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7638 EXPECT_EQ(ERR_IO_PENDING, rv); 7639 7640 EXPECT_EQ(OK, callback.WaitForResult()); 7641 7642 const HttpResponseInfo* response = trans->GetResponseInfo(); 7643 ASSERT_TRUE(response != NULL); 7644 7645 EXPECT_TRUE(response->headers.get() != NULL); 7646 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 7647 7648 std::string response_data; 7649 rv = ReadTransaction(trans.get(), &response_data); 7650 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 7651 } 7652 7653 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) { 7654 base::FilePath temp_file_path; 7655 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path)); 7656 const uint64 kFakeSize = 100000; // file is actually blank 7657 UploadFileElementReader::ScopedOverridingContentLengthForTests 7658 overriding_content_length(kFakeSize); 7659 7660 ScopedVector<UploadElementReader> element_readers; 7661 element_readers.push_back( 7662 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 7663 temp_file_path, 7664 0, 7665 kuint64max, 7666 base::Time())); 7667 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 7668 7669 HttpRequestInfo request; 7670 request.method = "POST"; 7671 request.url = GURL("http://www.google.com/upload"); 7672 request.upload_data_stream = &upload_data_stream; 7673 request.load_flags = 0; 7674 7675 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7676 scoped_ptr<HttpTransaction> trans( 7677 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7678 7679 MockRead data_reads[] = { 7680 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 7681 MockRead("hello world"), 7682 MockRead(SYNCHRONOUS, OK), 7683 }; 7684 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7685 session_deps_.socket_factory->AddSocketDataProvider(&data); 7686 7687 TestCompletionCallback callback; 7688 7689 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7690 EXPECT_EQ(ERR_IO_PENDING, rv); 7691 7692 rv = callback.WaitForResult(); 7693 EXPECT_EQ(OK, rv); 7694 7695 const HttpResponseInfo* response = trans->GetResponseInfo(); 7696 ASSERT_TRUE(response != NULL); 7697 7698 EXPECT_TRUE(response->headers.get() != NULL); 7699 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 7700 7701 std::string response_data; 7702 rv = ReadTransaction(trans.get(), &response_data); 7703 EXPECT_EQ(OK, rv); 7704 EXPECT_EQ("hello world", response_data); 7705 7706 base::DeleteFile(temp_file_path, false); 7707 } 7708 7709 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) { 7710 base::FilePath temp_file; 7711 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file)); 7712 std::string temp_file_content("Unreadable file."); 7713 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(), 7714 temp_file_content.length())); 7715 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file)); 7716 7717 ScopedVector<UploadElementReader> element_readers; 7718 element_readers.push_back( 7719 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 7720 temp_file, 7721 0, 7722 kuint64max, 7723 base::Time())); 7724 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 7725 7726 HttpRequestInfo request; 7727 request.method = "POST"; 7728 request.url = GURL("http://www.google.com/upload"); 7729 request.upload_data_stream = &upload_data_stream; 7730 request.load_flags = 0; 7731 7732 // If we try to upload an unreadable file, the transaction should fail. 7733 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7734 scoped_ptr<HttpTransaction> trans( 7735 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7736 7737 StaticSocketDataProvider data(NULL, 0, NULL, 0); 7738 session_deps_.socket_factory->AddSocketDataProvider(&data); 7739 7740 TestCompletionCallback callback; 7741 7742 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7743 EXPECT_EQ(ERR_IO_PENDING, rv); 7744 7745 rv = callback.WaitForResult(); 7746 EXPECT_EQ(ERR_ACCESS_DENIED, rv); 7747 7748 const HttpResponseInfo* response = trans->GetResponseInfo(); 7749 EXPECT_FALSE(response); 7750 7751 base::DeleteFile(temp_file, false); 7752 } 7753 7754 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) { 7755 class FakeUploadElementReader : public UploadElementReader { 7756 public: 7757 FakeUploadElementReader() {} 7758 virtual ~FakeUploadElementReader() {} 7759 7760 const CompletionCallback& callback() const { return callback_; } 7761 7762 // UploadElementReader overrides: 7763 virtual int Init(const CompletionCallback& callback) OVERRIDE { 7764 callback_ = callback; 7765 return ERR_IO_PENDING; 7766 } 7767 virtual uint64 GetContentLength() const OVERRIDE { return 0; } 7768 virtual uint64 BytesRemaining() const OVERRIDE { return 0; } 7769 virtual int Read(IOBuffer* buf, 7770 int buf_length, 7771 const CompletionCallback& callback) OVERRIDE { 7772 return ERR_FAILED; 7773 } 7774 7775 private: 7776 CompletionCallback callback_; 7777 }; 7778 7779 FakeUploadElementReader* fake_reader = new FakeUploadElementReader; 7780 ScopedVector<UploadElementReader> element_readers; 7781 element_readers.push_back(fake_reader); 7782 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 7783 7784 HttpRequestInfo request; 7785 request.method = "POST"; 7786 request.url = GURL("http://www.google.com/upload"); 7787 request.upload_data_stream = &upload_data_stream; 7788 request.load_flags = 0; 7789 7790 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7791 scoped_ptr<HttpTransaction> trans( 7792 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7793 7794 StaticSocketDataProvider data; 7795 session_deps_.socket_factory->AddSocketDataProvider(&data); 7796 7797 TestCompletionCallback callback; 7798 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7799 EXPECT_EQ(ERR_IO_PENDING, rv); 7800 base::MessageLoop::current()->RunUntilIdle(); 7801 7802 // Transaction is pending on request body initialization. 7803 ASSERT_FALSE(fake_reader->callback().is_null()); 7804 7805 // Return Init()'s result after the transaction gets destroyed. 7806 trans.reset(); 7807 fake_reader->callback().Run(OK); // Should not crash. 7808 } 7809 7810 // Tests that changes to Auth realms are treated like auth rejections. 7811 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) { 7812 7813 HttpRequestInfo request; 7814 request.method = "GET"; 7815 request.url = GURL("http://www.google.com/"); 7816 request.load_flags = 0; 7817 7818 // First transaction will request a resource and receive a Basic challenge 7819 // with realm="first_realm". 7820 MockWrite data_writes1[] = { 7821 MockWrite("GET / HTTP/1.1\r\n" 7822 "Host: www.google.com\r\n" 7823 "Connection: keep-alive\r\n" 7824 "\r\n"), 7825 }; 7826 MockRead data_reads1[] = { 7827 MockRead("HTTP/1.1 401 Unauthorized\r\n" 7828 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 7829 "\r\n"), 7830 }; 7831 7832 // After calling trans->RestartWithAuth(), provide an Authentication header 7833 // for first_realm. The server will reject and provide a challenge with 7834 // second_realm. 7835 MockWrite data_writes2[] = { 7836 MockWrite("GET / HTTP/1.1\r\n" 7837 "Host: www.google.com\r\n" 7838 "Connection: keep-alive\r\n" 7839 "Authorization: Basic Zmlyc3Q6YmF6\r\n" 7840 "\r\n"), 7841 }; 7842 MockRead data_reads2[] = { 7843 MockRead("HTTP/1.1 401 Unauthorized\r\n" 7844 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n" 7845 "\r\n"), 7846 }; 7847 7848 // This again fails, and goes back to first_realm. Make sure that the 7849 // entry is removed from cache. 7850 MockWrite data_writes3[] = { 7851 MockWrite("GET / HTTP/1.1\r\n" 7852 "Host: www.google.com\r\n" 7853 "Connection: keep-alive\r\n" 7854 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n" 7855 "\r\n"), 7856 }; 7857 MockRead data_reads3[] = { 7858 MockRead("HTTP/1.1 401 Unauthorized\r\n" 7859 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 7860 "\r\n"), 7861 }; 7862 7863 // Try one last time (with the correct password) and get the resource. 7864 MockWrite data_writes4[] = { 7865 MockWrite("GET / HTTP/1.1\r\n" 7866 "Host: www.google.com\r\n" 7867 "Connection: keep-alive\r\n" 7868 "Authorization: Basic Zmlyc3Q6YmFy\r\n" 7869 "\r\n"), 7870 }; 7871 MockRead data_reads4[] = { 7872 MockRead("HTTP/1.1 200 OK\r\n" 7873 "Content-Type: text/html; charset=iso-8859-1\r\n" 7874 "Content-Length: 5\r\n" 7875 "\r\n" 7876 "hello"), 7877 }; 7878 7879 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 7880 data_writes1, arraysize(data_writes1)); 7881 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 7882 data_writes2, arraysize(data_writes2)); 7883 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 7884 data_writes3, arraysize(data_writes3)); 7885 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4), 7886 data_writes4, arraysize(data_writes4)); 7887 session_deps_.socket_factory->AddSocketDataProvider(&data1); 7888 session_deps_.socket_factory->AddSocketDataProvider(&data2); 7889 session_deps_.socket_factory->AddSocketDataProvider(&data3); 7890 session_deps_.socket_factory->AddSocketDataProvider(&data4); 7891 7892 TestCompletionCallback callback1; 7893 7894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7895 scoped_ptr<HttpTransaction> trans( 7896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7897 7898 // Issue the first request with Authorize headers. There should be a 7899 // password prompt for first_realm waiting to be filled in after the 7900 // transaction completes. 7901 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 7902 EXPECT_EQ(ERR_IO_PENDING, rv); 7903 rv = callback1.WaitForResult(); 7904 EXPECT_EQ(OK, rv); 7905 const HttpResponseInfo* response = trans->GetResponseInfo(); 7906 ASSERT_TRUE(response != NULL); 7907 const AuthChallengeInfo* challenge = response->auth_challenge.get(); 7908 ASSERT_FALSE(challenge == NULL); 7909 EXPECT_FALSE(challenge->is_proxy); 7910 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 7911 EXPECT_EQ("first_realm", challenge->realm); 7912 EXPECT_EQ("basic", challenge->scheme); 7913 7914 // Issue the second request with an incorrect password. There should be a 7915 // password prompt for second_realm waiting to be filled in after the 7916 // transaction completes. 7917 TestCompletionCallback callback2; 7918 rv = trans->RestartWithAuth( 7919 AuthCredentials(kFirst, kBaz), callback2.callback()); 7920 EXPECT_EQ(ERR_IO_PENDING, rv); 7921 rv = callback2.WaitForResult(); 7922 EXPECT_EQ(OK, rv); 7923 response = trans->GetResponseInfo(); 7924 ASSERT_TRUE(response != NULL); 7925 challenge = response->auth_challenge.get(); 7926 ASSERT_FALSE(challenge == NULL); 7927 EXPECT_FALSE(challenge->is_proxy); 7928 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 7929 EXPECT_EQ("second_realm", challenge->realm); 7930 EXPECT_EQ("basic", challenge->scheme); 7931 7932 // Issue the third request with another incorrect password. There should be 7933 // a password prompt for first_realm waiting to be filled in. If the password 7934 // prompt is not present, it indicates that the HttpAuthCacheEntry for 7935 // first_realm was not correctly removed. 7936 TestCompletionCallback callback3; 7937 rv = trans->RestartWithAuth( 7938 AuthCredentials(kSecond, kFou), callback3.callback()); 7939 EXPECT_EQ(ERR_IO_PENDING, rv); 7940 rv = callback3.WaitForResult(); 7941 EXPECT_EQ(OK, rv); 7942 response = trans->GetResponseInfo(); 7943 ASSERT_TRUE(response != NULL); 7944 challenge = response->auth_challenge.get(); 7945 ASSERT_FALSE(challenge == NULL); 7946 EXPECT_FALSE(challenge->is_proxy); 7947 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 7948 EXPECT_EQ("first_realm", challenge->realm); 7949 EXPECT_EQ("basic", challenge->scheme); 7950 7951 // Issue the fourth request with the correct password and username. 7952 TestCompletionCallback callback4; 7953 rv = trans->RestartWithAuth( 7954 AuthCredentials(kFirst, kBar), callback4.callback()); 7955 EXPECT_EQ(ERR_IO_PENDING, rv); 7956 rv = callback4.WaitForResult(); 7957 EXPECT_EQ(OK, rv); 7958 response = trans->GetResponseInfo(); 7959 ASSERT_TRUE(response != NULL); 7960 EXPECT_TRUE(response->auth_challenge.get() == NULL); 7961 } 7962 7963 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { 7964 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 7965 HttpStreamFactory::set_use_alternate_protocols(true); 7966 7967 std::string alternate_protocol_http_header = 7968 GetAlternateProtocolHttpHeader(); 7969 7970 MockRead data_reads[] = { 7971 MockRead("HTTP/1.1 200 OK\r\n"), 7972 MockRead(alternate_protocol_http_header.c_str()), 7973 MockRead("hello world"), 7974 MockRead(SYNCHRONOUS, OK), 7975 }; 7976 7977 HttpRequestInfo request; 7978 request.method = "GET"; 7979 request.url = GURL("http://www.google.com/"); 7980 request.load_flags = 0; 7981 7982 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7983 7984 session_deps_.socket_factory->AddSocketDataProvider(&data); 7985 7986 TestCompletionCallback callback; 7987 7988 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7989 scoped_ptr<HttpTransaction> trans( 7990 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7991 7992 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7993 EXPECT_EQ(ERR_IO_PENDING, rv); 7994 7995 HostPortPair http_host_port_pair("www.google.com", 80); 7996 const HttpServerProperties& http_server_properties = 7997 *session->http_server_properties(); 7998 EXPECT_FALSE( 7999 http_server_properties.HasAlternateProtocol(http_host_port_pair)); 8000 8001 EXPECT_EQ(OK, callback.WaitForResult()); 8002 8003 const HttpResponseInfo* response = trans->GetResponseInfo(); 8004 ASSERT_TRUE(response != NULL); 8005 ASSERT_TRUE(response->headers.get() != NULL); 8006 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8007 EXPECT_FALSE(response->was_fetched_via_spdy); 8008 EXPECT_FALSE(response->was_npn_negotiated); 8009 8010 std::string response_data; 8011 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8012 EXPECT_EQ("hello world", response_data); 8013 8014 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair)); 8015 const PortAlternateProtocolPair alternate = 8016 http_server_properties.GetAlternateProtocol(http_host_port_pair); 8017 PortAlternateProtocolPair expected_alternate; 8018 expected_alternate.port = 443; 8019 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam()); 8020 EXPECT_TRUE(expected_alternate.Equals(alternate)); 8021 } 8022 8023 TEST_P(HttpNetworkTransactionTest, 8024 MarkBrokenAlternateProtocolAndFallback) { 8025 HttpStreamFactory::set_use_alternate_protocols(true); 8026 8027 HttpRequestInfo request; 8028 request.method = "GET"; 8029 request.url = GURL("http://www.google.com/"); 8030 request.load_flags = 0; 8031 8032 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8033 StaticSocketDataProvider first_data; 8034 first_data.set_connect_data(mock_connect); 8035 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8036 8037 MockRead data_reads[] = { 8038 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8039 MockRead("hello world"), 8040 MockRead(ASYNC, OK), 8041 }; 8042 StaticSocketDataProvider second_data( 8043 data_reads, arraysize(data_reads), NULL, 0); 8044 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8045 8046 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8047 8048 base::WeakPtr<HttpServerProperties> http_server_properties = 8049 session->http_server_properties(); 8050 // Port must be < 1024, or the header will be ignored (since initial port was 8051 // port 80 (another restricted port). 8052 http_server_properties->SetAlternateProtocol( 8053 HostPortPair::FromURL(request.url), 8054 666 /* port is ignored by MockConnect anyway */, 8055 AlternateProtocolFromNextProto(GetParam())); 8056 8057 scoped_ptr<HttpTransaction> trans( 8058 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8059 TestCompletionCallback callback; 8060 8061 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8062 EXPECT_EQ(ERR_IO_PENDING, rv); 8063 EXPECT_EQ(OK, callback.WaitForResult()); 8064 8065 const HttpResponseInfo* response = trans->GetResponseInfo(); 8066 ASSERT_TRUE(response != NULL); 8067 ASSERT_TRUE(response->headers.get() != NULL); 8068 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8069 8070 std::string response_data; 8071 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8072 EXPECT_EQ("hello world", response_data); 8073 8074 ASSERT_TRUE(http_server_properties->HasAlternateProtocol( 8075 HostPortPair::FromURL(request.url))); 8076 const PortAlternateProtocolPair alternate = 8077 http_server_properties->GetAlternateProtocol( 8078 HostPortPair::FromURL(request.url)); 8079 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); 8080 } 8081 8082 TEST_P(HttpNetworkTransactionTest, 8083 AlternateProtocolPortRestrictedBlocked) { 8084 // Ensure that we're not allowed to redirect traffic via an alternate 8085 // protocol to an unrestricted (port >= 1024) when the original traffic was 8086 // on a restricted port (port < 1024). Ensure that we can redirect in all 8087 // other cases. 8088 HttpStreamFactory::set_use_alternate_protocols(true); 8089 8090 HttpRequestInfo restricted_port_request; 8091 restricted_port_request.method = "GET"; 8092 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8093 restricted_port_request.load_flags = 0; 8094 8095 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8096 StaticSocketDataProvider first_data; 8097 first_data.set_connect_data(mock_connect); 8098 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8099 8100 MockRead data_reads[] = { 8101 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8102 MockRead("hello world"), 8103 MockRead(ASYNC, OK), 8104 }; 8105 StaticSocketDataProvider second_data( 8106 data_reads, arraysize(data_reads), NULL, 0); 8107 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8108 8109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8110 8111 base::WeakPtr<HttpServerProperties> http_server_properties = 8112 session->http_server_properties(); 8113 const int kUnrestrictedAlternatePort = 1024; 8114 http_server_properties->SetAlternateProtocol( 8115 HostPortPair::FromURL(restricted_port_request.url), 8116 kUnrestrictedAlternatePort, 8117 AlternateProtocolFromNextProto(GetParam())); 8118 8119 scoped_ptr<HttpTransaction> trans( 8120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8121 TestCompletionCallback callback; 8122 8123 int rv = trans->Start( 8124 &restricted_port_request, 8125 callback.callback(), BoundNetLog()); 8126 EXPECT_EQ(ERR_IO_PENDING, rv); 8127 // Invalid change to unrestricted port should fail. 8128 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult()); 8129 } 8130 8131 TEST_P(HttpNetworkTransactionTest, 8132 AlternateProtocolPortRestrictedPermitted) { 8133 // Ensure that we're allowed to redirect traffic via an alternate 8134 // protocol to an unrestricted (port >= 1024) when the original traffic was 8135 // on a restricted port (port < 1024) if we set 8136 // enable_user_alternate_protocol_ports. 8137 8138 HttpStreamFactory::set_use_alternate_protocols(true); 8139 session_deps_.enable_user_alternate_protocol_ports = true; 8140 8141 HttpRequestInfo restricted_port_request; 8142 restricted_port_request.method = "GET"; 8143 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8144 restricted_port_request.load_flags = 0; 8145 8146 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8147 StaticSocketDataProvider first_data; 8148 first_data.set_connect_data(mock_connect); 8149 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8150 8151 MockRead data_reads[] = { 8152 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8153 MockRead("hello world"), 8154 MockRead(ASYNC, OK), 8155 }; 8156 StaticSocketDataProvider second_data( 8157 data_reads, arraysize(data_reads), NULL, 0); 8158 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8159 8160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8161 8162 base::WeakPtr<HttpServerProperties> http_server_properties = 8163 session->http_server_properties(); 8164 const int kUnrestrictedAlternatePort = 1024; 8165 http_server_properties->SetAlternateProtocol( 8166 HostPortPair::FromURL(restricted_port_request.url), 8167 kUnrestrictedAlternatePort, 8168 AlternateProtocolFromNextProto(GetParam())); 8169 8170 scoped_ptr<HttpTransaction> trans( 8171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8172 TestCompletionCallback callback; 8173 8174 EXPECT_EQ(ERR_IO_PENDING, trans->Start( 8175 &restricted_port_request, 8176 callback.callback(), BoundNetLog())); 8177 // Change to unrestricted port should succeed. 8178 EXPECT_EQ(OK, callback.WaitForResult()); 8179 } 8180 8181 TEST_P(HttpNetworkTransactionTest, 8182 AlternateProtocolPortRestrictedAllowed) { 8183 // Ensure that we're not allowed to redirect traffic via an alternate 8184 // protocol to an unrestricted (port >= 1024) when the original traffic was 8185 // on a restricted port (port < 1024). Ensure that we can redirect in all 8186 // other cases. 8187 HttpStreamFactory::set_use_alternate_protocols(true); 8188 8189 HttpRequestInfo restricted_port_request; 8190 restricted_port_request.method = "GET"; 8191 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8192 restricted_port_request.load_flags = 0; 8193 8194 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8195 StaticSocketDataProvider first_data; 8196 first_data.set_connect_data(mock_connect); 8197 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8198 8199 MockRead data_reads[] = { 8200 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8201 MockRead("hello world"), 8202 MockRead(ASYNC, OK), 8203 }; 8204 StaticSocketDataProvider second_data( 8205 data_reads, arraysize(data_reads), NULL, 0); 8206 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8207 8208 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8209 8210 base::WeakPtr<HttpServerProperties> http_server_properties = 8211 session->http_server_properties(); 8212 const int kRestrictedAlternatePort = 80; 8213 http_server_properties->SetAlternateProtocol( 8214 HostPortPair::FromURL(restricted_port_request.url), 8215 kRestrictedAlternatePort, 8216 AlternateProtocolFromNextProto(GetParam())); 8217 8218 scoped_ptr<HttpTransaction> trans( 8219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8220 TestCompletionCallback callback; 8221 8222 int rv = trans->Start( 8223 &restricted_port_request, 8224 callback.callback(), BoundNetLog()); 8225 EXPECT_EQ(ERR_IO_PENDING, rv); 8226 // Valid change to restricted port should pass. 8227 EXPECT_EQ(OK, callback.WaitForResult()); 8228 } 8229 8230 TEST_P(HttpNetworkTransactionTest, 8231 AlternateProtocolPortUnrestrictedAllowed1) { 8232 // Ensure that we're not allowed to redirect traffic via an alternate 8233 // protocol to an unrestricted (port >= 1024) when the original traffic was 8234 // on a restricted port (port < 1024). Ensure that we can redirect in all 8235 // other cases. 8236 HttpStreamFactory::set_use_alternate_protocols(true); 8237 8238 HttpRequestInfo unrestricted_port_request; 8239 unrestricted_port_request.method = "GET"; 8240 unrestricted_port_request.url = GURL("http://www.google.com:1024/"); 8241 unrestricted_port_request.load_flags = 0; 8242 8243 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8244 StaticSocketDataProvider first_data; 8245 first_data.set_connect_data(mock_connect); 8246 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8247 8248 MockRead data_reads[] = { 8249 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8250 MockRead("hello world"), 8251 MockRead(ASYNC, OK), 8252 }; 8253 StaticSocketDataProvider second_data( 8254 data_reads, arraysize(data_reads), NULL, 0); 8255 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8256 8257 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8258 8259 base::WeakPtr<HttpServerProperties> http_server_properties = 8260 session->http_server_properties(); 8261 const int kRestrictedAlternatePort = 80; 8262 http_server_properties->SetAlternateProtocol( 8263 HostPortPair::FromURL(unrestricted_port_request.url), 8264 kRestrictedAlternatePort, 8265 AlternateProtocolFromNextProto(GetParam())); 8266 8267 scoped_ptr<HttpTransaction> trans( 8268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8269 TestCompletionCallback callback; 8270 8271 int rv = trans->Start( 8272 &unrestricted_port_request, callback.callback(), BoundNetLog()); 8273 EXPECT_EQ(ERR_IO_PENDING, rv); 8274 // Valid change to restricted port should pass. 8275 EXPECT_EQ(OK, callback.WaitForResult()); 8276 } 8277 8278 TEST_P(HttpNetworkTransactionTest, 8279 AlternateProtocolPortUnrestrictedAllowed2) { 8280 // Ensure that we're not allowed to redirect traffic via an alternate 8281 // protocol to an unrestricted (port >= 1024) when the original traffic was 8282 // on a restricted port (port < 1024). Ensure that we can redirect in all 8283 // other cases. 8284 HttpStreamFactory::set_use_alternate_protocols(true); 8285 8286 HttpRequestInfo unrestricted_port_request; 8287 unrestricted_port_request.method = "GET"; 8288 unrestricted_port_request.url = GURL("http://www.google.com:1024/"); 8289 unrestricted_port_request.load_flags = 0; 8290 8291 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8292 StaticSocketDataProvider first_data; 8293 first_data.set_connect_data(mock_connect); 8294 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8295 8296 MockRead data_reads[] = { 8297 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8298 MockRead("hello world"), 8299 MockRead(ASYNC, OK), 8300 }; 8301 StaticSocketDataProvider second_data( 8302 data_reads, arraysize(data_reads), NULL, 0); 8303 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8304 8305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8306 8307 base::WeakPtr<HttpServerProperties> http_server_properties = 8308 session->http_server_properties(); 8309 const int kUnrestrictedAlternatePort = 1024; 8310 http_server_properties->SetAlternateProtocol( 8311 HostPortPair::FromURL(unrestricted_port_request.url), 8312 kUnrestrictedAlternatePort, 8313 AlternateProtocolFromNextProto(GetParam())); 8314 8315 scoped_ptr<HttpTransaction> trans( 8316 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8317 TestCompletionCallback callback; 8318 8319 int rv = trans->Start( 8320 &unrestricted_port_request, callback.callback(), BoundNetLog()); 8321 EXPECT_EQ(ERR_IO_PENDING, rv); 8322 // Valid change to an unrestricted port should pass. 8323 EXPECT_EQ(OK, callback.WaitForResult()); 8324 } 8325 8326 TEST_P(HttpNetworkTransactionTest, 8327 AlternateProtocolUnsafeBlocked) { 8328 // Ensure that we're not allowed to redirect traffic via an alternate 8329 // protocol to an unsafe port, and that we resume the second 8330 // HttpStreamFactoryImpl::Job once the alternate protocol request fails. 8331 HttpStreamFactory::set_use_alternate_protocols(true); 8332 8333 HttpRequestInfo request; 8334 request.method = "GET"; 8335 request.url = GURL("http://www.google.com/"); 8336 request.load_flags = 0; 8337 8338 // The alternate protocol request will error out before we attempt to connect, 8339 // so only the standard HTTP request will try to connect. 8340 MockRead data_reads[] = { 8341 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8342 MockRead("hello world"), 8343 MockRead(ASYNC, OK), 8344 }; 8345 StaticSocketDataProvider data( 8346 data_reads, arraysize(data_reads), NULL, 0); 8347 session_deps_.socket_factory->AddSocketDataProvider(&data); 8348 8349 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8350 8351 base::WeakPtr<HttpServerProperties> http_server_properties = 8352 session->http_server_properties(); 8353 const int kUnsafePort = 7; 8354 http_server_properties->SetAlternateProtocol( 8355 HostPortPair::FromURL(request.url), 8356 kUnsafePort, 8357 AlternateProtocolFromNextProto(GetParam())); 8358 8359 scoped_ptr<HttpTransaction> trans( 8360 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8361 TestCompletionCallback callback; 8362 8363 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8364 EXPECT_EQ(ERR_IO_PENDING, rv); 8365 // The HTTP request should succeed. 8366 EXPECT_EQ(OK, callback.WaitForResult()); 8367 8368 // Disable alternate protocol before the asserts. 8369 HttpStreamFactory::set_use_alternate_protocols(false); 8370 8371 const HttpResponseInfo* response = trans->GetResponseInfo(); 8372 ASSERT_TRUE(response != NULL); 8373 ASSERT_TRUE(response->headers.get() != NULL); 8374 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8375 8376 std::string response_data; 8377 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8378 EXPECT_EQ("hello world", response_data); 8379 } 8380 8381 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) { 8382 HttpStreamFactory::set_use_alternate_protocols(true); 8383 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 8384 8385 HttpRequestInfo request; 8386 request.method = "GET"; 8387 request.url = GURL("http://www.google.com/"); 8388 request.load_flags = 0; 8389 8390 std::string alternate_protocol_http_header = 8391 GetAlternateProtocolHttpHeader(); 8392 8393 MockRead data_reads[] = { 8394 MockRead("HTTP/1.1 200 OK\r\n"), 8395 MockRead(alternate_protocol_http_header.c_str()), 8396 MockRead("hello world"), 8397 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8398 MockRead(ASYNC, OK) 8399 }; 8400 8401 StaticSocketDataProvider first_transaction( 8402 data_reads, arraysize(data_reads), NULL, 0); 8403 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8404 8405 SSLSocketDataProvider ssl(ASYNC, OK); 8406 ssl.SetNextProto(GetParam()); 8407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8408 8409 scoped_ptr<SpdyFrame> req( 8410 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8411 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 8412 8413 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8414 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8415 MockRead spdy_reads[] = { 8416 CreateMockRead(*resp), 8417 CreateMockRead(*data), 8418 MockRead(ASYNC, 0, 0), 8419 }; 8420 8421 DelayedSocketData spdy_data( 8422 1, // wait for one write to finish before reading. 8423 spdy_reads, arraysize(spdy_reads), 8424 spdy_writes, arraysize(spdy_writes)); 8425 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8426 8427 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8428 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 8429 NULL, 0, NULL, 0); 8430 hanging_non_alternate_protocol_socket.set_connect_data( 8431 never_finishing_connect); 8432 session_deps_.socket_factory->AddSocketDataProvider( 8433 &hanging_non_alternate_protocol_socket); 8434 8435 TestCompletionCallback callback; 8436 8437 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8438 scoped_ptr<HttpTransaction> trans( 8439 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8440 8441 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8442 EXPECT_EQ(ERR_IO_PENDING, rv); 8443 EXPECT_EQ(OK, callback.WaitForResult()); 8444 8445 const HttpResponseInfo* response = trans->GetResponseInfo(); 8446 ASSERT_TRUE(response != NULL); 8447 ASSERT_TRUE(response->headers.get() != NULL); 8448 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8449 8450 std::string response_data; 8451 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8452 EXPECT_EQ("hello world", response_data); 8453 8454 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8455 8456 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8457 EXPECT_EQ(ERR_IO_PENDING, rv); 8458 EXPECT_EQ(OK, callback.WaitForResult()); 8459 8460 response = trans->GetResponseInfo(); 8461 ASSERT_TRUE(response != NULL); 8462 ASSERT_TRUE(response->headers.get() != NULL); 8463 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8464 EXPECT_TRUE(response->was_fetched_via_spdy); 8465 EXPECT_TRUE(response->was_npn_negotiated); 8466 8467 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8468 EXPECT_EQ("hello!", response_data); 8469 } 8470 8471 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) { 8472 HttpStreamFactory::set_use_alternate_protocols(true); 8473 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 8474 8475 HttpRequestInfo request; 8476 request.method = "GET"; 8477 request.url = GURL("http://www.google.com/"); 8478 request.load_flags = 0; 8479 8480 std::string alternate_protocol_http_header = 8481 GetAlternateProtocolHttpHeader(); 8482 8483 MockRead data_reads[] = { 8484 MockRead("HTTP/1.1 200 OK\r\n"), 8485 MockRead(alternate_protocol_http_header.c_str()), 8486 MockRead("hello world"), 8487 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8488 MockRead(ASYNC, OK), 8489 }; 8490 8491 StaticSocketDataProvider first_transaction( 8492 data_reads, arraysize(data_reads), NULL, 0); 8493 // Socket 1 is the HTTP transaction with the Alternate-Protocol header. 8494 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8495 8496 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8497 StaticSocketDataProvider hanging_socket( 8498 NULL, 0, NULL, 0); 8499 hanging_socket.set_connect_data(never_finishing_connect); 8500 // Socket 2 and 3 are the hanging Alternate-Protocol and 8501 // non-Alternate-Protocol jobs from the 2nd transaction. 8502 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8503 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8504 8505 SSLSocketDataProvider ssl(ASYNC, OK); 8506 ssl.SetNextProto(GetParam()); 8507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8508 8509 scoped_ptr<SpdyFrame> req1( 8510 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8511 scoped_ptr<SpdyFrame> req2( 8512 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 8513 MockWrite spdy_writes[] = { 8514 CreateMockWrite(*req1), 8515 CreateMockWrite(*req2), 8516 }; 8517 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8518 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8519 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 8520 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 8521 MockRead spdy_reads[] = { 8522 CreateMockRead(*resp1), 8523 CreateMockRead(*data1), 8524 CreateMockRead(*resp2), 8525 CreateMockRead(*data2), 8526 MockRead(ASYNC, 0, 0), 8527 }; 8528 8529 DelayedSocketData spdy_data( 8530 2, // wait for writes to finish before reading. 8531 spdy_reads, arraysize(spdy_reads), 8532 spdy_writes, arraysize(spdy_writes)); 8533 // Socket 4 is the successful Alternate-Protocol for transaction 3. 8534 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8535 8536 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3. 8537 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8538 8539 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8540 TestCompletionCallback callback1; 8541 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 8542 8543 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog()); 8544 EXPECT_EQ(ERR_IO_PENDING, rv); 8545 EXPECT_EQ(OK, callback1.WaitForResult()); 8546 8547 const HttpResponseInfo* response = trans1.GetResponseInfo(); 8548 ASSERT_TRUE(response != NULL); 8549 ASSERT_TRUE(response->headers.get() != NULL); 8550 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8551 8552 std::string response_data; 8553 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 8554 EXPECT_EQ("hello world", response_data); 8555 8556 TestCompletionCallback callback2; 8557 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 8558 rv = trans2.Start(&request, callback2.callback(), BoundNetLog()); 8559 EXPECT_EQ(ERR_IO_PENDING, rv); 8560 8561 TestCompletionCallback callback3; 8562 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get()); 8563 rv = trans3.Start(&request, callback3.callback(), BoundNetLog()); 8564 EXPECT_EQ(ERR_IO_PENDING, rv); 8565 8566 EXPECT_EQ(OK, callback2.WaitForResult()); 8567 EXPECT_EQ(OK, callback3.WaitForResult()); 8568 8569 response = trans2.GetResponseInfo(); 8570 ASSERT_TRUE(response != NULL); 8571 ASSERT_TRUE(response->headers.get() != NULL); 8572 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8573 EXPECT_TRUE(response->was_fetched_via_spdy); 8574 EXPECT_TRUE(response->was_npn_negotiated); 8575 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 8576 EXPECT_EQ("hello!", response_data); 8577 8578 response = trans3.GetResponseInfo(); 8579 ASSERT_TRUE(response != NULL); 8580 ASSERT_TRUE(response->headers.get() != NULL); 8581 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8582 EXPECT_TRUE(response->was_fetched_via_spdy); 8583 EXPECT_TRUE(response->was_npn_negotiated); 8584 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data)); 8585 EXPECT_EQ("hello!", response_data); 8586 } 8587 8588 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) { 8589 HttpStreamFactory::set_use_alternate_protocols(true); 8590 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 8591 8592 HttpRequestInfo request; 8593 request.method = "GET"; 8594 request.url = GURL("http://www.google.com/"); 8595 request.load_flags = 0; 8596 8597 std::string alternate_protocol_http_header = 8598 GetAlternateProtocolHttpHeader(); 8599 8600 MockRead data_reads[] = { 8601 MockRead("HTTP/1.1 200 OK\r\n"), 8602 MockRead(alternate_protocol_http_header.c_str()), 8603 MockRead("hello world"), 8604 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8605 MockRead(ASYNC, OK), 8606 }; 8607 8608 StaticSocketDataProvider first_transaction( 8609 data_reads, arraysize(data_reads), NULL, 0); 8610 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8611 8612 SSLSocketDataProvider ssl(ASYNC, OK); 8613 ssl.SetNextProto(GetParam()); 8614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8615 8616 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8617 StaticSocketDataProvider hanging_alternate_protocol_socket( 8618 NULL, 0, NULL, 0); 8619 hanging_alternate_protocol_socket.set_connect_data( 8620 never_finishing_connect); 8621 session_deps_.socket_factory->AddSocketDataProvider( 8622 &hanging_alternate_protocol_socket); 8623 8624 // 2nd request is just a copy of the first one, over HTTP again. 8625 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8626 8627 TestCompletionCallback callback; 8628 8629 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8630 scoped_ptr<HttpTransaction> trans( 8631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8632 8633 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8634 EXPECT_EQ(ERR_IO_PENDING, rv); 8635 EXPECT_EQ(OK, callback.WaitForResult()); 8636 8637 const HttpResponseInfo* response = trans->GetResponseInfo(); 8638 ASSERT_TRUE(response != NULL); 8639 ASSERT_TRUE(response->headers.get() != NULL); 8640 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8641 8642 std::string response_data; 8643 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8644 EXPECT_EQ("hello world", response_data); 8645 8646 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8647 8648 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8649 EXPECT_EQ(ERR_IO_PENDING, rv); 8650 EXPECT_EQ(OK, callback.WaitForResult()); 8651 8652 response = trans->GetResponseInfo(); 8653 ASSERT_TRUE(response != NULL); 8654 ASSERT_TRUE(response->headers.get() != NULL); 8655 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8656 EXPECT_FALSE(response->was_fetched_via_spdy); 8657 EXPECT_FALSE(response->was_npn_negotiated); 8658 8659 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8660 EXPECT_EQ("hello world", response_data); 8661 } 8662 8663 class CapturingProxyResolver : public ProxyResolver { 8664 public: 8665 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {} 8666 virtual ~CapturingProxyResolver() {} 8667 8668 virtual int GetProxyForURL(const GURL& url, 8669 ProxyInfo* results, 8670 const CompletionCallback& callback, 8671 RequestHandle* request, 8672 const BoundNetLog& net_log) OVERRIDE { 8673 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, 8674 HostPortPair("myproxy", 80)); 8675 results->UseProxyServer(proxy_server); 8676 resolved_.push_back(url); 8677 return OK; 8678 } 8679 8680 virtual void CancelRequest(RequestHandle request) OVERRIDE { 8681 NOTREACHED(); 8682 } 8683 8684 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE { 8685 NOTREACHED(); 8686 return LOAD_STATE_IDLE; 8687 } 8688 8689 virtual void CancelSetPacScript() OVERRIDE { 8690 NOTREACHED(); 8691 } 8692 8693 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&, 8694 const CompletionCallback& /*callback*/) OVERRIDE { 8695 return OK; 8696 } 8697 8698 const std::vector<GURL>& resolved() const { return resolved_; } 8699 8700 private: 8701 std::vector<GURL> resolved_; 8702 8703 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver); 8704 }; 8705 8706 TEST_P(HttpNetworkTransactionTest, 8707 UseAlternateProtocolForTunneledNpnSpdy) { 8708 HttpStreamFactory::set_use_alternate_protocols(true); 8709 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 8710 8711 ProxyConfig proxy_config; 8712 proxy_config.set_auto_detect(true); 8713 proxy_config.set_pac_url(GURL("http://fooproxyurl")); 8714 8715 CapturingProxyResolver* capturing_proxy_resolver = 8716 new CapturingProxyResolver(); 8717 session_deps_.proxy_service.reset(new ProxyService( 8718 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver, 8719 NULL)); 8720 CapturingNetLog net_log; 8721 session_deps_.net_log = &net_log; 8722 8723 HttpRequestInfo request; 8724 request.method = "GET"; 8725 request.url = GURL("http://www.google.com/"); 8726 request.load_flags = 0; 8727 8728 std::string alternate_protocol_http_header = 8729 GetAlternateProtocolHttpHeader(); 8730 8731 MockRead data_reads[] = { 8732 MockRead("HTTP/1.1 200 OK\r\n"), 8733 MockRead(alternate_protocol_http_header.c_str()), 8734 MockRead("hello world"), 8735 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8736 MockRead(ASYNC, OK), 8737 }; 8738 8739 StaticSocketDataProvider first_transaction( 8740 data_reads, arraysize(data_reads), NULL, 0); 8741 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8742 8743 SSLSocketDataProvider ssl(ASYNC, OK); 8744 ssl.SetNextProto(GetParam()); 8745 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8746 8747 scoped_ptr<SpdyFrame> req( 8748 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8749 MockWrite spdy_writes[] = { 8750 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 8751 "Host: www.google.com\r\n" 8752 "Proxy-Connection: keep-alive\r\n\r\n"), // 0 8753 CreateMockWrite(*req), // 3 8754 }; 8755 8756 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 8757 8758 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8759 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8760 MockRead spdy_reads[] = { 8761 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1 8762 CreateMockRead(*resp.get(), 4), // 2, 4 8763 CreateMockRead(*data.get(), 4), // 5 8764 MockRead(ASYNC, 0, 0, 4), // 6 8765 }; 8766 8767 OrderedSocketData spdy_data( 8768 spdy_reads, arraysize(spdy_reads), 8769 spdy_writes, arraysize(spdy_writes)); 8770 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8771 8772 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8773 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 8774 NULL, 0, NULL, 0); 8775 hanging_non_alternate_protocol_socket.set_connect_data( 8776 never_finishing_connect); 8777 session_deps_.socket_factory->AddSocketDataProvider( 8778 &hanging_non_alternate_protocol_socket); 8779 8780 TestCompletionCallback callback; 8781 8782 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8783 scoped_ptr<HttpTransaction> trans( 8784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8785 8786 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8787 EXPECT_EQ(ERR_IO_PENDING, rv); 8788 EXPECT_EQ(OK, callback.WaitForResult()); 8789 8790 const HttpResponseInfo* response = trans->GetResponseInfo(); 8791 ASSERT_TRUE(response != NULL); 8792 ASSERT_TRUE(response->headers.get() != NULL); 8793 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8794 EXPECT_FALSE(response->was_fetched_via_spdy); 8795 EXPECT_FALSE(response->was_npn_negotiated); 8796 8797 std::string response_data; 8798 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8799 EXPECT_EQ("hello world", response_data); 8800 8801 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8802 8803 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8804 EXPECT_EQ(ERR_IO_PENDING, rv); 8805 EXPECT_EQ(OK, callback.WaitForResult()); 8806 8807 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 EXPECT_TRUE(response->was_fetched_via_spdy); 8812 EXPECT_TRUE(response->was_npn_negotiated); 8813 8814 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8815 EXPECT_EQ("hello!", response_data); 8816 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size()); 8817 EXPECT_EQ("http://www.google.com/", 8818 capturing_proxy_resolver->resolved()[0].spec()); 8819 EXPECT_EQ("https://www.google.com/", 8820 capturing_proxy_resolver->resolved()[1].spec()); 8821 8822 LoadTimingInfo load_timing_info; 8823 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 8824 TestLoadTimingNotReusedWithPac(load_timing_info, 8825 CONNECT_TIMING_HAS_SSL_TIMES); 8826 } 8827 8828 TEST_P(HttpNetworkTransactionTest, 8829 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) { 8830 HttpStreamFactory::set_use_alternate_protocols(true); 8831 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 8832 8833 HttpRequestInfo request; 8834 request.method = "GET"; 8835 request.url = GURL("http://www.google.com/"); 8836 request.load_flags = 0; 8837 8838 std::string alternate_protocol_http_header = 8839 GetAlternateProtocolHttpHeader(); 8840 8841 MockRead data_reads[] = { 8842 MockRead("HTTP/1.1 200 OK\r\n"), 8843 MockRead(alternate_protocol_http_header.c_str()), 8844 MockRead("hello world"), 8845 MockRead(ASYNC, OK), 8846 }; 8847 8848 StaticSocketDataProvider first_transaction( 8849 data_reads, arraysize(data_reads), NULL, 0); 8850 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8851 8852 SSLSocketDataProvider ssl(ASYNC, OK); 8853 ssl.SetNextProto(GetParam()); 8854 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8855 8856 scoped_ptr<SpdyFrame> req( 8857 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8858 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 8859 8860 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8861 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8862 MockRead spdy_reads[] = { 8863 CreateMockRead(*resp), 8864 CreateMockRead(*data), 8865 MockRead(ASYNC, 0, 0), 8866 }; 8867 8868 DelayedSocketData spdy_data( 8869 1, // wait for one write to finish before reading. 8870 spdy_reads, arraysize(spdy_reads), 8871 spdy_writes, arraysize(spdy_writes)); 8872 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8873 8874 TestCompletionCallback callback; 8875 8876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8877 8878 scoped_ptr<HttpTransaction> trans( 8879 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8880 8881 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8882 EXPECT_EQ(ERR_IO_PENDING, rv); 8883 EXPECT_EQ(OK, callback.WaitForResult()); 8884 8885 const HttpResponseInfo* response = trans->GetResponseInfo(); 8886 ASSERT_TRUE(response != NULL); 8887 ASSERT_TRUE(response->headers.get() != NULL); 8888 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8889 8890 std::string response_data; 8891 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8892 EXPECT_EQ("hello world", response_data); 8893 8894 // Set up an initial SpdySession in the pool to reuse. 8895 HostPortPair host_port_pair("www.google.com", 443); 8896 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 8897 kPrivacyModeDisabled); 8898 base::WeakPtr<SpdySession> spdy_session = 8899 CreateSecureSpdySession(session, key, BoundNetLog()); 8900 8901 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8902 8903 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8904 EXPECT_EQ(ERR_IO_PENDING, rv); 8905 EXPECT_EQ(OK, callback.WaitForResult()); 8906 8907 response = trans->GetResponseInfo(); 8908 ASSERT_TRUE(response != NULL); 8909 ASSERT_TRUE(response->headers.get() != NULL); 8910 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8911 EXPECT_TRUE(response->was_fetched_via_spdy); 8912 EXPECT_TRUE(response->was_npn_negotiated); 8913 8914 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8915 EXPECT_EQ("hello!", response_data); 8916 } 8917 8918 // GenerateAuthToken is a mighty big test. 8919 // It tests all permutation of GenerateAuthToken behavior: 8920 // - Synchronous and Asynchronous completion. 8921 // - OK or error on completion. 8922 // - Direct connection, non-authenticating proxy, and authenticating proxy. 8923 // - HTTP or HTTPS backend (to include proxy tunneling). 8924 // - Non-authenticating and authenticating backend. 8925 // 8926 // In all, there are 44 reasonable permuations (for example, if there are 8927 // problems generating an auth token for an authenticating proxy, we don't 8928 // need to test all permutations of the backend server). 8929 // 8930 // The test proceeds by going over each of the configuration cases, and 8931 // potentially running up to three rounds in each of the tests. The TestConfig 8932 // specifies both the configuration for the test as well as the expectations 8933 // for the results. 8934 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) { 8935 static const char kServer[] = "http://www.example.com"; 8936 static const char kSecureServer[] = "https://www.example.com"; 8937 static const char kProxy[] = "myproxy:70"; 8938 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS; 8939 8940 enum AuthTiming { 8941 AUTH_NONE, 8942 AUTH_SYNC, 8943 AUTH_ASYNC, 8944 }; 8945 8946 const MockWrite kGet( 8947 "GET / HTTP/1.1\r\n" 8948 "Host: www.example.com\r\n" 8949 "Connection: keep-alive\r\n\r\n"); 8950 const MockWrite kGetProxy( 8951 "GET http://www.example.com/ HTTP/1.1\r\n" 8952 "Host: www.example.com\r\n" 8953 "Proxy-Connection: keep-alive\r\n\r\n"); 8954 const MockWrite kGetAuth( 8955 "GET / HTTP/1.1\r\n" 8956 "Host: www.example.com\r\n" 8957 "Connection: keep-alive\r\n" 8958 "Authorization: auth_token\r\n\r\n"); 8959 const MockWrite kGetProxyAuth( 8960 "GET http://www.example.com/ HTTP/1.1\r\n" 8961 "Host: www.example.com\r\n" 8962 "Proxy-Connection: keep-alive\r\n" 8963 "Proxy-Authorization: auth_token\r\n\r\n"); 8964 const MockWrite kGetAuthThroughProxy( 8965 "GET http://www.example.com/ HTTP/1.1\r\n" 8966 "Host: www.example.com\r\n" 8967 "Proxy-Connection: keep-alive\r\n" 8968 "Authorization: auth_token\r\n\r\n"); 8969 const MockWrite kGetAuthWithProxyAuth( 8970 "GET http://www.example.com/ HTTP/1.1\r\n" 8971 "Host: www.example.com\r\n" 8972 "Proxy-Connection: keep-alive\r\n" 8973 "Proxy-Authorization: auth_token\r\n" 8974 "Authorization: auth_token\r\n\r\n"); 8975 const MockWrite kConnect( 8976 "CONNECT www.example.com:443 HTTP/1.1\r\n" 8977 "Host: www.example.com\r\n" 8978 "Proxy-Connection: keep-alive\r\n\r\n"); 8979 const MockWrite kConnectProxyAuth( 8980 "CONNECT www.example.com:443 HTTP/1.1\r\n" 8981 "Host: www.example.com\r\n" 8982 "Proxy-Connection: keep-alive\r\n" 8983 "Proxy-Authorization: auth_token\r\n\r\n"); 8984 8985 const MockRead kSuccess( 8986 "HTTP/1.1 200 OK\r\n" 8987 "Content-Type: text/html; charset=iso-8859-1\r\n" 8988 "Content-Length: 3\r\n\r\n" 8989 "Yes"); 8990 const MockRead kFailure( 8991 "Should not be called."); 8992 const MockRead kServerChallenge( 8993 "HTTP/1.1 401 Unauthorized\r\n" 8994 "WWW-Authenticate: Mock realm=server\r\n" 8995 "Content-Type: text/html; charset=iso-8859-1\r\n" 8996 "Content-Length: 14\r\n\r\n" 8997 "Unauthorized\r\n"); 8998 const MockRead kProxyChallenge( 8999 "HTTP/1.1 407 Unauthorized\r\n" 9000 "Proxy-Authenticate: Mock realm=proxy\r\n" 9001 "Proxy-Connection: close\r\n" 9002 "Content-Type: text/html; charset=iso-8859-1\r\n" 9003 "Content-Length: 14\r\n\r\n" 9004 "Unauthorized\r\n"); 9005 const MockRead kProxyConnected( 9006 "HTTP/1.1 200 Connection Established\r\n\r\n"); 9007 9008 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with 9009 // no constructors, but the C++ compiler on Windows warns about 9010 // unspecified data in compound literals. So, moved to using constructors, 9011 // and TestRound's created with the default constructor should not be used. 9012 struct TestRound { 9013 TestRound() 9014 : expected_rv(ERR_UNEXPECTED), 9015 extra_write(NULL), 9016 extra_read(NULL) { 9017 } 9018 TestRound(const MockWrite& write_arg, const MockRead& read_arg, 9019 int expected_rv_arg) 9020 : write(write_arg), 9021 read(read_arg), 9022 expected_rv(expected_rv_arg), 9023 extra_write(NULL), 9024 extra_read(NULL) { 9025 } 9026 TestRound(const MockWrite& write_arg, const MockRead& read_arg, 9027 int expected_rv_arg, const MockWrite* extra_write_arg, 9028 const MockRead* extra_read_arg) 9029 : write(write_arg), 9030 read(read_arg), 9031 expected_rv(expected_rv_arg), 9032 extra_write(extra_write_arg), 9033 extra_read(extra_read_arg) { 9034 } 9035 MockWrite write; 9036 MockRead read; 9037 int expected_rv; 9038 const MockWrite* extra_write; 9039 const MockRead* extra_read; 9040 }; 9041 9042 static const int kNoSSL = 500; 9043 9044 struct TestConfig { 9045 const char* proxy_url; 9046 AuthTiming proxy_auth_timing; 9047 int proxy_auth_rv; 9048 const char* server_url; 9049 AuthTiming server_auth_timing; 9050 int server_auth_rv; 9051 int num_auth_rounds; 9052 int first_ssl_round; 9053 TestRound rounds[3]; 9054 } test_configs[] = { 9055 // Non-authenticating HTTP server with a direct connection. 9056 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 9057 { TestRound(kGet, kSuccess, OK)}}, 9058 // Authenticating HTTP server with a direct connection. 9059 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 9060 { TestRound(kGet, kServerChallenge, OK), 9061 TestRound(kGetAuth, kSuccess, OK)}}, 9062 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 9063 { TestRound(kGet, kServerChallenge, OK), 9064 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9065 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 9066 { TestRound(kGet, kServerChallenge, OK), 9067 TestRound(kGetAuth, kSuccess, OK)}}, 9068 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 9069 { TestRound(kGet, kServerChallenge, OK), 9070 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9071 // Non-authenticating HTTP server through a non-authenticating proxy. 9072 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 9073 { TestRound(kGetProxy, kSuccess, OK)}}, 9074 // Authenticating HTTP server through a non-authenticating proxy. 9075 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 9076 { TestRound(kGetProxy, kServerChallenge, OK), 9077 TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 9078 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 9079 { TestRound(kGetProxy, kServerChallenge, OK), 9080 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 9081 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 9082 { TestRound(kGetProxy, kServerChallenge, OK), 9083 TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 9084 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 9085 { TestRound(kGetProxy, kServerChallenge, OK), 9086 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 9087 // Non-authenticating HTTP server through an authenticating proxy. 9088 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 9089 { TestRound(kGetProxy, kProxyChallenge, OK), 9090 TestRound(kGetProxyAuth, kSuccess, OK)}}, 9091 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 9092 { TestRound(kGetProxy, kProxyChallenge, OK), 9093 TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 9094 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 9095 { TestRound(kGetProxy, kProxyChallenge, OK), 9096 TestRound(kGetProxyAuth, kSuccess, OK)}}, 9097 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 9098 { TestRound(kGetProxy, kProxyChallenge, OK), 9099 TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 9100 // Authenticating HTTP server through an authenticating proxy. 9101 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 9102 { TestRound(kGetProxy, kProxyChallenge, OK), 9103 TestRound(kGetProxyAuth, kServerChallenge, OK), 9104 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9105 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 9106 { TestRound(kGetProxy, kProxyChallenge, OK), 9107 TestRound(kGetProxyAuth, kServerChallenge, OK), 9108 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9109 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 9110 { TestRound(kGetProxy, kProxyChallenge, OK), 9111 TestRound(kGetProxyAuth, kServerChallenge, OK), 9112 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9113 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 9114 { TestRound(kGetProxy, kProxyChallenge, OK), 9115 TestRound(kGetProxyAuth, kServerChallenge, OK), 9116 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9117 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 9118 { TestRound(kGetProxy, kProxyChallenge, OK), 9119 TestRound(kGetProxyAuth, kServerChallenge, OK), 9120 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9121 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 9122 { TestRound(kGetProxy, kProxyChallenge, OK), 9123 TestRound(kGetProxyAuth, kServerChallenge, OK), 9124 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9125 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 9126 { TestRound(kGetProxy, kProxyChallenge, OK), 9127 TestRound(kGetProxyAuth, kServerChallenge, OK), 9128 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9129 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 9130 { TestRound(kGetProxy, kProxyChallenge, OK), 9131 TestRound(kGetProxyAuth, kServerChallenge, OK), 9132 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9133 // Non-authenticating HTTPS server with a direct connection. 9134 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 9135 { TestRound(kGet, kSuccess, OK)}}, 9136 // Authenticating HTTPS server with a direct connection. 9137 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 9138 { TestRound(kGet, kServerChallenge, OK), 9139 TestRound(kGetAuth, kSuccess, OK)}}, 9140 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 9141 { TestRound(kGet, kServerChallenge, OK), 9142 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9143 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 9144 { TestRound(kGet, kServerChallenge, OK), 9145 TestRound(kGetAuth, kSuccess, OK)}}, 9146 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 9147 { TestRound(kGet, kServerChallenge, OK), 9148 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9149 // Non-authenticating HTTPS server with a non-authenticating proxy. 9150 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 9151 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}}, 9152 // Authenticating HTTPS server through a non-authenticating proxy. 9153 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 9154 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9155 TestRound(kGetAuth, kSuccess, OK)}}, 9156 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 9157 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9158 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9159 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 9160 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9161 TestRound(kGetAuth, kSuccess, OK)}}, 9162 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 9163 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9164 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9165 // Non-Authenticating HTTPS server through an authenticating proxy. 9166 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 9167 { TestRound(kConnect, kProxyChallenge, OK), 9168 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 9169 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 9170 { TestRound(kConnect, kProxyChallenge, OK), 9171 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 9172 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 9173 { TestRound(kConnect, kProxyChallenge, OK), 9174 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 9175 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 9176 { TestRound(kConnect, kProxyChallenge, OK), 9177 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 9178 // Authenticating HTTPS server through an authenticating proxy. 9179 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 9180 { TestRound(kConnect, kProxyChallenge, OK), 9181 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9182 &kGet, &kServerChallenge), 9183 TestRound(kGetAuth, kSuccess, OK)}}, 9184 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 9185 { TestRound(kConnect, kProxyChallenge, OK), 9186 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9187 &kGet, &kServerChallenge), 9188 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9189 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 9190 { TestRound(kConnect, kProxyChallenge, OK), 9191 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9192 &kGet, &kServerChallenge), 9193 TestRound(kGetAuth, kSuccess, OK)}}, 9194 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 9195 { TestRound(kConnect, kProxyChallenge, OK), 9196 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9197 &kGet, &kServerChallenge), 9198 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9199 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 9200 { TestRound(kConnect, kProxyChallenge, OK), 9201 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9202 &kGet, &kServerChallenge), 9203 TestRound(kGetAuth, kSuccess, OK)}}, 9204 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 9205 { TestRound(kConnect, kProxyChallenge, OK), 9206 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9207 &kGet, &kServerChallenge), 9208 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9209 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 9210 { TestRound(kConnect, kProxyChallenge, OK), 9211 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9212 &kGet, &kServerChallenge), 9213 TestRound(kGetAuth, kSuccess, OK)}}, 9214 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 9215 { TestRound(kConnect, kProxyChallenge, OK), 9216 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9217 &kGet, &kServerChallenge), 9218 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9219 }; 9220 9221 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) { 9222 HttpAuthHandlerMock::Factory* auth_factory( 9223 new HttpAuthHandlerMock::Factory()); 9224 session_deps_.http_auth_handler_factory.reset(auth_factory); 9225 const TestConfig& test_config = test_configs[i]; 9226 9227 // Set up authentication handlers as necessary. 9228 if (test_config.proxy_auth_timing != AUTH_NONE) { 9229 for (int n = 0; n < 2; n++) { 9230 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9231 std::string auth_challenge = "Mock realm=proxy"; 9232 GURL origin(test_config.proxy_url); 9233 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(), 9234 auth_challenge.end()); 9235 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY, 9236 origin, BoundNetLog()); 9237 auth_handler->SetGenerateExpectation( 9238 test_config.proxy_auth_timing == AUTH_ASYNC, 9239 test_config.proxy_auth_rv); 9240 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); 9241 } 9242 } 9243 if (test_config.server_auth_timing != AUTH_NONE) { 9244 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9245 std::string auth_challenge = "Mock realm=server"; 9246 GURL origin(test_config.server_url); 9247 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(), 9248 auth_challenge.end()); 9249 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 9250 origin, BoundNetLog()); 9251 auth_handler->SetGenerateExpectation( 9252 test_config.server_auth_timing == AUTH_ASYNC, 9253 test_config.server_auth_rv); 9254 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); 9255 } 9256 if (test_config.proxy_url) { 9257 session_deps_.proxy_service.reset( 9258 ProxyService::CreateFixed(test_config.proxy_url)); 9259 } else { 9260 session_deps_.proxy_service.reset(ProxyService::CreateDirect()); 9261 } 9262 9263 HttpRequestInfo request; 9264 request.method = "GET"; 9265 request.url = GURL(test_config.server_url); 9266 request.load_flags = 0; 9267 9268 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session); 9270 9271 for (int round = 0; round < test_config.num_auth_rounds; ++round) { 9272 const TestRound& read_write_round = test_config.rounds[round]; 9273 9274 // Set up expected reads and writes. 9275 MockRead reads[2]; 9276 reads[0] = read_write_round.read; 9277 size_t length_reads = 1; 9278 if (read_write_round.extra_read) { 9279 reads[1] = *read_write_round.extra_read; 9280 length_reads = 2; 9281 } 9282 9283 MockWrite writes[2]; 9284 writes[0] = read_write_round.write; 9285 size_t length_writes = 1; 9286 if (read_write_round.extra_write) { 9287 writes[1] = *read_write_round.extra_write; 9288 length_writes = 2; 9289 } 9290 StaticSocketDataProvider data_provider( 9291 reads, length_reads, writes, length_writes); 9292 session_deps_.socket_factory->AddSocketDataProvider(&data_provider); 9293 9294 // Add an SSL sequence if necessary. 9295 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK); 9296 if (round >= test_config.first_ssl_round) 9297 session_deps_.socket_factory->AddSSLSocketDataProvider( 9298 &ssl_socket_data_provider); 9299 9300 // Start or restart the transaction. 9301 TestCompletionCallback callback; 9302 int rv; 9303 if (round == 0) { 9304 rv = trans.Start(&request, callback.callback(), BoundNetLog()); 9305 } else { 9306 rv = trans.RestartWithAuth( 9307 AuthCredentials(kFoo, kBar), callback.callback()); 9308 } 9309 if (rv == ERR_IO_PENDING) 9310 rv = callback.WaitForResult(); 9311 9312 // Compare results with expected data. 9313 EXPECT_EQ(read_write_round.expected_rv, rv); 9314 const HttpResponseInfo* response = trans.GetResponseInfo(); 9315 if (read_write_round.expected_rv == OK) { 9316 ASSERT_TRUE(response != NULL); 9317 } else { 9318 EXPECT_TRUE(response == NULL); 9319 EXPECT_EQ(round + 1, test_config.num_auth_rounds); 9320 continue; 9321 } 9322 if (round + 1 < test_config.num_auth_rounds) { 9323 EXPECT_FALSE(response->auth_challenge.get() == NULL); 9324 } else { 9325 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9326 } 9327 } 9328 } 9329 } 9330 9331 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) { 9332 // Do multi-round authentication and make sure it works correctly. 9333 HttpAuthHandlerMock::Factory* auth_factory( 9334 new HttpAuthHandlerMock::Factory()); 9335 session_deps_.http_auth_handler_factory.reset(auth_factory); 9336 session_deps_.proxy_service.reset(ProxyService::CreateDirect()); 9337 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1"); 9338 session_deps_.host_resolver->set_synchronous_mode(true); 9339 9340 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9341 auth_handler->set_connection_based(true); 9342 std::string auth_challenge = "Mock realm=server"; 9343 GURL origin("http://www.example.com"); 9344 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(), 9345 auth_challenge.end()); 9346 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 9347 origin, BoundNetLog()); 9348 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); 9349 9350 int rv = OK; 9351 const HttpResponseInfo* response = NULL; 9352 HttpRequestInfo request; 9353 request.method = "GET"; 9354 request.url = origin; 9355 request.load_flags = 0; 9356 9357 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9358 9359 // Use a TCP Socket Pool with only one connection per group. This is used 9360 // to validate that the TCP socket is not released to the pool between 9361 // each round of multi-round authentication. 9362 HttpNetworkSessionPeer session_peer(session); 9363 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP"); 9364 TransportClientSocketPool* transport_pool = new TransportClientSocketPool( 9365 50, // Max sockets for pool 9366 1, // Max sockets per group 9367 &transport_pool_histograms, 9368 session_deps_.host_resolver.get(), 9369 session_deps_.socket_factory.get(), 9370 session_deps_.net_log); 9371 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 9372 new MockClientSocketPoolManager); 9373 mock_pool_manager->SetTransportSocketPool(transport_pool); 9374 session_peer.SetClientSocketPoolManager( 9375 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 9376 9377 scoped_ptr<HttpTransaction> trans( 9378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9379 TestCompletionCallback callback; 9380 9381 const MockWrite kGet( 9382 "GET / HTTP/1.1\r\n" 9383 "Host: www.example.com\r\n" 9384 "Connection: keep-alive\r\n\r\n"); 9385 const MockWrite kGetAuth( 9386 "GET / HTTP/1.1\r\n" 9387 "Host: www.example.com\r\n" 9388 "Connection: keep-alive\r\n" 9389 "Authorization: auth_token\r\n\r\n"); 9390 9391 const MockRead kServerChallenge( 9392 "HTTP/1.1 401 Unauthorized\r\n" 9393 "WWW-Authenticate: Mock realm=server\r\n" 9394 "Content-Type: text/html; charset=iso-8859-1\r\n" 9395 "Content-Length: 14\r\n\r\n" 9396 "Unauthorized\r\n"); 9397 const MockRead kSuccess( 9398 "HTTP/1.1 200 OK\r\n" 9399 "Content-Type: text/html; charset=iso-8859-1\r\n" 9400 "Content-Length: 3\r\n\r\n" 9401 "Yes"); 9402 9403 MockWrite writes[] = { 9404 // First round 9405 kGet, 9406 // Second round 9407 kGetAuth, 9408 // Third round 9409 kGetAuth, 9410 // Fourth round 9411 kGetAuth, 9412 // Competing request 9413 kGet, 9414 }; 9415 MockRead reads[] = { 9416 // First round 9417 kServerChallenge, 9418 // Second round 9419 kServerChallenge, 9420 // Third round 9421 kServerChallenge, 9422 // Fourth round 9423 kSuccess, 9424 // Competing response 9425 kSuccess, 9426 }; 9427 StaticSocketDataProvider data_provider(reads, arraysize(reads), 9428 writes, arraysize(writes)); 9429 session_deps_.socket_factory->AddSocketDataProvider(&data_provider); 9430 9431 const char* const kSocketGroup = "www.example.com:80"; 9432 9433 // First round of authentication. 9434 auth_handler->SetGenerateExpectation(false, OK); 9435 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9436 if (rv == ERR_IO_PENDING) 9437 rv = callback.WaitForResult(); 9438 EXPECT_EQ(OK, rv); 9439 response = trans->GetResponseInfo(); 9440 ASSERT_TRUE(response != NULL); 9441 EXPECT_FALSE(response->auth_challenge.get() == NULL); 9442 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9443 9444 // In between rounds, another request comes in for the same domain. 9445 // It should not be able to grab the TCP socket that trans has already 9446 // claimed. 9447 scoped_ptr<HttpTransaction> trans_compete( 9448 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9449 TestCompletionCallback callback_compete; 9450 rv = trans_compete->Start( 9451 &request, callback_compete.callback(), BoundNetLog()); 9452 EXPECT_EQ(ERR_IO_PENDING, rv); 9453 // callback_compete.WaitForResult at this point would stall forever, 9454 // since the HttpNetworkTransaction does not release the request back to 9455 // the pool until after authentication completes. 9456 9457 // Second round of authentication. 9458 auth_handler->SetGenerateExpectation(false, OK); 9459 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); 9460 if (rv == ERR_IO_PENDING) 9461 rv = callback.WaitForResult(); 9462 EXPECT_EQ(OK, rv); 9463 response = trans->GetResponseInfo(); 9464 ASSERT_TRUE(response != NULL); 9465 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9466 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9467 9468 // Third round of authentication. 9469 auth_handler->SetGenerateExpectation(false, OK); 9470 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); 9471 if (rv == ERR_IO_PENDING) 9472 rv = callback.WaitForResult(); 9473 EXPECT_EQ(OK, rv); 9474 response = trans->GetResponseInfo(); 9475 ASSERT_TRUE(response != NULL); 9476 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9477 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9478 9479 // Fourth round of authentication, which completes successfully. 9480 auth_handler->SetGenerateExpectation(false, OK); 9481 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); 9482 if (rv == ERR_IO_PENDING) 9483 rv = callback.WaitForResult(); 9484 EXPECT_EQ(OK, rv); 9485 response = trans->GetResponseInfo(); 9486 ASSERT_TRUE(response != NULL); 9487 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9488 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9489 9490 // Read the body since the fourth round was successful. This will also 9491 // release the socket back to the pool. 9492 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50)); 9493 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 9494 if (rv == ERR_IO_PENDING) 9495 rv = callback.WaitForResult(); 9496 EXPECT_EQ(3, rv); 9497 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 9498 EXPECT_EQ(0, rv); 9499 // There are still 0 idle sockets, since the trans_compete transaction 9500 // will be handed it immediately after trans releases it to the group. 9501 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9502 9503 // The competing request can now finish. Wait for the headers and then 9504 // read the body. 9505 rv = callback_compete.WaitForResult(); 9506 EXPECT_EQ(OK, rv); 9507 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); 9508 if (rv == ERR_IO_PENDING) 9509 rv = callback.WaitForResult(); 9510 EXPECT_EQ(3, rv); 9511 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); 9512 EXPECT_EQ(0, rv); 9513 9514 // Finally, the socket is released to the group. 9515 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9516 } 9517 9518 // This tests the case that a request is issued via http instead of spdy after 9519 // npn is negotiated. 9520 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) { 9521 HttpStreamFactory::set_use_alternate_protocols(true); 9522 std::vector<NextProto> next_protos; 9523 next_protos.push_back(kProtoHTTP11); 9524 HttpStreamFactory::SetNextProtos(next_protos); 9525 HttpRequestInfo request; 9526 request.method = "GET"; 9527 request.url = GURL("https://www.google.com/"); 9528 request.load_flags = 0; 9529 9530 MockWrite data_writes[] = { 9531 MockWrite("GET / HTTP/1.1\r\n" 9532 "Host: www.google.com\r\n" 9533 "Connection: keep-alive\r\n\r\n"), 9534 }; 9535 9536 std::string alternate_protocol_http_header = 9537 GetAlternateProtocolHttpHeader(); 9538 9539 MockRead data_reads[] = { 9540 MockRead("HTTP/1.1 200 OK\r\n"), 9541 MockRead(alternate_protocol_http_header.c_str()), 9542 MockRead("hello world"), 9543 MockRead(SYNCHRONOUS, OK), 9544 }; 9545 9546 SSLSocketDataProvider ssl(ASYNC, OK); 9547 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 9548 ssl.next_proto = "http/1.1"; 9549 ssl.protocol_negotiated = kProtoHTTP11; 9550 9551 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9552 9553 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 9554 data_writes, arraysize(data_writes)); 9555 session_deps_.socket_factory->AddSocketDataProvider(&data); 9556 9557 TestCompletionCallback callback; 9558 9559 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9560 scoped_ptr<HttpTransaction> trans( 9561 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9562 9563 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9564 9565 EXPECT_EQ(ERR_IO_PENDING, rv); 9566 EXPECT_EQ(OK, callback.WaitForResult()); 9567 9568 const HttpResponseInfo* response = trans->GetResponseInfo(); 9569 ASSERT_TRUE(response != NULL); 9570 ASSERT_TRUE(response->headers.get() != NULL); 9571 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9572 9573 std::string response_data; 9574 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9575 EXPECT_EQ("hello world", response_data); 9576 9577 EXPECT_FALSE(response->was_fetched_via_spdy); 9578 EXPECT_TRUE(response->was_npn_negotiated); 9579 } 9580 9581 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) { 9582 // Simulate the SSL handshake completing with an NPN negotiation 9583 // followed by an immediate server closing of the socket. 9584 // Fix crash: http://crbug.com/46369 9585 HttpStreamFactory::set_use_alternate_protocols(true); 9586 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 9587 9588 HttpRequestInfo request; 9589 request.method = "GET"; 9590 request.url = GURL("https://www.google.com/"); 9591 request.load_flags = 0; 9592 9593 SSLSocketDataProvider ssl(ASYNC, OK); 9594 ssl.SetNextProto(GetParam()); 9595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9596 9597 scoped_ptr<SpdyFrame> req( 9598 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 9599 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 9600 9601 MockRead spdy_reads[] = { 9602 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately. 9603 }; 9604 9605 DelayedSocketData spdy_data( 9606 0, // don't wait in this case, immediate hangup. 9607 spdy_reads, arraysize(spdy_reads), 9608 spdy_writes, arraysize(spdy_writes)); 9609 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 9610 9611 TestCompletionCallback callback; 9612 9613 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9614 scoped_ptr<HttpTransaction> trans( 9615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9616 9617 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9618 EXPECT_EQ(ERR_IO_PENDING, rv); 9619 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); 9620 } 9621 9622 // A subclass of HttpAuthHandlerMock that records the request URL when 9623 // it gets it. This is needed since the auth handler may get destroyed 9624 // before we get a chance to query it. 9625 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock { 9626 public: 9627 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {} 9628 9629 virtual ~UrlRecordingHttpAuthHandlerMock() {} 9630 9631 protected: 9632 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials, 9633 const HttpRequestInfo* request, 9634 const CompletionCallback& callback, 9635 std::string* auth_token) OVERRIDE { 9636 *url_ = request->url; 9637 return HttpAuthHandlerMock::GenerateAuthTokenImpl( 9638 credentials, request, callback, auth_token); 9639 } 9640 9641 private: 9642 GURL* url_; 9643 }; 9644 9645 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { 9646 // This test ensures that the URL passed into the proxy is upgraded 9647 // to https when doing an Alternate Protocol upgrade. 9648 HttpStreamFactory::set_use_alternate_protocols(true); 9649 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 9650 9651 session_deps_.proxy_service.reset( 9652 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 9653 CapturingNetLog net_log; 9654 session_deps_.net_log = &net_log; 9655 GURL request_url; 9656 { 9657 HttpAuthHandlerMock::Factory* auth_factory = 9658 new HttpAuthHandlerMock::Factory(); 9659 UrlRecordingHttpAuthHandlerMock* auth_handler = 9660 new UrlRecordingHttpAuthHandlerMock(&request_url); 9661 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); 9662 auth_factory->set_do_init_from_challenge(true); 9663 session_deps_.http_auth_handler_factory.reset(auth_factory); 9664 } 9665 9666 HttpRequestInfo request; 9667 request.method = "GET"; 9668 request.url = GURL("http://www.google.com"); 9669 request.load_flags = 0; 9670 9671 // First round goes unauthenticated through the proxy. 9672 MockWrite data_writes_1[] = { 9673 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 9674 "Host: www.google.com\r\n" 9675 "Proxy-Connection: keep-alive\r\n" 9676 "\r\n"), 9677 }; 9678 MockRead data_reads_1[] = { 9679 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 9680 MockRead("HTTP/1.1 200 OK\r\n" 9681 "Alternate-Protocol: 443:npn-spdy/2\r\n" 9682 "Proxy-Connection: close\r\n" 9683 "\r\n"), 9684 }; 9685 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1), 9686 data_writes_1, arraysize(data_writes_1)); 9687 9688 // Second round tries to tunnel to www.google.com due to the 9689 // Alternate-Protocol announcement in the first round. It fails due 9690 // to a proxy authentication challenge. 9691 // After the failure, a tunnel is established to www.google.com using 9692 // Proxy-Authorization headers. There is then a SPDY request round. 9693 // 9694 // NOTE: Despite the "Proxy-Connection: Close", these are done on the 9695 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket 9696 // does a Disconnect and Connect on the same socket, rather than trying 9697 // to obtain a new one. 9698 // 9699 // NOTE: Originally, the proxy response to the second CONNECT request 9700 // simply returned another 407 so the unit test could skip the SSL connection 9701 // establishment and SPDY framing issues. Alas, the 9702 // retry-http-when-alternate-protocol fails logic kicks in, which was more 9703 // complicated to set up expectations for than the SPDY session. 9704 9705 scoped_ptr<SpdyFrame> req( 9706 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 9707 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 9708 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 9709 9710 MockWrite data_writes_2[] = { 9711 // First connection attempt without Proxy-Authorization. 9712 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 9713 "Host: www.google.com\r\n" 9714 "Proxy-Connection: keep-alive\r\n" 9715 "\r\n"), 9716 9717 // Second connection attempt with Proxy-Authorization. 9718 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 9719 "Host: www.google.com\r\n" 9720 "Proxy-Connection: keep-alive\r\n" 9721 "Proxy-Authorization: auth_token\r\n" 9722 "\r\n"), 9723 9724 // SPDY request 9725 CreateMockWrite(*req), 9726 }; 9727 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n" 9728 "Proxy-Authenticate: Mock\r\n" 9729 "Proxy-Connection: close\r\n" 9730 "\r\n"); 9731 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 9732 MockRead data_reads_2[] = { 9733 // First connection attempt fails 9734 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1), 9735 MockRead(ASYNC, kRejectConnectResponse, 9736 arraysize(kRejectConnectResponse) - 1, 1), 9737 9738 // Second connection attempt passes 9739 MockRead(ASYNC, kAcceptConnectResponse, 9740 arraysize(kAcceptConnectResponse) -1, 4), 9741 9742 // SPDY response 9743 CreateMockRead(*resp.get(), 6), 9744 CreateMockRead(*data.get(), 6), 9745 MockRead(ASYNC, 0, 0, 6), 9746 }; 9747 OrderedSocketData data_2( 9748 data_reads_2, arraysize(data_reads_2), 9749 data_writes_2, arraysize(data_writes_2)); 9750 9751 SSLSocketDataProvider ssl(ASYNC, OK); 9752 ssl.SetNextProto(GetParam()); 9753 9754 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 9755 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 9756 NULL, 0, NULL, 0); 9757 hanging_non_alternate_protocol_socket.set_connect_data( 9758 never_finishing_connect); 9759 9760 session_deps_.socket_factory->AddSocketDataProvider(&data_1); 9761 session_deps_.socket_factory->AddSocketDataProvider(&data_2); 9762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9763 session_deps_.socket_factory->AddSocketDataProvider( 9764 &hanging_non_alternate_protocol_socket); 9765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9766 9767 // First round should work and provide the Alternate-Protocol state. 9768 TestCompletionCallback callback_1; 9769 scoped_ptr<HttpTransaction> trans_1( 9770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9771 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog()); 9772 EXPECT_EQ(ERR_IO_PENDING, rv); 9773 EXPECT_EQ(OK, callback_1.WaitForResult()); 9774 9775 // Second round should attempt a tunnel connect and get an auth challenge. 9776 TestCompletionCallback callback_2; 9777 scoped_ptr<HttpTransaction> trans_2( 9778 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9779 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog()); 9780 EXPECT_EQ(ERR_IO_PENDING, rv); 9781 EXPECT_EQ(OK, callback_2.WaitForResult()); 9782 const HttpResponseInfo* response = trans_2->GetResponseInfo(); 9783 ASSERT_TRUE(response != NULL); 9784 ASSERT_FALSE(response->auth_challenge.get() == NULL); 9785 9786 // Restart with auth. Tunnel should work and response received. 9787 TestCompletionCallback callback_3; 9788 rv = trans_2->RestartWithAuth( 9789 AuthCredentials(kFoo, kBar), callback_3.callback()); 9790 EXPECT_EQ(ERR_IO_PENDING, rv); 9791 EXPECT_EQ(OK, callback_3.WaitForResult()); 9792 9793 // After all that work, these two lines (or actually, just the scheme) are 9794 // what this test is all about. Make sure it happens correctly. 9795 EXPECT_EQ("https", request_url.scheme()); 9796 EXPECT_EQ("www.google.com", request_url.host()); 9797 9798 LoadTimingInfo load_timing_info; 9799 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info)); 9800 TestLoadTimingNotReusedWithPac(load_timing_info, 9801 CONNECT_TIMING_HAS_SSL_TIMES); 9802 } 9803 9804 // Test that if we cancel the transaction as the connection is completing, that 9805 // everything tears down correctly. 9806 TEST_P(HttpNetworkTransactionTest, SimpleCancel) { 9807 // Setup everything about the connection to complete synchronously, so that 9808 // after calling HttpNetworkTransaction::Start, the only thing we're waiting 9809 // for is the callback from the HttpStreamRequest. 9810 // Then cancel the transaction. 9811 // Verify that we don't crash. 9812 MockConnect mock_connect(SYNCHRONOUS, OK); 9813 MockRead data_reads[] = { 9814 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"), 9815 MockRead(SYNCHRONOUS, "hello world"), 9816 MockRead(SYNCHRONOUS, OK), 9817 }; 9818 9819 HttpRequestInfo request; 9820 request.method = "GET"; 9821 request.url = GURL("http://www.google.com/"); 9822 request.load_flags = 0; 9823 9824 session_deps_.host_resolver->set_synchronous_mode(true); 9825 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9826 scoped_ptr<HttpTransaction> trans( 9827 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 9828 9829 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 9830 data.set_connect_data(mock_connect); 9831 session_deps_.socket_factory->AddSocketDataProvider(&data); 9832 9833 TestCompletionCallback callback; 9834 9835 CapturingBoundNetLog log; 9836 int rv = trans->Start(&request, callback.callback(), log.bound()); 9837 EXPECT_EQ(ERR_IO_PENDING, rv); 9838 trans.reset(); // Cancel the transaction here. 9839 9840 base::MessageLoop::current()->RunUntilIdle(); 9841 } 9842 9843 // Test a basic GET request through a proxy. 9844 TEST_P(HttpNetworkTransactionTest, ProxyGet) { 9845 session_deps_.proxy_service.reset( 9846 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 9847 CapturingBoundNetLog log; 9848 session_deps_.net_log = log.bound().net_log(); 9849 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9850 9851 HttpRequestInfo request; 9852 request.method = "GET"; 9853 request.url = GURL("http://www.google.com/"); 9854 9855 MockWrite data_writes1[] = { 9856 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 9857 "Host: www.google.com\r\n" 9858 "Proxy-Connection: keep-alive\r\n\r\n"), 9859 }; 9860 9861 MockRead data_reads1[] = { 9862 MockRead("HTTP/1.1 200 OK\r\n"), 9863 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 9864 MockRead("Content-Length: 100\r\n\r\n"), 9865 MockRead(SYNCHRONOUS, OK), 9866 }; 9867 9868 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 9869 data_writes1, arraysize(data_writes1)); 9870 session_deps_.socket_factory->AddSocketDataProvider(&data1); 9871 9872 TestCompletionCallback callback1; 9873 9874 scoped_ptr<HttpTransaction> trans( 9875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9876 9877 int rv = trans->Start(&request, callback1.callback(), log.bound()); 9878 EXPECT_EQ(ERR_IO_PENDING, rv); 9879 9880 rv = callback1.WaitForResult(); 9881 EXPECT_EQ(OK, rv); 9882 9883 const HttpResponseInfo* response = trans->GetResponseInfo(); 9884 ASSERT_TRUE(response != NULL); 9885 9886 EXPECT_TRUE(response->headers->IsKeepAlive()); 9887 EXPECT_EQ(200, response->headers->response_code()); 9888 EXPECT_EQ(100, response->headers->GetContentLength()); 9889 EXPECT_TRUE(response->was_fetched_via_proxy); 9890 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 9891 9892 LoadTimingInfo load_timing_info; 9893 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 9894 TestLoadTimingNotReusedWithPac(load_timing_info, 9895 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 9896 } 9897 9898 // Test a basic HTTPS GET request through a proxy. 9899 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) { 9900 session_deps_.proxy_service.reset( 9901 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 9902 CapturingBoundNetLog log; 9903 session_deps_.net_log = log.bound().net_log(); 9904 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9905 9906 HttpRequestInfo request; 9907 request.method = "GET"; 9908 request.url = GURL("https://www.google.com/"); 9909 9910 // Since we have proxy, should try to establish tunnel. 9911 MockWrite data_writes1[] = { 9912 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 9913 "Host: www.google.com\r\n" 9914 "Proxy-Connection: keep-alive\r\n\r\n"), 9915 9916 MockWrite("GET / HTTP/1.1\r\n" 9917 "Host: www.google.com\r\n" 9918 "Connection: keep-alive\r\n\r\n"), 9919 }; 9920 9921 MockRead data_reads1[] = { 9922 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 9923 9924 MockRead("HTTP/1.1 200 OK\r\n"), 9925 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 9926 MockRead("Content-Length: 100\r\n\r\n"), 9927 MockRead(SYNCHRONOUS, OK), 9928 }; 9929 9930 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 9931 data_writes1, arraysize(data_writes1)); 9932 session_deps_.socket_factory->AddSocketDataProvider(&data1); 9933 SSLSocketDataProvider ssl(ASYNC, OK); 9934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9935 9936 TestCompletionCallback callback1; 9937 9938 scoped_ptr<HttpTransaction> trans( 9939 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9940 9941 int rv = trans->Start(&request, callback1.callback(), log.bound()); 9942 EXPECT_EQ(ERR_IO_PENDING, rv); 9943 9944 rv = callback1.WaitForResult(); 9945 EXPECT_EQ(OK, rv); 9946 net::CapturingNetLog::CapturedEntryList entries; 9947 log.GetEntries(&entries); 9948 size_t pos = ExpectLogContainsSomewhere( 9949 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 9950 NetLog::PHASE_NONE); 9951 ExpectLogContainsSomewhere( 9952 entries, pos, 9953 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 9954 NetLog::PHASE_NONE); 9955 9956 const HttpResponseInfo* response = trans->GetResponseInfo(); 9957 ASSERT_TRUE(response != NULL); 9958 9959 EXPECT_TRUE(response->headers->IsKeepAlive()); 9960 EXPECT_EQ(200, response->headers->response_code()); 9961 EXPECT_EQ(100, response->headers->GetContentLength()); 9962 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 9963 EXPECT_TRUE(response->was_fetched_via_proxy); 9964 9965 LoadTimingInfo load_timing_info; 9966 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 9967 TestLoadTimingNotReusedWithPac(load_timing_info, 9968 CONNECT_TIMING_HAS_SSL_TIMES); 9969 } 9970 9971 // Test a basic HTTPS GET request through a proxy, but the server hangs up 9972 // while establishing the tunnel. 9973 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { 9974 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 9975 CapturingBoundNetLog log; 9976 session_deps_.net_log = log.bound().net_log(); 9977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9978 9979 HttpRequestInfo request; 9980 request.method = "GET"; 9981 request.url = GURL("https://www.google.com/"); 9982 9983 // Since we have proxy, should try to establish tunnel. 9984 MockWrite data_writes1[] = { 9985 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 9986 "Host: www.google.com\r\n" 9987 "Proxy-Connection: keep-alive\r\n\r\n"), 9988 9989 MockWrite("GET / HTTP/1.1\r\n" 9990 "Host: www.google.com\r\n" 9991 "Connection: keep-alive\r\n\r\n"), 9992 }; 9993 9994 MockRead data_reads1[] = { 9995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 9996 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 9997 MockRead(ASYNC, 0, 0), // EOF 9998 }; 9999 10000 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 10001 data_writes1, arraysize(data_writes1)); 10002 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10003 SSLSocketDataProvider ssl(ASYNC, OK); 10004 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10005 10006 TestCompletionCallback callback1; 10007 10008 scoped_ptr<HttpTransaction> trans( 10009 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10010 10011 int rv = trans->Start(&request, callback1.callback(), log.bound()); 10012 EXPECT_EQ(ERR_IO_PENDING, rv); 10013 10014 rv = callback1.WaitForResult(); 10015 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 10016 net::CapturingNetLog::CapturedEntryList entries; 10017 log.GetEntries(&entries); 10018 size_t pos = ExpectLogContainsSomewhere( 10019 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 10020 NetLog::PHASE_NONE); 10021 ExpectLogContainsSomewhere( 10022 entries, pos, 10023 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 10024 NetLog::PHASE_NONE); 10025 } 10026 10027 // Test for crbug.com/55424. 10028 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) { 10029 scoped_ptr<SpdyFrame> req( 10030 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10031 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 10032 10033 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10034 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10035 MockRead spdy_reads[] = { 10036 CreateMockRead(*resp), 10037 CreateMockRead(*data), 10038 MockRead(ASYNC, 0, 0), 10039 }; 10040 10041 DelayedSocketData spdy_data( 10042 1, // wait for one write to finish before reading. 10043 spdy_reads, arraysize(spdy_reads), 10044 spdy_writes, arraysize(spdy_writes)); 10045 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10046 10047 SSLSocketDataProvider ssl(ASYNC, OK); 10048 ssl.SetNextProto(GetParam()); 10049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10050 10051 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10052 10053 // Set up an initial SpdySession in the pool to reuse. 10054 HostPortPair host_port_pair("www.google.com", 443); 10055 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 10056 kPrivacyModeDisabled); 10057 base::WeakPtr<SpdySession> spdy_session = 10058 CreateInsecureSpdySession(session, key, BoundNetLog()); 10059 10060 HttpRequestInfo request; 10061 request.method = "GET"; 10062 request.url = GURL("https://www.google.com/"); 10063 request.load_flags = 0; 10064 10065 // This is the important line that marks this as a preconnect. 10066 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED; 10067 10068 scoped_ptr<HttpTransaction> trans( 10069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10070 10071 TestCompletionCallback callback; 10072 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 10073 EXPECT_EQ(ERR_IO_PENDING, rv); 10074 EXPECT_EQ(OK, callback.WaitForResult()); 10075 } 10076 10077 // Given a net error, cause that error to be returned from the first Write() 10078 // call and verify that the HttpTransaction fails with that error. 10079 void HttpNetworkTransactionTest::CheckErrorIsPassedBack( 10080 int error, IoMode mode) { 10081 net::HttpRequestInfo request_info; 10082 request_info.url = GURL("https://www.example.com/"); 10083 request_info.method = "GET"; 10084 request_info.load_flags = net::LOAD_NORMAL; 10085 10086 SSLSocketDataProvider ssl_data(mode, OK); 10087 net::MockWrite data_writes[] = { 10088 net::MockWrite(mode, error), 10089 }; 10090 net::StaticSocketDataProvider data(NULL, 0, 10091 data_writes, arraysize(data_writes)); 10092 session_deps_.socket_factory->AddSocketDataProvider(&data); 10093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); 10094 10095 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10096 scoped_ptr<HttpTransaction> trans( 10097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10098 10099 TestCompletionCallback callback; 10100 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10101 if (rv == net::ERR_IO_PENDING) 10102 rv = callback.WaitForResult(); 10103 ASSERT_EQ(error, rv); 10104 } 10105 10106 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) { 10107 // Just check a grab bag of cert errors. 10108 static const int kErrors[] = { 10109 ERR_CERT_COMMON_NAME_INVALID, 10110 ERR_CERT_AUTHORITY_INVALID, 10111 ERR_CERT_DATE_INVALID, 10112 }; 10113 for (size_t i = 0; i < arraysize(kErrors); i++) { 10114 CheckErrorIsPassedBack(kErrors[i], ASYNC); 10115 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS); 10116 } 10117 } 10118 10119 // Ensure that a client certificate is removed from the SSL client auth 10120 // cache when: 10121 // 1) No proxy is involved. 10122 // 2) TLS False Start is disabled. 10123 // 3) The initial TLS handshake requests a client certificate. 10124 // 4) The client supplies an invalid/unacceptable certificate. 10125 TEST_P(HttpNetworkTransactionTest, 10126 ClientAuthCertCache_Direct_NoFalseStart) { 10127 net::HttpRequestInfo request_info; 10128 request_info.url = GURL("https://www.example.com/"); 10129 request_info.method = "GET"; 10130 request_info.load_flags = net::LOAD_NORMAL; 10131 10132 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10133 cert_request->host_and_port = "www.example.com:443"; 10134 10135 // [ssl_]data1 contains the data for the first SSL handshake. When a 10136 // CertificateRequest is received for the first time, the handshake will 10137 // be aborted to allow the caller to provide a certificate. 10138 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10139 ssl_data1.cert_request_info = cert_request.get(); 10140 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10141 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10142 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10143 10144 // [ssl_]data2 contains the data for the second SSL handshake. When TLS 10145 // False Start is not being used, the result of the SSL handshake will be 10146 // returned as part of the SSLClientSocket::Connect() call. This test 10147 // matches the result of a server sending a handshake_failure alert, 10148 // rather than a Finished message, because it requires a client 10149 // certificate and none was supplied. 10150 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10151 ssl_data2.cert_request_info = cert_request.get(); 10152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10153 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 10154 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10155 10156 // [ssl_]data3 contains the data for the third SSL handshake. When a 10157 // connection to a server fails during an SSL handshake, 10158 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous 10159 // connection was attempted with TLSv1.1. This is transparent to the caller 10160 // of the HttpNetworkTransaction. Because this test failure is due to 10161 // requiring a client certificate, this fallback handshake should also 10162 // fail. 10163 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10164 ssl_data3.cert_request_info = cert_request.get(); 10165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10166 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 10167 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10168 10169 // [ssl_]data4 contains the data for the fourth SSL handshake. When a 10170 // connection to a server fails during an SSL handshake, 10171 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous 10172 // connection was attempted with TLSv1. This is transparent to the caller 10173 // of the HttpNetworkTransaction. Because this test failure is due to 10174 // requiring a client certificate, this fallback handshake should also 10175 // fail. 10176 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10177 ssl_data4.cert_request_info = cert_request.get(); 10178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4); 10179 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0); 10180 session_deps_.socket_factory->AddSocketDataProvider(&data4); 10181 10182 // Need one more if TLSv1.2 is enabled. 10183 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10184 ssl_data5.cert_request_info = cert_request.get(); 10185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5); 10186 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0); 10187 session_deps_.socket_factory->AddSocketDataProvider(&data5); 10188 10189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10190 scoped_ptr<HttpTransaction> trans( 10191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10192 10193 // Begin the SSL handshake with the peer. This consumes ssl_data1. 10194 TestCompletionCallback callback; 10195 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10196 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10197 10198 // Complete the SSL handshake, which should abort due to requiring a 10199 // client certificate. 10200 rv = callback.WaitForResult(); 10201 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10202 10203 // Indicate that no certificate should be supplied. From the perspective 10204 // of SSLClientCertCache, NULL is just as meaningful as a real 10205 // certificate, so this is the same as supply a 10206 // legitimate-but-unacceptable certificate. 10207 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10208 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10209 10210 // Ensure the certificate was added to the client auth cache before 10211 // allowing the connection to continue restarting. 10212 scoped_refptr<X509Certificate> client_cert; 10213 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 10214 &client_cert)); 10215 ASSERT_EQ(NULL, client_cert.get()); 10216 10217 // Restart the handshake. This will consume ssl_data2, which fails, and 10218 // then consume ssl_data3 and ssl_data4, both of which should also fail. 10219 // The result code is checked against what ssl_data4 should return. 10220 rv = callback.WaitForResult(); 10221 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 10222 10223 // Ensure that the client certificate is removed from the cache on a 10224 // handshake failure. 10225 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 10226 &client_cert)); 10227 } 10228 10229 // Ensure that a client certificate is removed from the SSL client auth 10230 // cache when: 10231 // 1) No proxy is involved. 10232 // 2) TLS False Start is enabled. 10233 // 3) The initial TLS handshake requests a client certificate. 10234 // 4) The client supplies an invalid/unacceptable certificate. 10235 TEST_P(HttpNetworkTransactionTest, 10236 ClientAuthCertCache_Direct_FalseStart) { 10237 net::HttpRequestInfo request_info; 10238 request_info.url = GURL("https://www.example.com/"); 10239 request_info.method = "GET"; 10240 request_info.load_flags = net::LOAD_NORMAL; 10241 10242 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10243 cert_request->host_and_port = "www.example.com:443"; 10244 10245 // When TLS False Start is used, SSLClientSocket::Connect() calls will 10246 // return successfully after reading up to the peer's Certificate message. 10247 // This is to allow the caller to call SSLClientSocket::Write(), which can 10248 // enqueue application data to be sent in the same packet as the 10249 // ChangeCipherSpec and Finished messages. 10250 // The actual handshake will be finished when SSLClientSocket::Read() is 10251 // called, which expects to process the peer's ChangeCipherSpec and 10252 // Finished messages. If there was an error negotiating with the peer, 10253 // such as due to the peer requiring a client certificate when none was 10254 // supplied, the alert sent by the peer won't be processed until Read() is 10255 // called. 10256 10257 // Like the non-False Start case, when a client certificate is requested by 10258 // the peer, the handshake is aborted during the Connect() call. 10259 // [ssl_]data1 represents the initial SSL handshake with the peer. 10260 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10261 ssl_data1.cert_request_info = cert_request.get(); 10262 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10263 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10264 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10265 10266 // When a client certificate is supplied, Connect() will not be aborted 10267 // when the peer requests the certificate. Instead, the handshake will 10268 // artificially succeed, allowing the caller to write the HTTP request to 10269 // the socket. The handshake messages are not processed until Read() is 10270 // called, which then detects that the handshake was aborted, due to the 10271 // peer sending a handshake_failure because it requires a client 10272 // certificate. 10273 SSLSocketDataProvider ssl_data2(ASYNC, net::OK); 10274 ssl_data2.cert_request_info = cert_request.get(); 10275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10276 net::MockRead data2_reads[] = { 10277 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR), 10278 }; 10279 net::StaticSocketDataProvider data2( 10280 data2_reads, arraysize(data2_reads), NULL, 0); 10281 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10282 10283 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is 10284 // the data for the SSL handshake once the TLSv1.1 connection falls back to 10285 // TLSv1. It has the same behaviour as [ssl_]data2. 10286 SSLSocketDataProvider ssl_data3(ASYNC, net::OK); 10287 ssl_data3.cert_request_info = cert_request.get(); 10288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10289 net::StaticSocketDataProvider data3( 10290 data2_reads, arraysize(data2_reads), NULL, 0); 10291 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10292 10293 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection 10294 // falls back to SSLv3. It has the same behaviour as [ssl_]data2. 10295 SSLSocketDataProvider ssl_data4(ASYNC, net::OK); 10296 ssl_data4.cert_request_info = cert_request.get(); 10297 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4); 10298 net::StaticSocketDataProvider data4( 10299 data2_reads, arraysize(data2_reads), NULL, 0); 10300 session_deps_.socket_factory->AddSocketDataProvider(&data4); 10301 10302 // Need one more if TLSv1.2 is enabled. 10303 SSLSocketDataProvider ssl_data5(ASYNC, net::OK); 10304 ssl_data5.cert_request_info = cert_request.get(); 10305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5); 10306 net::StaticSocketDataProvider data5( 10307 data2_reads, arraysize(data2_reads), NULL, 0); 10308 session_deps_.socket_factory->AddSocketDataProvider(&data5); 10309 10310 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10311 scoped_ptr<HttpTransaction> trans( 10312 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10313 10314 // Begin the initial SSL handshake. 10315 TestCompletionCallback callback; 10316 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10317 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10318 10319 // Complete the SSL handshake, which should abort due to requiring a 10320 // client certificate. 10321 rv = callback.WaitForResult(); 10322 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10323 10324 // Indicate that no certificate should be supplied. From the perspective 10325 // of SSLClientCertCache, NULL is just as meaningful as a real 10326 // certificate, so this is the same as supply a 10327 // legitimate-but-unacceptable certificate. 10328 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10329 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10330 10331 // Ensure the certificate was added to the client auth cache before 10332 // allowing the connection to continue restarting. 10333 scoped_refptr<X509Certificate> client_cert; 10334 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 10335 &client_cert)); 10336 ASSERT_EQ(NULL, client_cert.get()); 10337 10338 // Restart the handshake. This will consume ssl_data2, which fails, and 10339 // then consume ssl_data3 and ssl_data4, both of which should also fail. 10340 // The result code is checked against what ssl_data4 should return. 10341 rv = callback.WaitForResult(); 10342 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 10343 10344 // Ensure that the client certificate is removed from the cache on a 10345 // handshake failure. 10346 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 10347 &client_cert)); 10348 } 10349 10350 // Ensure that a client certificate is removed from the SSL client auth 10351 // cache when: 10352 // 1) An HTTPS proxy is involved. 10353 // 3) The HTTPS proxy requests a client certificate. 10354 // 4) The client supplies an invalid/unacceptable certificate for the 10355 // proxy. 10356 // The test is repeated twice, first for connecting to an HTTPS endpoint, 10357 // then for connecting to an HTTP endpoint. 10358 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) { 10359 session_deps_.proxy_service.reset( 10360 ProxyService::CreateFixed("https://proxy:70")); 10361 CapturingBoundNetLog log; 10362 session_deps_.net_log = log.bound().net_log(); 10363 10364 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10365 cert_request->host_and_port = "proxy:70"; 10366 10367 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of 10368 // [ssl_]data[1-3]. Rather than represending the endpoint 10369 // (www.example.com:443), they represent failures with the HTTPS proxy 10370 // (proxy:70). 10371 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10372 ssl_data1.cert_request_info = cert_request.get(); 10373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10374 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10375 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10376 10377 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10378 ssl_data2.cert_request_info = cert_request.get(); 10379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10380 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 10381 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10382 10383 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3. 10384 #if 0 10385 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10386 ssl_data3.cert_request_info = cert_request.get(); 10387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10388 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 10389 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10390 #endif 10391 10392 net::HttpRequestInfo requests[2]; 10393 requests[0].url = GURL("https://www.example.com/"); 10394 requests[0].method = "GET"; 10395 requests[0].load_flags = net::LOAD_NORMAL; 10396 10397 requests[1].url = GURL("http://www.example.com/"); 10398 requests[1].method = "GET"; 10399 requests[1].load_flags = net::LOAD_NORMAL; 10400 10401 for (size_t i = 0; i < arraysize(requests); ++i) { 10402 session_deps_.socket_factory->ResetNextMockIndexes(); 10403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10404 scoped_ptr<HttpNetworkTransaction> trans( 10405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10406 10407 // Begin the SSL handshake with the proxy. 10408 TestCompletionCallback callback; 10409 int rv = trans->Start( 10410 &requests[i], callback.callback(), net::BoundNetLog()); 10411 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10412 10413 // Complete the SSL handshake, which should abort due to requiring a 10414 // client certificate. 10415 rv = callback.WaitForResult(); 10416 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10417 10418 // Indicate that no certificate should be supplied. From the perspective 10419 // of SSLClientCertCache, NULL is just as meaningful as a real 10420 // certificate, so this is the same as supply a 10421 // legitimate-but-unacceptable certificate. 10422 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10423 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10424 10425 // Ensure the certificate was added to the client auth cache before 10426 // allowing the connection to continue restarting. 10427 scoped_refptr<X509Certificate> client_cert; 10428 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70", 10429 &client_cert)); 10430 ASSERT_EQ(NULL, client_cert.get()); 10431 // Ensure the certificate was NOT cached for the endpoint. This only 10432 // applies to HTTPS requests, but is fine to check for HTTP requests. 10433 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 10434 &client_cert)); 10435 10436 // Restart the handshake. This will consume ssl_data2, which fails, and 10437 // then consume ssl_data3, which should also fail. The result code is 10438 // checked against what ssl_data3 should return. 10439 rv = callback.WaitForResult(); 10440 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv); 10441 10442 // Now that the new handshake has failed, ensure that the client 10443 // certificate was removed from the client auth cache. 10444 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70", 10445 &client_cert)); 10446 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 10447 &client_cert)); 10448 } 10449 } 10450 10451 // Unlike TEST/TEST_F, which are macros that expand to further macros, 10452 // TEST_P is a macro that expands directly to code that stringizes the 10453 // arguments. As a result, macros passed as parameters (such as prefix 10454 // or test_case_name) will not be expanded by the preprocessor. To 10455 // work around this, indirect the macro for TEST_P, so that the 10456 // pre-processor will expand macros such as MAYBE_test_name before 10457 // instantiating the test. 10458 #define WRAPPED_TEST_P(test_case_name, test_name) \ 10459 TEST_P(test_case_name, test_name) 10460 10461 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 10462 #if defined(OS_WIN) 10463 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling 10464 #else 10465 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling 10466 #endif 10467 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) { 10468 HttpStreamFactory::set_use_alternate_protocols(true); 10469 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 10470 10471 // Set up a special HttpNetworkSession with a MockCachingHostResolver. 10472 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 10473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10474 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 10475 pool_peer.DisableDomainAuthenticationVerification(); 10476 10477 SSLSocketDataProvider ssl(ASYNC, OK); 10478 ssl.SetNextProto(GetParam()); 10479 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10480 10481 scoped_ptr<SpdyFrame> host1_req( 10482 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10483 scoped_ptr<SpdyFrame> host2_req( 10484 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 10485 MockWrite spdy_writes[] = { 10486 CreateMockWrite(*host1_req, 1), 10487 CreateMockWrite(*host2_req, 4), 10488 }; 10489 scoped_ptr<SpdyFrame> host1_resp( 10490 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10491 scoped_ptr<SpdyFrame> host1_resp_body( 10492 spdy_util_.ConstructSpdyBodyFrame(1, true)); 10493 scoped_ptr<SpdyFrame> host2_resp( 10494 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 10495 scoped_ptr<SpdyFrame> host2_resp_body( 10496 spdy_util_.ConstructSpdyBodyFrame(3, true)); 10497 MockRead spdy_reads[] = { 10498 CreateMockRead(*host1_resp, 2), 10499 CreateMockRead(*host1_resp_body, 3), 10500 CreateMockRead(*host2_resp, 5), 10501 CreateMockRead(*host2_resp_body, 6), 10502 MockRead(ASYNC, 0, 7), 10503 }; 10504 10505 IPAddressNumber ip; 10506 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 10507 IPEndPoint peer_addr = IPEndPoint(ip, 443); 10508 MockConnect connect(ASYNC, OK, peer_addr); 10509 OrderedSocketData spdy_data( 10510 connect, 10511 spdy_reads, arraysize(spdy_reads), 10512 spdy_writes, arraysize(spdy_writes)); 10513 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10514 10515 TestCompletionCallback callback; 10516 HttpRequestInfo request1; 10517 request1.method = "GET"; 10518 request1.url = GURL("https://www.google.com/"); 10519 request1.load_flags = 0; 10520 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 10521 10522 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 10523 EXPECT_EQ(ERR_IO_PENDING, rv); 10524 EXPECT_EQ(OK, callback.WaitForResult()); 10525 10526 const HttpResponseInfo* response = trans1.GetResponseInfo(); 10527 ASSERT_TRUE(response != NULL); 10528 ASSERT_TRUE(response->headers.get() != NULL); 10529 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10530 10531 std::string response_data; 10532 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 10533 EXPECT_EQ("hello!", response_data); 10534 10535 // Preload www.gmail.com into HostCache. 10536 HostPortPair host_port("www.gmail.com", 443); 10537 HostResolver::RequestInfo resolve_info(host_port); 10538 AddressList ignored; 10539 rv = session_deps_.host_resolver->Resolve(resolve_info, 10540 DEFAULT_PRIORITY, 10541 &ignored, 10542 callback.callback(), 10543 NULL, 10544 BoundNetLog()); 10545 EXPECT_EQ(ERR_IO_PENDING, rv); 10546 rv = callback.WaitForResult(); 10547 EXPECT_EQ(OK, rv); 10548 10549 HttpRequestInfo request2; 10550 request2.method = "GET"; 10551 request2.url = GURL("https://www.gmail.com/"); 10552 request2.load_flags = 0; 10553 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 10554 10555 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 10556 EXPECT_EQ(ERR_IO_PENDING, rv); 10557 EXPECT_EQ(OK, callback.WaitForResult()); 10558 10559 response = trans2.GetResponseInfo(); 10560 ASSERT_TRUE(response != NULL); 10561 ASSERT_TRUE(response->headers.get() != NULL); 10562 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10563 EXPECT_TRUE(response->was_fetched_via_spdy); 10564 EXPECT_TRUE(response->was_npn_negotiated); 10565 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 10566 EXPECT_EQ("hello!", response_data); 10567 } 10568 #undef MAYBE_UseIPConnectionPooling 10569 10570 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) { 10571 HttpStreamFactory::set_use_alternate_protocols(true); 10572 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 10573 10574 // Set up a special HttpNetworkSession with a MockCachingHostResolver. 10575 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 10576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10577 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 10578 pool_peer.DisableDomainAuthenticationVerification(); 10579 10580 SSLSocketDataProvider ssl(ASYNC, OK); 10581 ssl.SetNextProto(GetParam()); 10582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10583 10584 scoped_ptr<SpdyFrame> host1_req( 10585 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10586 scoped_ptr<SpdyFrame> host2_req( 10587 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 10588 MockWrite spdy_writes[] = { 10589 CreateMockWrite(*host1_req, 1), 10590 CreateMockWrite(*host2_req, 4), 10591 }; 10592 scoped_ptr<SpdyFrame> host1_resp( 10593 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10594 scoped_ptr<SpdyFrame> host1_resp_body( 10595 spdy_util_.ConstructSpdyBodyFrame(1, true)); 10596 scoped_ptr<SpdyFrame> host2_resp( 10597 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 10598 scoped_ptr<SpdyFrame> host2_resp_body( 10599 spdy_util_.ConstructSpdyBodyFrame(3, true)); 10600 MockRead spdy_reads[] = { 10601 CreateMockRead(*host1_resp, 2), 10602 CreateMockRead(*host1_resp_body, 3), 10603 CreateMockRead(*host2_resp, 5), 10604 CreateMockRead(*host2_resp_body, 6), 10605 MockRead(ASYNC, 0, 7), 10606 }; 10607 10608 IPAddressNumber ip; 10609 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 10610 IPEndPoint peer_addr = IPEndPoint(ip, 443); 10611 MockConnect connect(ASYNC, OK, peer_addr); 10612 OrderedSocketData spdy_data( 10613 connect, 10614 spdy_reads, arraysize(spdy_reads), 10615 spdy_writes, arraysize(spdy_writes)); 10616 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10617 10618 TestCompletionCallback callback; 10619 HttpRequestInfo request1; 10620 request1.method = "GET"; 10621 request1.url = GURL("https://www.google.com/"); 10622 request1.load_flags = 0; 10623 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 10624 10625 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 10626 EXPECT_EQ(ERR_IO_PENDING, rv); 10627 EXPECT_EQ(OK, callback.WaitForResult()); 10628 10629 const HttpResponseInfo* response = trans1.GetResponseInfo(); 10630 ASSERT_TRUE(response != NULL); 10631 ASSERT_TRUE(response->headers.get() != NULL); 10632 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10633 10634 std::string response_data; 10635 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 10636 EXPECT_EQ("hello!", response_data); 10637 10638 HttpRequestInfo request2; 10639 request2.method = "GET"; 10640 request2.url = GURL("https://www.gmail.com/"); 10641 request2.load_flags = 0; 10642 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 10643 10644 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 10645 EXPECT_EQ(ERR_IO_PENDING, rv); 10646 EXPECT_EQ(OK, callback.WaitForResult()); 10647 10648 response = trans2.GetResponseInfo(); 10649 ASSERT_TRUE(response != NULL); 10650 ASSERT_TRUE(response->headers.get() != NULL); 10651 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10652 EXPECT_TRUE(response->was_fetched_via_spdy); 10653 EXPECT_TRUE(response->was_npn_negotiated); 10654 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 10655 EXPECT_EQ("hello!", response_data); 10656 } 10657 10658 class OneTimeCachingHostResolver : public net::HostResolver { 10659 public: 10660 explicit OneTimeCachingHostResolver(const HostPortPair& host_port) 10661 : host_port_(host_port) {} 10662 virtual ~OneTimeCachingHostResolver() {} 10663 10664 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); } 10665 10666 // HostResolver methods: 10667 virtual int Resolve(const RequestInfo& info, 10668 RequestPriority priority, 10669 AddressList* addresses, 10670 const CompletionCallback& callback, 10671 RequestHandle* out_req, 10672 const BoundNetLog& net_log) OVERRIDE { 10673 return host_resolver_.Resolve( 10674 info, priority, addresses, callback, out_req, net_log); 10675 } 10676 10677 virtual int ResolveFromCache(const RequestInfo& info, 10678 AddressList* addresses, 10679 const BoundNetLog& net_log) OVERRIDE { 10680 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log); 10681 if (rv == OK && info.host_port_pair().Equals(host_port_)) 10682 host_resolver_.GetHostCache()->clear(); 10683 return rv; 10684 } 10685 10686 virtual void CancelRequest(RequestHandle req) OVERRIDE { 10687 host_resolver_.CancelRequest(req); 10688 } 10689 10690 MockCachingHostResolver* GetMockHostResolver() { 10691 return &host_resolver_; 10692 } 10693 10694 private: 10695 MockCachingHostResolver host_resolver_; 10696 const HostPortPair host_port_; 10697 }; 10698 10699 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 10700 #if defined(OS_WIN) 10701 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \ 10702 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration 10703 #else 10704 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \ 10705 UseIPConnectionPoolingWithHostCacheExpiration 10706 #endif 10707 WRAPPED_TEST_P(HttpNetworkTransactionTest, 10708 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) { 10709 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_ 10710 // prefix doesn't work with parametrized tests). 10711 #if defined(OS_WIN) 10712 return; 10713 #endif 10714 10715 HttpStreamFactory::set_use_alternate_protocols(true); 10716 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 10717 10718 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver. 10719 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443)); 10720 HttpNetworkSession::Params params = 10721 SpdySessionDependencies::CreateSessionParams(&session_deps_); 10722 params.host_resolver = &host_resolver; 10723 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10724 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 10725 pool_peer.DisableDomainAuthenticationVerification(); 10726 10727 SSLSocketDataProvider ssl(ASYNC, OK); 10728 ssl.SetNextProto(GetParam()); 10729 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10730 10731 scoped_ptr<SpdyFrame> host1_req( 10732 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10733 scoped_ptr<SpdyFrame> host2_req( 10734 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 10735 MockWrite spdy_writes[] = { 10736 CreateMockWrite(*host1_req, 1), 10737 CreateMockWrite(*host2_req, 4), 10738 }; 10739 scoped_ptr<SpdyFrame> host1_resp( 10740 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10741 scoped_ptr<SpdyFrame> host1_resp_body( 10742 spdy_util_.ConstructSpdyBodyFrame(1, true)); 10743 scoped_ptr<SpdyFrame> host2_resp( 10744 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 10745 scoped_ptr<SpdyFrame> host2_resp_body( 10746 spdy_util_.ConstructSpdyBodyFrame(3, true)); 10747 MockRead spdy_reads[] = { 10748 CreateMockRead(*host1_resp, 2), 10749 CreateMockRead(*host1_resp_body, 3), 10750 CreateMockRead(*host2_resp, 5), 10751 CreateMockRead(*host2_resp_body, 6), 10752 MockRead(ASYNC, 0, 7), 10753 }; 10754 10755 IPAddressNumber ip; 10756 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 10757 IPEndPoint peer_addr = IPEndPoint(ip, 443); 10758 MockConnect connect(ASYNC, OK, peer_addr); 10759 OrderedSocketData spdy_data( 10760 connect, 10761 spdy_reads, arraysize(spdy_reads), 10762 spdy_writes, arraysize(spdy_writes)); 10763 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10764 10765 TestCompletionCallback callback; 10766 HttpRequestInfo request1; 10767 request1.method = "GET"; 10768 request1.url = GURL("https://www.google.com/"); 10769 request1.load_flags = 0; 10770 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 10771 10772 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 10773 EXPECT_EQ(ERR_IO_PENDING, rv); 10774 EXPECT_EQ(OK, callback.WaitForResult()); 10775 10776 const HttpResponseInfo* response = trans1.GetResponseInfo(); 10777 ASSERT_TRUE(response != NULL); 10778 ASSERT_TRUE(response->headers.get() != NULL); 10779 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10780 10781 std::string response_data; 10782 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 10783 EXPECT_EQ("hello!", response_data); 10784 10785 // Preload cache entries into HostCache. 10786 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443)); 10787 AddressList ignored; 10788 rv = host_resolver.Resolve(resolve_info, 10789 DEFAULT_PRIORITY, 10790 &ignored, 10791 callback.callback(), 10792 NULL, 10793 BoundNetLog()); 10794 EXPECT_EQ(ERR_IO_PENDING, rv); 10795 rv = callback.WaitForResult(); 10796 EXPECT_EQ(OK, rv); 10797 10798 HttpRequestInfo request2; 10799 request2.method = "GET"; 10800 request2.url = GURL("https://www.gmail.com/"); 10801 request2.load_flags = 0; 10802 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 10803 10804 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 10805 EXPECT_EQ(ERR_IO_PENDING, rv); 10806 EXPECT_EQ(OK, callback.WaitForResult()); 10807 10808 response = trans2.GetResponseInfo(); 10809 ASSERT_TRUE(response != NULL); 10810 ASSERT_TRUE(response->headers.get() != NULL); 10811 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10812 EXPECT_TRUE(response->was_fetched_via_spdy); 10813 EXPECT_TRUE(response->was_npn_negotiated); 10814 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 10815 EXPECT_EQ("hello!", response_data); 10816 } 10817 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration 10818 10819 TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) { 10820 MockRead data_reads1[] = { 10821 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION), 10822 }; 10823 MockRead data_reads2[] = { 10824 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 10825 MockRead("hello world"), 10826 MockRead(SYNCHRONOUS, OK), 10827 }; 10828 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0); 10829 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0); 10830 StaticSocketDataProvider* data[] = { &data1, &data2 }; 10831 10832 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data)); 10833 10834 EXPECT_EQ(OK, out.rv); 10835 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 10836 EXPECT_EQ("hello world", out.response_data); 10837 } 10838 10839 TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) { 10840 MockWrite data_writes1[] = { 10841 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION), 10842 }; 10843 MockWrite data_writes2[] = { 10844 MockWrite("GET / HTTP/1.1\r\n" 10845 "Host: www.google.com\r\n" 10846 "Connection: keep-alive\r\n\r\n"), 10847 }; 10848 MockRead data_reads2[] = { 10849 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 10850 MockRead("hello world"), 10851 MockRead(SYNCHRONOUS, OK), 10852 }; 10853 StaticSocketDataProvider data1(NULL, 0, 10854 data_writes1, arraysize(data_writes1)); 10855 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 10856 data_writes2, arraysize(data_writes2)); 10857 StaticSocketDataProvider* data[] = { &data1, &data2 }; 10858 10859 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data)); 10860 10861 EXPECT_EQ(OK, out.rv); 10862 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 10863 EXPECT_EQ("hello world", out.response_data); 10864 } 10865 10866 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) { 10867 const std::string https_url = "https://www.google.com/"; 10868 const std::string http_url = "http://www.google.com:443/"; 10869 10870 // SPDY GET for HTTPS URL 10871 scoped_ptr<SpdyFrame> req1( 10872 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 10873 10874 MockWrite writes1[] = { 10875 CreateMockWrite(*req1, 0), 10876 }; 10877 10878 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10879 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10880 MockRead reads1[] = { 10881 CreateMockRead(*resp1, 1), 10882 CreateMockRead(*body1, 2), 10883 MockRead(ASYNC, ERR_IO_PENDING, 3) 10884 }; 10885 10886 DelayedSocketData data1( 10887 1, reads1, arraysize(reads1), 10888 writes1, arraysize(writes1)); 10889 MockConnect connect_data1(ASYNC, OK); 10890 data1.set_connect_data(connect_data1); 10891 10892 // HTTP GET for the HTTP URL 10893 MockWrite writes2[] = { 10894 MockWrite(ASYNC, 4, 10895 "GET / HTTP/1.1\r\n" 10896 "Host: www.google.com:443\r\n" 10897 "Connection: keep-alive\r\n\r\n"), 10898 }; 10899 10900 MockRead reads2[] = { 10901 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 10902 MockRead(ASYNC, 6, "hello"), 10903 MockRead(ASYNC, 7, OK), 10904 }; 10905 10906 DelayedSocketData data2( 10907 1, reads2, arraysize(reads2), 10908 writes2, arraysize(writes2)); 10909 10910 SSLSocketDataProvider ssl(ASYNC, OK); 10911 ssl.SetNextProto(GetParam()); 10912 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10913 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10914 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10915 10916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10917 10918 // Start the first transaction to set up the SpdySession 10919 HttpRequestInfo request1; 10920 request1.method = "GET"; 10921 request1.url = GURL(https_url); 10922 request1.load_flags = 0; 10923 HttpNetworkTransaction trans1(LOWEST, session.get()); 10924 TestCompletionCallback callback1; 10925 EXPECT_EQ(ERR_IO_PENDING, 10926 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 10927 base::MessageLoop::current()->RunUntilIdle(); 10928 10929 EXPECT_EQ(OK, callback1.WaitForResult()); 10930 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 10931 10932 // Now, start the HTTP request 10933 HttpRequestInfo request2; 10934 request2.method = "GET"; 10935 request2.url = GURL(http_url); 10936 request2.load_flags = 0; 10937 HttpNetworkTransaction trans2(MEDIUM, session.get()); 10938 TestCompletionCallback callback2; 10939 EXPECT_EQ(ERR_IO_PENDING, 10940 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 10941 base::MessageLoop::current()->RunUntilIdle(); 10942 10943 EXPECT_EQ(OK, callback2.WaitForResult()); 10944 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); 10945 } 10946 10947 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { 10948 const std::string https_url = "https://www.google.com/"; 10949 const std::string http_url = "http://www.google.com:443/"; 10950 10951 // SPDY GET for HTTPS URL (through CONNECT tunnel) 10952 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 10953 LOWEST)); 10954 scoped_ptr<SpdyFrame> req1( 10955 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 10956 10957 // SPDY GET for HTTP URL (through the proxy, but not the tunnel) 10958 scoped_ptr<SpdyFrame> wrapped_req1( 10959 spdy_util_.ConstructWrappedSpdyFrame(req1, 1)); 10960 const char* const headers[] = { 10961 spdy_util_.GetMethodKey(), "GET", 10962 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/", 10963 spdy_util_.GetHostKey(), "www.google.com:443", 10964 spdy_util_.GetSchemeKey(), "http", 10965 spdy_util_.GetVersionKey(), "HTTP/1.1" 10966 }; 10967 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame( 10968 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN, 10969 headers, arraysize(headers), 0)); 10970 10971 MockWrite writes1[] = { 10972 CreateMockWrite(*connect, 0), 10973 CreateMockWrite(*wrapped_req1, 2), 10974 CreateMockWrite(*req2, 5), 10975 }; 10976 10977 scoped_ptr<SpdyFrame> conn_resp( 10978 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10979 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10980 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10981 scoped_ptr<SpdyFrame> wrapped_resp1( 10982 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1)); 10983 scoped_ptr<SpdyFrame> wrapped_body1( 10984 spdy_util_.ConstructWrappedSpdyFrame(body1, 1)); 10985 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 10986 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 10987 MockRead reads1[] = { 10988 CreateMockRead(*conn_resp, 1), 10989 CreateMockRead(*wrapped_resp1, 3), 10990 CreateMockRead(*wrapped_body1, 4), 10991 CreateMockRead(*resp2, 6), 10992 CreateMockRead(*body2, 7), 10993 MockRead(ASYNC, ERR_IO_PENDING, 8) 10994 }; 10995 10996 DeterministicSocketData data1(reads1, arraysize(reads1), 10997 writes1, arraysize(writes1)); 10998 MockConnect connect_data1(ASYNC, OK); 10999 data1.set_connect_data(connect_data1); 11000 11001 session_deps_.proxy_service.reset( 11002 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 11003 CapturingNetLog log; 11004 session_deps_.net_log = &log; 11005 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy 11006 ssl1.SetNextProto(GetParam()); 11007 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11008 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server 11009 ssl2.SetNextProto(GetParam()); 11010 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11011 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1); 11012 11013 scoped_refptr<HttpNetworkSession> session( 11014 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11015 11016 // Start the first transaction to set up the SpdySession 11017 HttpRequestInfo request1; 11018 request1.method = "GET"; 11019 request1.url = GURL(https_url); 11020 request1.load_flags = 0; 11021 HttpNetworkTransaction trans1(LOWEST, session.get()); 11022 TestCompletionCallback callback1; 11023 EXPECT_EQ(ERR_IO_PENDING, 11024 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11025 base::MessageLoop::current()->RunUntilIdle(); 11026 data1.RunFor(4); 11027 11028 EXPECT_EQ(OK, callback1.WaitForResult()); 11029 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11030 11031 LoadTimingInfo load_timing_info1; 11032 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1)); 11033 TestLoadTimingNotReusedWithPac(load_timing_info1, 11034 CONNECT_TIMING_HAS_SSL_TIMES); 11035 11036 // Now, start the HTTP request 11037 HttpRequestInfo request2; 11038 request2.method = "GET"; 11039 request2.url = GURL(http_url); 11040 request2.load_flags = 0; 11041 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11042 TestCompletionCallback callback2; 11043 EXPECT_EQ(ERR_IO_PENDING, 11044 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11045 base::MessageLoop::current()->RunUntilIdle(); 11046 data1.RunFor(3); 11047 11048 EXPECT_EQ(OK, callback2.WaitForResult()); 11049 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11050 11051 LoadTimingInfo load_timing_info2; 11052 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2)); 11053 // The established SPDY sessions is considered reused by the HTTP request. 11054 TestLoadTimingReusedWithPac(load_timing_info2); 11055 // HTTP requests over a SPDY session should have a different connection 11056 // socket_log_id than requests over a tunnel. 11057 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 11058 } 11059 11060 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) { 11061 HttpStreamFactory::set_force_spdy_always(true); 11062 const std::string https_url = "https://www.google.com/"; 11063 const std::string http_url = "http://www.google.com:443/"; 11064 11065 // SPDY GET for HTTPS URL 11066 scoped_ptr<SpdyFrame> req1( 11067 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 11068 // SPDY GET for the HTTP URL 11069 scoped_ptr<SpdyFrame> req2( 11070 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM)); 11071 11072 MockWrite writes[] = { 11073 CreateMockWrite(*req1, 1), 11074 CreateMockWrite(*req2, 4), 11075 }; 11076 11077 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11078 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11079 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11080 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 11081 MockRead reads[] = { 11082 CreateMockRead(*resp1, 2), 11083 CreateMockRead(*body1, 3), 11084 CreateMockRead(*resp2, 5), 11085 CreateMockRead(*body2, 6), 11086 MockRead(ASYNC, ERR_IO_PENDING, 7) 11087 }; 11088 11089 OrderedSocketData data(reads, arraysize(reads), 11090 writes, arraysize(writes)); 11091 11092 SSLSocketDataProvider ssl(ASYNC, OK); 11093 ssl.SetNextProto(GetParam()); 11094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11095 session_deps_.socket_factory->AddSocketDataProvider(&data); 11096 11097 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11098 11099 // Start the first transaction to set up the SpdySession 11100 HttpRequestInfo request1; 11101 request1.method = "GET"; 11102 request1.url = GURL(https_url); 11103 request1.load_flags = 0; 11104 HttpNetworkTransaction trans1(LOWEST, session.get()); 11105 TestCompletionCallback callback1; 11106 EXPECT_EQ(ERR_IO_PENDING, 11107 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11108 base::MessageLoop::current()->RunUntilIdle(); 11109 11110 EXPECT_EQ(OK, callback1.WaitForResult()); 11111 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11112 11113 // Now, start the HTTP request 11114 HttpRequestInfo request2; 11115 request2.method = "GET"; 11116 request2.url = GURL(http_url); 11117 request2.load_flags = 0; 11118 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11119 TestCompletionCallback callback2; 11120 EXPECT_EQ(ERR_IO_PENDING, 11121 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11122 base::MessageLoop::current()->RunUntilIdle(); 11123 11124 EXPECT_EQ(OK, callback2.WaitForResult()); 11125 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11126 } 11127 11128 // Test that in the case where we have a SPDY session to a SPDY proxy 11129 // that we do not pool other origins that resolve to the same IP when 11130 // the certificate does not match the new origin. 11131 // http://crbug.com/134690 11132 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) { 11133 const std::string url1 = "http://www.google.com/"; 11134 const std::string url2 = "https://mail.google.com/"; 11135 const std::string ip_addr = "1.2.3.4"; 11136 11137 // SPDY GET for HTTP URL (through SPDY proxy) 11138 scoped_ptr<SpdyHeaderBlock> headers( 11139 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/")); 11140 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame( 11141 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0)); 11142 11143 MockWrite writes1[] = { 11144 CreateMockWrite(*req1, 0), 11145 }; 11146 11147 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11148 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11149 MockRead reads1[] = { 11150 CreateMockRead(*resp1, 1), 11151 CreateMockRead(*body1, 2), 11152 MockRead(ASYNC, OK, 3) // EOF 11153 }; 11154 11155 scoped_ptr<DeterministicSocketData> data1( 11156 new DeterministicSocketData(reads1, arraysize(reads1), 11157 writes1, arraysize(writes1))); 11158 IPAddressNumber ip; 11159 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip)); 11160 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11161 MockConnect connect_data1(ASYNC, OK, peer_addr); 11162 data1->set_connect_data(connect_data1); 11163 11164 // SPDY GET for HTTPS URL (direct) 11165 scoped_ptr<SpdyFrame> req2( 11166 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM)); 11167 11168 MockWrite writes2[] = { 11169 CreateMockWrite(*req2, 0), 11170 }; 11171 11172 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11173 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11174 MockRead reads2[] = { 11175 CreateMockRead(*resp2, 1), 11176 CreateMockRead(*body2, 2), 11177 MockRead(ASYNC, OK, 3) // EOF 11178 }; 11179 11180 scoped_ptr<DeterministicSocketData> data2( 11181 new DeterministicSocketData(reads2, arraysize(reads2), 11182 writes2, arraysize(writes2))); 11183 MockConnect connect_data2(ASYNC, OK); 11184 data2->set_connect_data(connect_data2); 11185 11186 // Set up a proxy config that sends HTTP requests to a proxy, and 11187 // all others direct. 11188 ProxyConfig proxy_config; 11189 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443"); 11190 CapturingProxyResolver* capturing_proxy_resolver = 11191 new CapturingProxyResolver(); 11192 session_deps_.proxy_service.reset(new ProxyService( 11193 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver, 11194 NULL)); 11195 11196 // Load a valid cert. Note, that this does not need to 11197 // be valid for proxy because the MockSSLClientSocket does 11198 // not actually verify it. But SpdySession will use this 11199 // to see if it is valid for the new origin 11200 base::FilePath certs_dir = GetTestCertsDirectory(); 11201 scoped_refptr<X509Certificate> server_cert( 11202 ImportCertFromFile(certs_dir, "ok_cert.pem")); 11203 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); 11204 11205 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy 11206 ssl1.SetNextProto(GetParam()); 11207 ssl1.cert = server_cert; 11208 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11209 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11210 data1.get()); 11211 11212 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server 11213 ssl2.SetNextProto(GetParam()); 11214 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11215 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11216 data2.get()); 11217 11218 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 11219 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr); 11220 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr); 11221 11222 scoped_refptr<HttpNetworkSession> session( 11223 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11224 11225 // Start the first transaction to set up the SpdySession 11226 HttpRequestInfo request1; 11227 request1.method = "GET"; 11228 request1.url = GURL(url1); 11229 request1.load_flags = 0; 11230 HttpNetworkTransaction trans1(LOWEST, session.get()); 11231 TestCompletionCallback callback1; 11232 ASSERT_EQ(ERR_IO_PENDING, 11233 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11234 data1->RunFor(3); 11235 11236 ASSERT_TRUE(callback1.have_result()); 11237 EXPECT_EQ(OK, callback1.WaitForResult()); 11238 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11239 11240 // Now, start the HTTP request 11241 HttpRequestInfo request2; 11242 request2.method = "GET"; 11243 request2.url = GURL(url2); 11244 request2.load_flags = 0; 11245 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11246 TestCompletionCallback callback2; 11247 EXPECT_EQ(ERR_IO_PENDING, 11248 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11249 base::MessageLoop::current()->RunUntilIdle(); 11250 data2->RunFor(3); 11251 11252 ASSERT_TRUE(callback2.have_result()); 11253 EXPECT_EQ(OK, callback2.WaitForResult()); 11254 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11255 } 11256 11257 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED 11258 // error) in SPDY session, removes the socket from pool and closes the SPDY 11259 // session. Verify that new url's from the same HttpNetworkSession (and a new 11260 // SpdySession) do work. http://crbug.com/224701 11261 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) { 11262 const std::string https_url = "https://www.google.com/"; 11263 11264 MockRead reads1[] = { 11265 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0) 11266 }; 11267 11268 scoped_ptr<DeterministicSocketData> data1( 11269 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0)); 11270 data1->SetStop(1); 11271 11272 scoped_ptr<SpdyFrame> req2( 11273 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM)); 11274 MockWrite writes2[] = { 11275 CreateMockWrite(*req2, 0), 11276 }; 11277 11278 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11279 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11280 MockRead reads2[] = { 11281 CreateMockRead(*resp2, 1), 11282 CreateMockRead(*body2, 2), 11283 MockRead(ASYNC, OK, 3) // EOF 11284 }; 11285 11286 scoped_ptr<DeterministicSocketData> data2( 11287 new DeterministicSocketData(reads2, arraysize(reads2), 11288 writes2, arraysize(writes2))); 11289 11290 SSLSocketDataProvider ssl1(ASYNC, OK); 11291 ssl1.SetNextProto(GetParam()); 11292 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11293 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11294 data1.get()); 11295 11296 SSLSocketDataProvider ssl2(ASYNC, OK); 11297 ssl2.SetNextProto(GetParam()); 11298 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11299 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11300 data2.get()); 11301 11302 scoped_refptr<HttpNetworkSession> session( 11303 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11304 11305 // Start the first transaction to set up the SpdySession and verify that 11306 // connection was closed. 11307 HttpRequestInfo request1; 11308 request1.method = "GET"; 11309 request1.url = GURL(https_url); 11310 request1.load_flags = 0; 11311 HttpNetworkTransaction trans1(MEDIUM, session.get()); 11312 TestCompletionCallback callback1; 11313 EXPECT_EQ(ERR_IO_PENDING, 11314 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11315 base::MessageLoop::current()->RunUntilIdle(); 11316 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult()); 11317 11318 // Now, start the second request and make sure it succeeds. 11319 HttpRequestInfo request2; 11320 request2.method = "GET"; 11321 request2.url = GURL(https_url); 11322 request2.load_flags = 0; 11323 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11324 TestCompletionCallback callback2; 11325 EXPECT_EQ(ERR_IO_PENDING, 11326 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11327 base::MessageLoop::current()->RunUntilIdle(); 11328 data2->RunFor(3); 11329 11330 ASSERT_TRUE(callback2.have_result()); 11331 EXPECT_EQ(OK, callback2.WaitForResult()); 11332 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11333 } 11334 11335 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) { 11336 HttpStreamFactory::SetNextProtos(SpdyNextProtos()); 11337 ClientSocketPoolManager::set_max_sockets_per_group( 11338 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 11339 ClientSocketPoolManager::set_max_sockets_per_pool( 11340 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 11341 11342 // Use two different hosts with different IPs so they don't get pooled. 11343 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1"); 11344 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2"); 11345 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11346 11347 SSLSocketDataProvider ssl1(ASYNC, OK); 11348 ssl1.SetNextProto(GetParam()); 11349 SSLSocketDataProvider ssl2(ASYNC, OK); 11350 ssl2.SetNextProto(GetParam()); 11351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); 11352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 11353 11354 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet( 11355 "https://www.a.com", false, 1, DEFAULT_PRIORITY)); 11356 MockWrite spdy1_writes[] = { 11357 CreateMockWrite(*host1_req, 1), 11358 }; 11359 scoped_ptr<SpdyFrame> host1_resp( 11360 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11361 scoped_ptr<SpdyFrame> host1_resp_body( 11362 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11363 MockRead spdy1_reads[] = { 11364 CreateMockRead(*host1_resp, 2), 11365 CreateMockRead(*host1_resp_body, 3), 11366 MockRead(ASYNC, ERR_IO_PENDING, 4), 11367 }; 11368 11369 scoped_ptr<OrderedSocketData> spdy1_data( 11370 new OrderedSocketData( 11371 spdy1_reads, arraysize(spdy1_reads), 11372 spdy1_writes, arraysize(spdy1_writes))); 11373 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get()); 11374 11375 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet( 11376 "https://www.b.com", false, 1, DEFAULT_PRIORITY)); 11377 MockWrite spdy2_writes[] = { 11378 CreateMockWrite(*host2_req, 1), 11379 }; 11380 scoped_ptr<SpdyFrame> host2_resp( 11381 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11382 scoped_ptr<SpdyFrame> host2_resp_body( 11383 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11384 MockRead spdy2_reads[] = { 11385 CreateMockRead(*host2_resp, 2), 11386 CreateMockRead(*host2_resp_body, 3), 11387 MockRead(ASYNC, ERR_IO_PENDING, 4), 11388 }; 11389 11390 scoped_ptr<OrderedSocketData> spdy2_data( 11391 new OrderedSocketData( 11392 spdy2_reads, arraysize(spdy2_reads), 11393 spdy2_writes, arraysize(spdy2_writes))); 11394 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get()); 11395 11396 MockWrite http_write[] = { 11397 MockWrite("GET / HTTP/1.1\r\n" 11398 "Host: www.a.com\r\n" 11399 "Connection: keep-alive\r\n\r\n"), 11400 }; 11401 11402 MockRead http_read[] = { 11403 MockRead("HTTP/1.1 200 OK\r\n"), 11404 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 11405 MockRead("Content-Length: 6\r\n\r\n"), 11406 MockRead("hello!"), 11407 }; 11408 StaticSocketDataProvider http_data(http_read, arraysize(http_read), 11409 http_write, arraysize(http_write)); 11410 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 11411 11412 HostPortPair host_port_pair_a("www.a.com", 443); 11413 SpdySessionKey spdy_session_key_a( 11414 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled); 11415 EXPECT_FALSE( 11416 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11417 11418 TestCompletionCallback callback; 11419 HttpRequestInfo request1; 11420 request1.method = "GET"; 11421 request1.url = GURL("https://www.a.com/"); 11422 request1.load_flags = 0; 11423 scoped_ptr<HttpNetworkTransaction> trans( 11424 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11425 11426 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 11427 EXPECT_EQ(ERR_IO_PENDING, rv); 11428 EXPECT_EQ(OK, callback.WaitForResult()); 11429 11430 const HttpResponseInfo* response = trans->GetResponseInfo(); 11431 ASSERT_TRUE(response != NULL); 11432 ASSERT_TRUE(response->headers.get() != NULL); 11433 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11434 EXPECT_TRUE(response->was_fetched_via_spdy); 11435 EXPECT_TRUE(response->was_npn_negotiated); 11436 11437 std::string response_data; 11438 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11439 EXPECT_EQ("hello!", response_data); 11440 trans.reset(); 11441 EXPECT_TRUE( 11442 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11443 11444 HostPortPair host_port_pair_b("www.b.com", 443); 11445 SpdySessionKey spdy_session_key_b( 11446 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled); 11447 EXPECT_FALSE( 11448 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11449 HttpRequestInfo request2; 11450 request2.method = "GET"; 11451 request2.url = GURL("https://www.b.com/"); 11452 request2.load_flags = 0; 11453 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11454 11455 rv = trans->Start(&request2, callback.callback(), BoundNetLog()); 11456 EXPECT_EQ(ERR_IO_PENDING, rv); 11457 EXPECT_EQ(OK, callback.WaitForResult()); 11458 11459 response = trans->GetResponseInfo(); 11460 ASSERT_TRUE(response != NULL); 11461 ASSERT_TRUE(response->headers.get() != NULL); 11462 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11463 EXPECT_TRUE(response->was_fetched_via_spdy); 11464 EXPECT_TRUE(response->was_npn_negotiated); 11465 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11466 EXPECT_EQ("hello!", response_data); 11467 EXPECT_FALSE( 11468 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11469 EXPECT_TRUE( 11470 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11471 11472 HostPortPair host_port_pair_a1("www.a.com", 80); 11473 SpdySessionKey spdy_session_key_a1( 11474 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled); 11475 EXPECT_FALSE( 11476 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1)); 11477 HttpRequestInfo request3; 11478 request3.method = "GET"; 11479 request3.url = GURL("http://www.a.com/"); 11480 request3.load_flags = 0; 11481 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11482 11483 rv = trans->Start(&request3, callback.callback(), BoundNetLog()); 11484 EXPECT_EQ(ERR_IO_PENDING, rv); 11485 EXPECT_EQ(OK, callback.WaitForResult()); 11486 11487 response = trans->GetResponseInfo(); 11488 ASSERT_TRUE(response != NULL); 11489 ASSERT_TRUE(response->headers.get() != NULL); 11490 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11491 EXPECT_FALSE(response->was_fetched_via_spdy); 11492 EXPECT_FALSE(response->was_npn_negotiated); 11493 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11494 EXPECT_EQ("hello!", response_data); 11495 EXPECT_FALSE( 11496 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11497 EXPECT_FALSE( 11498 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11499 } 11500 11501 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) { 11502 HttpRequestInfo request; 11503 request.method = "GET"; 11504 request.url = GURL("http://www.google.com/"); 11505 request.load_flags = 0; 11506 11507 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11508 scoped_ptr<HttpTransaction> trans( 11509 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11510 11511 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED); 11512 StaticSocketDataProvider data; 11513 data.set_connect_data(mock_connect); 11514 session_deps_.socket_factory->AddSocketDataProvider(&data); 11515 11516 TestCompletionCallback callback; 11517 11518 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11519 EXPECT_EQ(ERR_IO_PENDING, rv); 11520 11521 rv = callback.WaitForResult(); 11522 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); 11523 11524 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11525 11526 // We don't care whether this succeeds or fails, but it shouldn't crash. 11527 HttpRequestHeaders request_headers; 11528 trans->GetFullRequestHeaders(&request_headers); 11529 } 11530 11531 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) { 11532 HttpRequestInfo request; 11533 request.method = "GET"; 11534 request.url = GURL("http://www.google.com/"); 11535 request.load_flags = 0; 11536 11537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11538 scoped_ptr<HttpTransaction> trans( 11539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11540 11541 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 11542 StaticSocketDataProvider data; 11543 data.set_connect_data(mock_connect); 11544 session_deps_.socket_factory->AddSocketDataProvider(&data); 11545 11546 TestCompletionCallback callback; 11547 11548 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11549 EXPECT_EQ(ERR_IO_PENDING, rv); 11550 11551 rv = callback.WaitForResult(); 11552 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); 11553 11554 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11555 11556 // We don't care whether this succeeds or fails, but it shouldn't crash. 11557 HttpRequestHeaders request_headers; 11558 trans->GetFullRequestHeaders(&request_headers); 11559 } 11560 11561 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) { 11562 HttpRequestInfo request; 11563 request.method = "GET"; 11564 request.url = GURL("http://www.google.com/"); 11565 request.load_flags = 0; 11566 11567 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11568 scoped_ptr<HttpTransaction> trans( 11569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11570 11571 MockWrite data_writes[] = { 11572 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 11573 }; 11574 MockRead data_reads[] = { 11575 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 11576 }; 11577 11578 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 11579 data_writes, arraysize(data_writes)); 11580 session_deps_.socket_factory->AddSocketDataProvider(&data); 11581 11582 TestCompletionCallback callback; 11583 11584 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11585 EXPECT_EQ(ERR_IO_PENDING, rv); 11586 11587 rv = callback.WaitForResult(); 11588 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 11589 11590 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11591 11592 HttpRequestHeaders request_headers; 11593 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 11594 EXPECT_TRUE(request_headers.HasHeader("Host")); 11595 } 11596 11597 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) { 11598 HttpRequestInfo request; 11599 request.method = "GET"; 11600 request.url = GURL("http://www.google.com/"); 11601 request.load_flags = 0; 11602 11603 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11604 scoped_ptr<HttpTransaction> trans( 11605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11606 11607 MockWrite data_writes[] = { 11608 MockWrite(ASYNC, ERR_CONNECTION_RESET), 11609 }; 11610 MockRead data_reads[] = { 11611 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 11612 }; 11613 11614 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 11615 data_writes, arraysize(data_writes)); 11616 session_deps_.socket_factory->AddSocketDataProvider(&data); 11617 11618 TestCompletionCallback callback; 11619 11620 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11621 EXPECT_EQ(ERR_IO_PENDING, rv); 11622 11623 rv = callback.WaitForResult(); 11624 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 11625 11626 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11627 11628 HttpRequestHeaders request_headers; 11629 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 11630 EXPECT_TRUE(request_headers.HasHeader("Host")); 11631 } 11632 11633 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) { 11634 HttpRequestInfo request; 11635 request.method = "GET"; 11636 request.url = GURL("http://www.google.com/"); 11637 request.load_flags = 0; 11638 11639 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11640 scoped_ptr<HttpTransaction> trans( 11641 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11642 11643 MockWrite data_writes[] = { 11644 MockWrite("GET / HTTP/1.1\r\n" 11645 "Host: www.google.com\r\n" 11646 "Connection: keep-alive\r\n\r\n"), 11647 }; 11648 MockRead data_reads[] = { 11649 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET), 11650 }; 11651 11652 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 11653 data_writes, arraysize(data_writes)); 11654 session_deps_.socket_factory->AddSocketDataProvider(&data); 11655 11656 TestCompletionCallback callback; 11657 11658 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11659 EXPECT_EQ(ERR_IO_PENDING, rv); 11660 11661 rv = callback.WaitForResult(); 11662 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 11663 11664 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11665 11666 HttpRequestHeaders request_headers; 11667 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 11668 EXPECT_TRUE(request_headers.HasHeader("Host")); 11669 } 11670 11671 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) { 11672 HttpRequestInfo request; 11673 request.method = "GET"; 11674 request.url = GURL("http://www.google.com/"); 11675 request.load_flags = 0; 11676 11677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11678 scoped_ptr<HttpTransaction> trans( 11679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11680 11681 MockWrite data_writes[] = { 11682 MockWrite("GET / HTTP/1.1\r\n" 11683 "Host: www.google.com\r\n" 11684 "Connection: keep-alive\r\n\r\n"), 11685 }; 11686 MockRead data_reads[] = { 11687 MockRead(ASYNC, ERR_CONNECTION_RESET), 11688 }; 11689 11690 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 11691 data_writes, arraysize(data_writes)); 11692 session_deps_.socket_factory->AddSocketDataProvider(&data); 11693 11694 TestCompletionCallback callback; 11695 11696 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11697 EXPECT_EQ(ERR_IO_PENDING, rv); 11698 11699 rv = callback.WaitForResult(); 11700 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 11701 11702 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11703 11704 HttpRequestHeaders request_headers; 11705 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 11706 EXPECT_TRUE(request_headers.HasHeader("Host")); 11707 } 11708 11709 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) { 11710 HttpRequestInfo request; 11711 request.method = "GET"; 11712 request.url = GURL("http://www.google.com/"); 11713 request.load_flags = 0; 11714 request.extra_headers.SetHeader("X-Foo", "bar"); 11715 11716 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11717 scoped_ptr<HttpTransaction> trans( 11718 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11719 11720 MockWrite data_writes[] = { 11721 MockWrite("GET / HTTP/1.1\r\n" 11722 "Host: www.google.com\r\n" 11723 "Connection: keep-alive\r\n" 11724 "X-Foo: bar\r\n\r\n"), 11725 }; 11726 MockRead data_reads[] = { 11727 MockRead("HTTP/1.1 200 OK\r\n" 11728 "Content-Length: 5\r\n\r\n" 11729 "hello"), 11730 MockRead(ASYNC, ERR_UNEXPECTED), 11731 }; 11732 11733 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 11734 data_writes, arraysize(data_writes)); 11735 session_deps_.socket_factory->AddSocketDataProvider(&data); 11736 11737 TestCompletionCallback callback; 11738 11739 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11740 EXPECT_EQ(ERR_IO_PENDING, rv); 11741 11742 rv = callback.WaitForResult(); 11743 EXPECT_EQ(OK, rv); 11744 11745 HttpRequestHeaders request_headers; 11746 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 11747 std::string foo; 11748 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo)); 11749 EXPECT_EQ("bar", foo); 11750 } 11751 11752 namespace { 11753 11754 // Fake HttpStreamBase that simply records calls to SetPriority(). 11755 class FakeStream : public HttpStreamBase, 11756 public base::SupportsWeakPtr<FakeStream> { 11757 public: 11758 explicit FakeStream(RequestPriority priority) : priority_(priority) {} 11759 virtual ~FakeStream() {} 11760 11761 RequestPriority priority() const { return priority_; } 11762 11763 virtual int InitializeStream(const HttpRequestInfo* request_info, 11764 RequestPriority priority, 11765 const BoundNetLog& net_log, 11766 const CompletionCallback& callback) OVERRIDE { 11767 return ERR_IO_PENDING; 11768 } 11769 11770 virtual int SendRequest(const HttpRequestHeaders& request_headers, 11771 HttpResponseInfo* response, 11772 const CompletionCallback& callback) OVERRIDE { 11773 ADD_FAILURE(); 11774 return ERR_UNEXPECTED; 11775 } 11776 11777 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE { 11778 ADD_FAILURE(); 11779 return ERR_UNEXPECTED; 11780 } 11781 11782 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE { 11783 ADD_FAILURE(); 11784 return NULL; 11785 } 11786 11787 virtual int ReadResponseBody(IOBuffer* buf, int buf_len, 11788 const CompletionCallback& callback) OVERRIDE { 11789 ADD_FAILURE(); 11790 return ERR_UNEXPECTED; 11791 } 11792 11793 virtual void Close(bool not_reusable) OVERRIDE {} 11794 11795 virtual bool IsResponseBodyComplete() const OVERRIDE { 11796 ADD_FAILURE(); 11797 return false; 11798 } 11799 11800 virtual bool CanFindEndOfResponse() const OVERRIDE { 11801 return false; 11802 } 11803 11804 virtual bool IsConnectionReused() const OVERRIDE { 11805 ADD_FAILURE(); 11806 return false; 11807 } 11808 11809 virtual void SetConnectionReused() OVERRIDE { 11810 ADD_FAILURE(); 11811 } 11812 11813 virtual bool IsConnectionReusable() const OVERRIDE { 11814 ADD_FAILURE(); 11815 return false; 11816 } 11817 11818 virtual int64 GetTotalReceivedBytes() const OVERRIDE { 11819 ADD_FAILURE(); 11820 return 0; 11821 } 11822 11823 virtual bool GetLoadTimingInfo( 11824 LoadTimingInfo* load_timing_info) const OVERRIDE { 11825 ADD_FAILURE(); 11826 return false; 11827 } 11828 11829 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { 11830 ADD_FAILURE(); 11831 } 11832 11833 virtual void GetSSLCertRequestInfo( 11834 SSLCertRequestInfo* cert_request_info) OVERRIDE { 11835 ADD_FAILURE(); 11836 } 11837 11838 virtual bool IsSpdyHttpStream() const OVERRIDE { 11839 ADD_FAILURE(); 11840 return false; 11841 } 11842 11843 virtual void Drain(HttpNetworkSession* session) OVERRIDE { 11844 ADD_FAILURE(); 11845 } 11846 11847 virtual void SetPriority(RequestPriority priority) OVERRIDE { 11848 priority_ = priority; 11849 } 11850 11851 private: 11852 RequestPriority priority_; 11853 11854 DISALLOW_COPY_AND_ASSIGN(FakeStream); 11855 }; 11856 11857 // Fake HttpStreamRequest that simply records calls to SetPriority() 11858 // and vends FakeStreams with its current priority. 11859 class FakeStreamRequest : public HttpStreamRequest, 11860 public base::SupportsWeakPtr<FakeStreamRequest> { 11861 public: 11862 FakeStreamRequest(RequestPriority priority, 11863 HttpStreamRequest::Delegate* delegate) 11864 : priority_(priority), 11865 delegate_(delegate), 11866 websocket_stream_create_helper_(NULL) {} 11867 11868 FakeStreamRequest(RequestPriority priority, 11869 HttpStreamRequest::Delegate* delegate, 11870 WebSocketHandshakeStreamBase::CreateHelper* create_helper) 11871 : priority_(priority), 11872 delegate_(delegate), 11873 websocket_stream_create_helper_(create_helper) {} 11874 11875 virtual ~FakeStreamRequest() {} 11876 11877 RequestPriority priority() const { return priority_; } 11878 11879 const WebSocketHandshakeStreamBase::CreateHelper* 11880 websocket_stream_create_helper() const { 11881 return websocket_stream_create_helper_; 11882 } 11883 11884 // Create a new FakeStream and pass it to the request's 11885 // delegate. Returns a weak pointer to the FakeStream. 11886 base::WeakPtr<FakeStream> FinishStreamRequest() { 11887 FakeStream* fake_stream = new FakeStream(priority_); 11888 // Do this before calling OnStreamReady() as OnStreamReady() may 11889 // immediately delete |fake_stream|. 11890 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr(); 11891 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream); 11892 return weak_stream; 11893 } 11894 11895 virtual int RestartTunnelWithProxyAuth( 11896 const AuthCredentials& credentials) OVERRIDE { 11897 ADD_FAILURE(); 11898 return ERR_UNEXPECTED; 11899 } 11900 11901 virtual LoadState GetLoadState() const OVERRIDE { 11902 ADD_FAILURE(); 11903 return LoadState(); 11904 } 11905 11906 virtual void SetPriority(RequestPriority priority) OVERRIDE { 11907 priority_ = priority; 11908 } 11909 11910 virtual bool was_npn_negotiated() const OVERRIDE { 11911 return false; 11912 } 11913 11914 virtual NextProto protocol_negotiated() const OVERRIDE { 11915 return kProtoUnknown; 11916 } 11917 11918 virtual bool using_spdy() const OVERRIDE { 11919 return false; 11920 } 11921 11922 private: 11923 RequestPriority priority_; 11924 HttpStreamRequest::Delegate* const delegate_; 11925 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_; 11926 11927 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest); 11928 }; 11929 11930 // Fake HttpStreamFactory that vends FakeStreamRequests. 11931 class FakeStreamFactory : public HttpStreamFactory { 11932 public: 11933 FakeStreamFactory() {} 11934 virtual ~FakeStreamFactory() {} 11935 11936 // Returns a WeakPtr<> to the last HttpStreamRequest returned by 11937 // RequestStream() (which may be NULL if it was destroyed already). 11938 base::WeakPtr<FakeStreamRequest> last_stream_request() { 11939 return last_stream_request_; 11940 } 11941 11942 virtual HttpStreamRequest* RequestStream( 11943 const HttpRequestInfo& info, 11944 RequestPriority priority, 11945 const SSLConfig& server_ssl_config, 11946 const SSLConfig& proxy_ssl_config, 11947 HttpStreamRequest::Delegate* delegate, 11948 const BoundNetLog& net_log) OVERRIDE { 11949 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate); 11950 last_stream_request_ = fake_request->AsWeakPtr(); 11951 return fake_request; 11952 } 11953 11954 virtual HttpStreamRequest* RequestWebSocketHandshakeStream( 11955 const HttpRequestInfo& info, 11956 RequestPriority priority, 11957 const SSLConfig& server_ssl_config, 11958 const SSLConfig& proxy_ssl_config, 11959 HttpStreamRequest::Delegate* delegate, 11960 WebSocketHandshakeStreamBase::CreateHelper* create_helper, 11961 const BoundNetLog& net_log) OVERRIDE { 11962 FakeStreamRequest* fake_request = 11963 new FakeStreamRequest(priority, delegate, create_helper); 11964 last_stream_request_ = fake_request->AsWeakPtr(); 11965 return fake_request; 11966 } 11967 11968 virtual void PreconnectStreams(int num_streams, 11969 const HttpRequestInfo& info, 11970 RequestPriority priority, 11971 const SSLConfig& server_ssl_config, 11972 const SSLConfig& proxy_ssl_config) OVERRIDE { 11973 ADD_FAILURE(); 11974 } 11975 11976 virtual base::Value* PipelineInfoToValue() const OVERRIDE { 11977 ADD_FAILURE(); 11978 return NULL; 11979 } 11980 11981 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE { 11982 ADD_FAILURE(); 11983 return NULL; 11984 } 11985 11986 private: 11987 base::WeakPtr<FakeStreamRequest> last_stream_request_; 11988 11989 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory); 11990 }; 11991 11992 // TODO(yhirano): Split this class out into a net/websockets file, if it is 11993 // worth doing. 11994 class FakeWebSocketStreamCreateHelper : 11995 public WebSocketHandshakeStreamBase::CreateHelper { 11996 public: 11997 virtual WebSocketHandshakeStreamBase* CreateBasicStream( 11998 scoped_ptr<ClientSocketHandle> connection, 11999 bool using_proxy) OVERRIDE { 12000 NOTREACHED(); 12001 return NULL; 12002 } 12003 12004 virtual WebSocketHandshakeStreamBase* CreateSpdyStream( 12005 const base::WeakPtr<SpdySession>& session, 12006 bool use_relative_url) OVERRIDE { 12007 NOTREACHED(); 12008 return NULL; 12009 }; 12010 12011 virtual ~FakeWebSocketStreamCreateHelper() {} 12012 12013 virtual scoped_ptr<WebSocketStream> Upgrade() { 12014 NOTREACHED(); 12015 return scoped_ptr<WebSocketStream>(); 12016 } 12017 }; 12018 12019 } // namespace 12020 12021 // Make sure that HttpNetworkTransaction passes on its priority to its 12022 // stream request on start. 12023 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) { 12024 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12025 HttpNetworkSessionPeer peer(session); 12026 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12027 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12028 12029 HttpNetworkTransaction trans(LOW, session); 12030 12031 ASSERT_TRUE(fake_factory->last_stream_request() == NULL); 12032 12033 HttpRequestInfo request; 12034 TestCompletionCallback callback; 12035 EXPECT_EQ(ERR_IO_PENDING, 12036 trans.Start(&request, callback.callback(), BoundNetLog())); 12037 12038 base::WeakPtr<FakeStreamRequest> fake_request = 12039 fake_factory->last_stream_request(); 12040 ASSERT_TRUE(fake_request != NULL); 12041 EXPECT_EQ(LOW, fake_request->priority()); 12042 } 12043 12044 // Make sure that HttpNetworkTransaction passes on its priority 12045 // updates to its stream request. 12046 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) { 12047 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12048 HttpNetworkSessionPeer peer(session); 12049 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12050 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12051 12052 HttpNetworkTransaction trans(LOW, session); 12053 12054 HttpRequestInfo request; 12055 TestCompletionCallback callback; 12056 EXPECT_EQ(ERR_IO_PENDING, 12057 trans.Start(&request, callback.callback(), BoundNetLog())); 12058 12059 base::WeakPtr<FakeStreamRequest> fake_request = 12060 fake_factory->last_stream_request(); 12061 ASSERT_TRUE(fake_request != NULL); 12062 EXPECT_EQ(LOW, fake_request->priority()); 12063 12064 trans.SetPriority(LOWEST); 12065 ASSERT_TRUE(fake_request != NULL); 12066 EXPECT_EQ(LOWEST, fake_request->priority()); 12067 } 12068 12069 // Make sure that HttpNetworkTransaction passes on its priority 12070 // updates to its stream. 12071 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) { 12072 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12073 HttpNetworkSessionPeer peer(session); 12074 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12075 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12076 12077 HttpNetworkTransaction trans(LOW, session); 12078 12079 HttpRequestInfo request; 12080 TestCompletionCallback callback; 12081 EXPECT_EQ(ERR_IO_PENDING, 12082 trans.Start(&request, callback.callback(), BoundNetLog())); 12083 12084 base::WeakPtr<FakeStreamRequest> fake_request = 12085 fake_factory->last_stream_request(); 12086 ASSERT_TRUE(fake_request != NULL); 12087 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest(); 12088 ASSERT_TRUE(fake_stream != NULL); 12089 EXPECT_EQ(LOW, fake_stream->priority()); 12090 12091 trans.SetPriority(LOWEST); 12092 EXPECT_EQ(LOWEST, fake_stream->priority()); 12093 } 12094 12095 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) { 12096 // The same logic needs to be tested for both ws: and wss: schemes, but this 12097 // test is already parameterised on NextProto, so it uses a loop to verify 12098 // that the different schemes work. 12099 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"}; 12100 for (size_t i = 0; i < arraysize(test_cases); ++i) { 12101 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12102 HttpNetworkSessionPeer peer(session); 12103 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12104 FakeWebSocketStreamCreateHelper websocket_stream_create_helper; 12105 peer.SetHttpStreamFactoryForWebSocket( 12106 scoped_ptr<HttpStreamFactory>(fake_factory)); 12107 12108 HttpNetworkTransaction trans(LOW, session); 12109 trans.SetWebSocketHandshakeStreamCreateHelper( 12110 &websocket_stream_create_helper); 12111 12112 HttpRequestInfo request; 12113 TestCompletionCallback callback; 12114 request.method = "GET"; 12115 request.url = GURL(test_cases[i]); 12116 12117 EXPECT_EQ(ERR_IO_PENDING, 12118 trans.Start(&request, callback.callback(), BoundNetLog())); 12119 12120 base::WeakPtr<FakeStreamRequest> fake_request = 12121 fake_factory->last_stream_request(); 12122 ASSERT_TRUE(fake_request != NULL); 12123 EXPECT_EQ(&websocket_stream_create_helper, 12124 fake_request->websocket_stream_create_helper()); 12125 } 12126 } 12127 12128 // Tests that when a used socket is returned to the SSL socket pool, it's closed 12129 // if the transport socket pool is stalled on the global socket limit. 12130 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) { 12131 ClientSocketPoolManager::set_max_sockets_per_group( 12132 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12133 ClientSocketPoolManager::set_max_sockets_per_pool( 12134 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12135 12136 // Set up SSL request. 12137 12138 HttpRequestInfo ssl_request; 12139 ssl_request.method = "GET"; 12140 ssl_request.url = GURL("https://www.google.com/"); 12141 12142 MockWrite ssl_writes[] = { 12143 MockWrite("GET / HTTP/1.1\r\n" 12144 "Host: www.google.com\r\n" 12145 "Connection: keep-alive\r\n\r\n"), 12146 }; 12147 MockRead ssl_reads[] = { 12148 MockRead("HTTP/1.1 200 OK\r\n"), 12149 MockRead("Content-Length: 11\r\n\r\n"), 12150 MockRead("hello world"), 12151 MockRead(SYNCHRONOUS, OK), 12152 }; 12153 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads), 12154 ssl_writes, arraysize(ssl_writes)); 12155 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data); 12156 12157 SSLSocketDataProvider ssl(ASYNC, OK); 12158 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 12159 12160 // Set up HTTP request. 12161 12162 HttpRequestInfo http_request; 12163 http_request.method = "GET"; 12164 http_request.url = GURL("http://www.google.com/"); 12165 12166 MockWrite http_writes[] = { 12167 MockWrite("GET / HTTP/1.1\r\n" 12168 "Host: www.google.com\r\n" 12169 "Connection: keep-alive\r\n\r\n"), 12170 }; 12171 MockRead http_reads[] = { 12172 MockRead("HTTP/1.1 200 OK\r\n"), 12173 MockRead("Content-Length: 7\r\n\r\n"), 12174 MockRead("falafel"), 12175 MockRead(SYNCHRONOUS, OK), 12176 }; 12177 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 12178 http_writes, arraysize(http_writes)); 12179 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 12180 12181 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12182 12183 // Start the SSL request. 12184 TestCompletionCallback ssl_callback; 12185 scoped_ptr<HttpTransaction> ssl_trans( 12186 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12187 ASSERT_EQ(ERR_IO_PENDING, 12188 ssl_trans->Start(&ssl_request, ssl_callback.callback(), 12189 BoundNetLog())); 12190 12191 // Start the HTTP request. Pool should stall. 12192 TestCompletionCallback http_callback; 12193 scoped_ptr<HttpTransaction> http_trans( 12194 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12195 ASSERT_EQ(ERR_IO_PENDING, 12196 http_trans->Start(&http_request, http_callback.callback(), 12197 BoundNetLog())); 12198 EXPECT_TRUE(IsTransportSocketPoolStalled(session)); 12199 12200 // Wait for response from SSL request. 12201 ASSERT_EQ(OK, ssl_callback.WaitForResult()); 12202 std::string response_data; 12203 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data)); 12204 EXPECT_EQ("hello world", response_data); 12205 12206 // The SSL socket should automatically be closed, so the HTTP request can 12207 // start. 12208 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session)); 12209 ASSERT_FALSE(IsTransportSocketPoolStalled(session)); 12210 12211 // The HTTP request can now complete. 12212 ASSERT_EQ(OK, http_callback.WaitForResult()); 12213 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data)); 12214 EXPECT_EQ("falafel", response_data); 12215 12216 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session)); 12217 } 12218 12219 // Tests that when a SSL connection is established but there's no corresponding 12220 // request that needs it, the new socket is closed if the transport socket pool 12221 // is stalled on the global socket limit. 12222 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) { 12223 ClientSocketPoolManager::set_max_sockets_per_group( 12224 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12225 ClientSocketPoolManager::set_max_sockets_per_pool( 12226 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12227 12228 // Set up an ssl request. 12229 12230 HttpRequestInfo ssl_request; 12231 ssl_request.method = "GET"; 12232 ssl_request.url = GURL("https://www.foopy.com/"); 12233 12234 // No data will be sent on the SSL socket. 12235 StaticSocketDataProvider ssl_data; 12236 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data); 12237 12238 SSLSocketDataProvider ssl(ASYNC, OK); 12239 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 12240 12241 // Set up HTTP request. 12242 12243 HttpRequestInfo http_request; 12244 http_request.method = "GET"; 12245 http_request.url = GURL("http://www.google.com/"); 12246 12247 MockWrite http_writes[] = { 12248 MockWrite("GET / HTTP/1.1\r\n" 12249 "Host: www.google.com\r\n" 12250 "Connection: keep-alive\r\n\r\n"), 12251 }; 12252 MockRead http_reads[] = { 12253 MockRead("HTTP/1.1 200 OK\r\n"), 12254 MockRead("Content-Length: 7\r\n\r\n"), 12255 MockRead("falafel"), 12256 MockRead(SYNCHRONOUS, OK), 12257 }; 12258 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 12259 http_writes, arraysize(http_writes)); 12260 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 12261 12262 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12263 12264 // Preconnect an SSL socket. A preconnect is needed because connect jobs are 12265 // cancelled when a normal transaction is cancelled. 12266 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory(); 12267 net::SSLConfig ssl_config; 12268 session->ssl_config_service()->GetSSLConfig(&ssl_config); 12269 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY, 12270 ssl_config, ssl_config); 12271 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session)); 12272 12273 // Start the HTTP request. Pool should stall. 12274 TestCompletionCallback http_callback; 12275 scoped_ptr<HttpTransaction> http_trans( 12276 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12277 ASSERT_EQ(ERR_IO_PENDING, 12278 http_trans->Start(&http_request, http_callback.callback(), 12279 BoundNetLog())); 12280 EXPECT_TRUE(IsTransportSocketPoolStalled(session)); 12281 12282 // The SSL connection will automatically be closed once the connection is 12283 // established, to let the HTTP request start. 12284 ASSERT_EQ(OK, http_callback.WaitForResult()); 12285 std::string response_data; 12286 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data)); 12287 EXPECT_EQ("falafel", response_data); 12288 12289 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session)); 12290 } 12291 12292 } // namespace net 12293