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/run_loop.h" 20 #include "base/strings/string_util.h" 21 #include "base/strings/utf_string_conversions.h" 22 #include "base/test/test_file_util.h" 23 #include "net/base/auth.h" 24 #include "net/base/capturing_net_log.h" 25 #include "net/base/completion_callback.h" 26 #include "net/base/load_timing_info.h" 27 #include "net/base/load_timing_info_test_util.h" 28 #include "net/base/net_log.h" 29 #include "net/base/net_log_unittest.h" 30 #include "net/base/request_priority.h" 31 #include "net/base/test_completion_callback.h" 32 #include "net/base/test_data_directory.h" 33 #include "net/base/upload_bytes_element_reader.h" 34 #include "net/base/upload_data_stream.h" 35 #include "net/base/upload_file_element_reader.h" 36 #include "net/cert/mock_cert_verifier.h" 37 #include "net/dns/host_cache.h" 38 #include "net/dns/mock_host_resolver.h" 39 #include "net/http/http_auth_challenge_tokenizer.h" 40 #include "net/http/http_auth_handler_digest.h" 41 #include "net/http/http_auth_handler_mock.h" 42 #include "net/http/http_auth_handler_ntlm.h" 43 #include "net/http/http_basic_stream.h" 44 #include "net/http/http_network_session.h" 45 #include "net/http/http_network_session_peer.h" 46 #include "net/http/http_server_properties_impl.h" 47 #include "net/http/http_stream.h" 48 #include "net/http/http_stream_factory.h" 49 #include "net/http/http_transaction_test_util.h" 50 #include "net/proxy/proxy_config_service_fixed.h" 51 #include "net/proxy/proxy_info.h" 52 #include "net/proxy/proxy_resolver.h" 53 #include "net/proxy/proxy_service.h" 54 #include "net/socket/client_socket_factory.h" 55 #include "net/socket/client_socket_pool_manager.h" 56 #include "net/socket/mock_client_socket_pool_manager.h" 57 #include "net/socket/next_proto.h" 58 #include "net/socket/socket_test_util.h" 59 #include "net/socket/ssl_client_socket.h" 60 #include "net/spdy/spdy_framer.h" 61 #include "net/spdy/spdy_session.h" 62 #include "net/spdy/spdy_session_pool.h" 63 #include "net/spdy/spdy_test_util_common.h" 64 #include "net/ssl/ssl_cert_request_info.h" 65 #include "net/ssl/ssl_config_service.h" 66 #include "net/ssl/ssl_config_service_defaults.h" 67 #include "net/ssl/ssl_info.h" 68 #include "net/test/cert_test_util.h" 69 #include "net/websockets/websocket_handshake_stream_base.h" 70 #include "testing/gtest/include/gtest/gtest.h" 71 #include "testing/platform_test.h" 72 #include "url/gurl.h" 73 74 using base::ASCIIToUTF16; 75 76 //----------------------------------------------------------------------------- 77 78 namespace { 79 80 const base::string16 kBar(ASCIIToUTF16("bar")); 81 const base::string16 kBar2(ASCIIToUTF16("bar2")); 82 const base::string16 kBar3(ASCIIToUTF16("bar3")); 83 const base::string16 kBaz(ASCIIToUTF16("baz")); 84 const base::string16 kFirst(ASCIIToUTF16("first")); 85 const base::string16 kFoo(ASCIIToUTF16("foo")); 86 const base::string16 kFoo2(ASCIIToUTF16("foo2")); 87 const base::string16 kFoo3(ASCIIToUTF16("foo3")); 88 const base::string16 kFou(ASCIIToUTF16("fou")); 89 const base::string16 kSecond(ASCIIToUTF16("second")); 90 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm")); 91 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword")); 92 93 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) { 94 return session->GetTransportSocketPool( 95 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount(); 96 } 97 98 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) { 99 return session->GetSSLSocketPool( 100 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount(); 101 } 102 103 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) { 104 return session->GetTransportSocketPool( 105 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled(); 106 } 107 108 // Takes in a Value created from a NetLogHttpResponseParameter, and returns 109 // a JSONified list of headers as a single string. Uses single quotes instead 110 // of double quotes for easier comparison. Returns false on failure. 111 bool GetHeaders(base::DictionaryValue* params, std::string* headers) { 112 if (!params) 113 return false; 114 base::ListValue* header_list; 115 if (!params->GetList("headers", &header_list)) 116 return false; 117 std::string double_quote_headers; 118 base::JSONWriter::Write(header_list, &double_quote_headers); 119 base::ReplaceChars(double_quote_headers, "\"", "'", headers); 120 return true; 121 } 122 123 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is 124 // used. 125 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) { 126 EXPECT_TRUE(load_timing_info.socket_reused); 127 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 128 129 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 130 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 131 132 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 133 EXPECT_FALSE(load_timing_info.send_start.is_null()); 134 135 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 136 137 // Set at a higher level. 138 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 139 EXPECT_TRUE(load_timing_info.request_start.is_null()); 140 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 141 } 142 143 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is 144 // used. 145 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info, 146 int connect_timing_flags) { 147 EXPECT_FALSE(load_timing_info.socket_reused); 148 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 149 150 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 151 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 152 153 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 154 connect_timing_flags); 155 EXPECT_LE(load_timing_info.connect_timing.connect_end, 156 load_timing_info.send_start); 157 158 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 159 160 // Set at a higher level. 161 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 162 EXPECT_TRUE(load_timing_info.request_start.is_null()); 163 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 164 } 165 166 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is 167 // used. 168 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) { 169 EXPECT_TRUE(load_timing_info.socket_reused); 170 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 171 172 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 173 174 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 175 EXPECT_LE(load_timing_info.proxy_resolve_start, 176 load_timing_info.proxy_resolve_end); 177 EXPECT_LE(load_timing_info.proxy_resolve_end, 178 load_timing_info.send_start); 179 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 180 181 // Set at a higher level. 182 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 183 EXPECT_TRUE(load_timing_info.request_start.is_null()); 184 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 185 } 186 187 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is 188 // used. 189 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info, 190 int connect_timing_flags) { 191 EXPECT_FALSE(load_timing_info.socket_reused); 192 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 193 194 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 195 EXPECT_LE(load_timing_info.proxy_resolve_start, 196 load_timing_info.proxy_resolve_end); 197 EXPECT_LE(load_timing_info.proxy_resolve_end, 198 load_timing_info.connect_timing.connect_start); 199 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 200 connect_timing_flags); 201 EXPECT_LE(load_timing_info.connect_timing.connect_end, 202 load_timing_info.send_start); 203 204 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 205 206 // Set at a higher level. 207 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 208 EXPECT_TRUE(load_timing_info.request_start.is_null()); 209 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 210 } 211 212 } // namespace 213 214 namespace net { 215 216 namespace { 217 218 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) { 219 return SpdySessionDependencies::SpdyCreateSession(session_deps); 220 } 221 222 } // namespace 223 224 class HttpNetworkTransactionTest 225 : public PlatformTest, 226 public ::testing::WithParamInterface<NextProto> { 227 public: 228 virtual ~HttpNetworkTransactionTest() { 229 // Important to restore the per-pool limit first, since the pool limit must 230 // always be greater than group limit, and the tests reduce both limits. 231 ClientSocketPoolManager::set_max_sockets_per_pool( 232 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_); 233 ClientSocketPoolManager::set_max_sockets_per_group( 234 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_); 235 } 236 237 protected: 238 HttpNetworkTransactionTest() 239 : spdy_util_(GetParam()), 240 session_deps_(GetParam()), 241 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group( 242 HttpNetworkSession::NORMAL_SOCKET_POOL)), 243 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool( 244 HttpNetworkSession::NORMAL_SOCKET_POOL)) { 245 } 246 247 struct SimpleGetHelperResult { 248 int rv; 249 std::string status_line; 250 std::string response_data; 251 int64 totalReceivedBytes; 252 LoadTimingInfo load_timing_info; 253 }; 254 255 virtual void SetUp() { 256 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 257 base::MessageLoop::current()->RunUntilIdle(); 258 } 259 260 virtual void TearDown() { 261 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 262 base::MessageLoop::current()->RunUntilIdle(); 263 // Empty the current queue. 264 base::MessageLoop::current()->RunUntilIdle(); 265 PlatformTest::TearDown(); 266 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 267 base::MessageLoop::current()->RunUntilIdle(); 268 } 269 270 // This is the expected return from a current server advertising SPDY. 271 std::string GetAlternateProtocolHttpHeader() { 272 return 273 std::string("Alternate-Protocol: 443:") + 274 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) + 275 "\r\n\r\n"; 276 } 277 278 // Either |write_failure| specifies a write failure or |read_failure| 279 // specifies a read failure when using a reused socket. In either case, the 280 // failure should cause the network transaction to resend the request, and the 281 // other argument should be NULL. 282 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure, 283 const MockRead* read_failure); 284 285 // Either |write_failure| specifies a write failure or |read_failure| 286 // specifies a read failure when using a reused socket. In either case, the 287 // failure should cause the network transaction to resend the request, and the 288 // other argument should be NULL. 289 void PreconnectErrorResendRequestTest(const MockWrite* write_failure, 290 const MockRead* read_failure, 291 bool use_spdy); 292 293 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[], 294 size_t data_count) { 295 SimpleGetHelperResult out; 296 297 HttpRequestInfo request; 298 request.method = "GET"; 299 request.url = GURL("http://www.google.com/"); 300 request.load_flags = 0; 301 302 CapturingBoundNetLog log; 303 session_deps_.net_log = log.bound().net_log(); 304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 305 scoped_ptr<HttpTransaction> trans( 306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 307 308 for (size_t i = 0; i < data_count; ++i) { 309 session_deps_.socket_factory->AddSocketDataProvider(data[i]); 310 } 311 312 TestCompletionCallback callback; 313 314 EXPECT_TRUE(log.bound().IsLogging()); 315 int rv = trans->Start(&request, callback.callback(), log.bound()); 316 EXPECT_EQ(ERR_IO_PENDING, rv); 317 318 out.rv = callback.WaitForResult(); 319 320 // Even in the failure cases that use this function, connections are always 321 // successfully established before the error. 322 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info)); 323 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 324 325 if (out.rv != OK) 326 return out; 327 328 const HttpResponseInfo* response = trans->GetResponseInfo(); 329 // Can't use ASSERT_* inside helper functions like this, so 330 // return an error. 331 if (response == NULL || response->headers.get() == NULL) { 332 out.rv = ERR_UNEXPECTED; 333 return out; 334 } 335 out.status_line = response->headers->GetStatusLine(); 336 337 EXPECT_EQ("127.0.0.1", response->socket_address.host()); 338 EXPECT_EQ(80, response->socket_address.port()); 339 340 rv = ReadTransaction(trans.get(), &out.response_data); 341 EXPECT_EQ(OK, rv); 342 343 net::CapturingNetLog::CapturedEntryList entries; 344 log.GetEntries(&entries); 345 size_t pos = ExpectLogContainsSomewhere( 346 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, 347 NetLog::PHASE_NONE); 348 ExpectLogContainsSomewhere( 349 entries, pos, 350 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, 351 NetLog::PHASE_NONE); 352 353 std::string line; 354 EXPECT_TRUE(entries[pos].GetStringValue("line", &line)); 355 EXPECT_EQ("GET / HTTP/1.1\r\n", line); 356 357 HttpRequestHeaders request_headers; 358 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 359 std::string value; 360 EXPECT_TRUE(request_headers.GetHeader("Host", &value)); 361 EXPECT_EQ("www.google.com", value); 362 EXPECT_TRUE(request_headers.GetHeader("Connection", &value)); 363 EXPECT_EQ("keep-alive", value); 364 365 std::string response_headers; 366 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers)); 367 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']", 368 response_headers); 369 370 out.totalReceivedBytes = trans->GetTotalReceivedBytes(); 371 return out; 372 } 373 374 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[], 375 size_t reads_count) { 376 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0); 377 StaticSocketDataProvider* data[] = { &reads }; 378 return SimpleGetHelperForData(data, 1); 379 } 380 381 int64 ReadsSize(MockRead data_reads[], size_t reads_count) { 382 int64 size = 0; 383 for (size_t i = 0; i < reads_count; ++i) 384 size += data_reads[i].data_len; 385 return size; 386 } 387 388 void ConnectStatusHelperWithExpectedStatus(const MockRead& status, 389 int expected_status); 390 391 void ConnectStatusHelper(const MockRead& status); 392 393 void BypassHostCacheOnRefreshHelper(int load_flags); 394 395 void CheckErrorIsPassedBack(int error, IoMode mode); 396 397 SpdyTestUtil spdy_util_; 398 SpdySessionDependencies session_deps_; 399 400 // Original socket limits. Some tests set these. Safest to always restore 401 // them once each test has been run. 402 int old_max_group_sockets_; 403 int old_max_pool_sockets_; 404 }; 405 406 INSTANTIATE_TEST_CASE_P( 407 NextProto, 408 HttpNetworkTransactionTest, 409 testing::Values(kProtoDeprecatedSPDY2, 410 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4)); 411 412 namespace { 413 414 class BeforeNetworkStartHandler { 415 public: 416 explicit BeforeNetworkStartHandler(bool defer) 417 : defer_on_before_network_start_(defer), 418 observed_before_network_start_(false) {} 419 420 void OnBeforeNetworkStart(bool* defer) { 421 *defer = defer_on_before_network_start_; 422 observed_before_network_start_ = true; 423 } 424 425 bool observed_before_network_start() const { 426 return observed_before_network_start_; 427 } 428 429 private: 430 const bool defer_on_before_network_start_; 431 bool observed_before_network_start_; 432 433 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler); 434 }; 435 436 // Fill |str| with a long header list that consumes >= |size| bytes. 437 void FillLargeHeadersString(std::string* str, int size) { 438 const char* row = 439 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; 440 const int sizeof_row = strlen(row); 441 const int num_rows = static_cast<int>( 442 ceil(static_cast<float>(size) / sizeof_row)); 443 const int sizeof_data = num_rows * sizeof_row; 444 DCHECK(sizeof_data >= size); 445 str->reserve(sizeof_data); 446 447 for (int i = 0; i < num_rows; ++i) 448 str->append(row, sizeof_row); 449 } 450 451 // Alternative functions that eliminate randomness and dependency on the local 452 // host name so that the generated NTLM messages are reproducible. 453 void MockGenerateRandom1(uint8* output, size_t n) { 454 static const uint8 bytes[] = { 455 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54 456 }; 457 static size_t current_byte = 0; 458 for (size_t i = 0; i < n; ++i) { 459 output[i] = bytes[current_byte++]; 460 current_byte %= arraysize(bytes); 461 } 462 } 463 464 void MockGenerateRandom2(uint8* output, size_t n) { 465 static const uint8 bytes[] = { 466 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1, 467 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f 468 }; 469 static size_t current_byte = 0; 470 for (size_t i = 0; i < n; ++i) { 471 output[i] = bytes[current_byte++]; 472 current_byte %= arraysize(bytes); 473 } 474 } 475 476 std::string MockGetHostName() { 477 return "WTC-WIN7"; 478 } 479 480 template<typename ParentPool> 481 class CaptureGroupNameSocketPool : public ParentPool { 482 public: 483 CaptureGroupNameSocketPool(HostResolver* host_resolver, 484 CertVerifier* cert_verifier); 485 486 const std::string last_group_name_received() const { 487 return last_group_name_; 488 } 489 490 virtual int RequestSocket(const std::string& group_name, 491 const void* socket_params, 492 RequestPriority priority, 493 ClientSocketHandle* handle, 494 const CompletionCallback& callback, 495 const BoundNetLog& net_log) { 496 last_group_name_ = group_name; 497 return ERR_IO_PENDING; 498 } 499 virtual void CancelRequest(const std::string& group_name, 500 ClientSocketHandle* handle) {} 501 virtual void ReleaseSocket(const std::string& group_name, 502 scoped_ptr<StreamSocket> socket, 503 int id) {} 504 virtual void CloseIdleSockets() {} 505 virtual int IdleSocketCount() const { 506 return 0; 507 } 508 virtual int IdleSocketCountInGroup(const std::string& group_name) const { 509 return 0; 510 } 511 virtual LoadState GetLoadState(const std::string& group_name, 512 const ClientSocketHandle* handle) const { 513 return LOAD_STATE_IDLE; 514 } 515 virtual base::TimeDelta ConnectionTimeout() const { 516 return base::TimeDelta(); 517 } 518 519 private: 520 std::string last_group_name_; 521 }; 522 523 typedef CaptureGroupNameSocketPool<TransportClientSocketPool> 524 CaptureGroupNameTransportSocketPool; 525 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool> 526 CaptureGroupNameHttpProxySocketPool; 527 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool> 528 CaptureGroupNameSOCKSSocketPool; 529 typedef CaptureGroupNameSocketPool<SSLClientSocketPool> 530 CaptureGroupNameSSLSocketPool; 531 532 template<typename ParentPool> 533 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool( 534 HostResolver* host_resolver, 535 CertVerifier* /* cert_verifier */) 536 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {} 537 538 template<> 539 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool( 540 HostResolver* host_resolver, 541 CertVerifier* /* cert_verifier */) 542 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {} 543 544 template <> 545 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool( 546 HostResolver* host_resolver, 547 CertVerifier* cert_verifier) 548 : SSLClientSocketPool(0, 549 0, 550 NULL, 551 host_resolver, 552 cert_verifier, 553 NULL, 554 NULL, 555 NULL, 556 std::string(), 557 NULL, 558 NULL, 559 NULL, 560 NULL, 561 NULL, 562 NULL) {} 563 564 //----------------------------------------------------------------------------- 565 566 // Helper functions for validating that AuthChallengeInfo's are correctly 567 // configured for common cases. 568 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) { 569 if (!auth_challenge) 570 return false; 571 EXPECT_FALSE(auth_challenge->is_proxy); 572 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString()); 573 EXPECT_EQ("MyRealm1", auth_challenge->realm); 574 EXPECT_EQ("basic", auth_challenge->scheme); 575 return true; 576 } 577 578 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) { 579 if (!auth_challenge) 580 return false; 581 EXPECT_TRUE(auth_challenge->is_proxy); 582 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString()); 583 EXPECT_EQ("MyRealm1", auth_challenge->realm); 584 EXPECT_EQ("basic", auth_challenge->scheme); 585 return true; 586 } 587 588 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) { 589 if (!auth_challenge) 590 return false; 591 EXPECT_FALSE(auth_challenge->is_proxy); 592 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString()); 593 EXPECT_EQ("digestive", auth_challenge->realm); 594 EXPECT_EQ("digest", auth_challenge->scheme); 595 return true; 596 } 597 598 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) { 599 if (!auth_challenge) 600 return false; 601 EXPECT_FALSE(auth_challenge->is_proxy); 602 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString()); 603 EXPECT_EQ(std::string(), auth_challenge->realm); 604 EXPECT_EQ("ntlm", auth_challenge->scheme); 605 return true; 606 } 607 608 } // namespace 609 610 TEST_P(HttpNetworkTransactionTest, Basic) { 611 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 612 scoped_ptr<HttpTransaction> trans( 613 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 614 } 615 616 TEST_P(HttpNetworkTransactionTest, SimpleGET) { 617 MockRead data_reads[] = { 618 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 619 MockRead("hello world"), 620 MockRead(SYNCHRONOUS, OK), 621 }; 622 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 623 arraysize(data_reads)); 624 EXPECT_EQ(OK, out.rv); 625 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 626 EXPECT_EQ("hello world", out.response_data); 627 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 628 EXPECT_EQ(reads_size, out.totalReceivedBytes); 629 } 630 631 // Response with no status line. 632 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) { 633 MockRead data_reads[] = { 634 MockRead("hello world"), 635 MockRead(SYNCHRONOUS, OK), 636 }; 637 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 638 arraysize(data_reads)); 639 EXPECT_EQ(OK, out.rv); 640 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 641 EXPECT_EQ("hello world", out.response_data); 642 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 643 EXPECT_EQ(reads_size, out.totalReceivedBytes); 644 } 645 646 // Allow up to 4 bytes of junk to precede status line. 647 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) { 648 MockRead data_reads[] = { 649 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 650 MockRead(SYNCHRONOUS, OK), 651 }; 652 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 653 arraysize(data_reads)); 654 EXPECT_EQ(OK, out.rv); 655 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 656 EXPECT_EQ("DATA", out.response_data); 657 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 658 EXPECT_EQ(reads_size, out.totalReceivedBytes); 659 } 660 661 // Allow up to 4 bytes of junk to precede status line. 662 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { 663 MockRead data_reads[] = { 664 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 665 MockRead(SYNCHRONOUS, OK), 666 }; 667 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 668 arraysize(data_reads)); 669 EXPECT_EQ(OK, out.rv); 670 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 671 EXPECT_EQ("DATA", out.response_data); 672 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 673 EXPECT_EQ(reads_size, out.totalReceivedBytes); 674 } 675 676 // Beyond 4 bytes of slop and it should fail to find a status line. 677 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { 678 MockRead data_reads[] = { 679 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"), 680 MockRead(SYNCHRONOUS, OK), 681 }; 682 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 683 arraysize(data_reads)); 684 EXPECT_EQ(OK, out.rv); 685 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 686 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); 687 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 688 EXPECT_EQ(reads_size, out.totalReceivedBytes); 689 } 690 691 // Same as StatusLineJunk4Bytes, except the read chunks are smaller. 692 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { 693 MockRead data_reads[] = { 694 MockRead("\n"), 695 MockRead("\n"), 696 MockRead("Q"), 697 MockRead("J"), 698 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 699 MockRead(SYNCHRONOUS, OK), 700 }; 701 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 702 arraysize(data_reads)); 703 EXPECT_EQ(OK, out.rv); 704 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 705 EXPECT_EQ("DATA", out.response_data); 706 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 707 EXPECT_EQ(reads_size, out.totalReceivedBytes); 708 } 709 710 // Close the connection before enough bytes to have a status line. 711 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) { 712 MockRead data_reads[] = { 713 MockRead("HTT"), 714 MockRead(SYNCHRONOUS, OK), 715 }; 716 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 717 arraysize(data_reads)); 718 EXPECT_EQ(OK, out.rv); 719 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 720 EXPECT_EQ("HTT", out.response_data); 721 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 722 EXPECT_EQ(reads_size, out.totalReceivedBytes); 723 } 724 725 // Simulate a 204 response, lacking a Content-Length header, sent over a 726 // persistent connection. The response should still terminate since a 204 727 // cannot have a response body. 728 TEST_P(HttpNetworkTransactionTest, StopsReading204) { 729 char junk[] = "junk"; 730 MockRead data_reads[] = { 731 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 732 MockRead(junk), // Should not be read!! 733 MockRead(SYNCHRONOUS, OK), 734 }; 735 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 736 arraysize(data_reads)); 737 EXPECT_EQ(OK, out.rv); 738 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); 739 EXPECT_EQ("", out.response_data); 740 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 741 int64 response_size = reads_size - strlen(junk); 742 EXPECT_EQ(response_size, out.totalReceivedBytes); 743 } 744 745 // A simple request using chunked encoding with some extra data after. 746 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) { 747 std::string final_chunk = "0\r\n\r\n"; 748 std::string extra_data = "HTTP/1.1 200 OK\r\n"; 749 std::string last_read = final_chunk + extra_data; 750 MockRead data_reads[] = { 751 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"), 752 MockRead("5\r\nHello\r\n"), 753 MockRead("1\r\n"), 754 MockRead(" \r\n"), 755 MockRead("5\r\nworld\r\n"), 756 MockRead(last_read.data()), 757 MockRead(SYNCHRONOUS, OK), 758 }; 759 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 760 arraysize(data_reads)); 761 EXPECT_EQ(OK, out.rv); 762 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 763 EXPECT_EQ("Hello world", out.response_data); 764 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 765 int64 response_size = reads_size - extra_data.size(); 766 EXPECT_EQ(response_size, out.totalReceivedBytes); 767 } 768 769 // Next tests deal with http://crbug.com/56344. 770 771 TEST_P(HttpNetworkTransactionTest, 772 MultipleContentLengthHeadersNoTransferEncoding) { 773 MockRead data_reads[] = { 774 MockRead("HTTP/1.1 200 OK\r\n"), 775 MockRead("Content-Length: 10\r\n"), 776 MockRead("Content-Length: 5\r\n\r\n"), 777 }; 778 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 779 arraysize(data_reads)); 780 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 781 } 782 783 TEST_P(HttpNetworkTransactionTest, 784 DuplicateContentLengthHeadersNoTransferEncoding) { 785 MockRead data_reads[] = { 786 MockRead("HTTP/1.1 200 OK\r\n"), 787 MockRead("Content-Length: 5\r\n"), 788 MockRead("Content-Length: 5\r\n\r\n"), 789 MockRead("Hello"), 790 }; 791 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 792 arraysize(data_reads)); 793 EXPECT_EQ(OK, out.rv); 794 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 795 EXPECT_EQ("Hello", out.response_data); 796 } 797 798 TEST_P(HttpNetworkTransactionTest, 799 ComplexContentLengthHeadersNoTransferEncoding) { 800 // More than 2 dupes. 801 { 802 MockRead data_reads[] = { 803 MockRead("HTTP/1.1 200 OK\r\n"), 804 MockRead("Content-Length: 5\r\n"), 805 MockRead("Content-Length: 5\r\n"), 806 MockRead("Content-Length: 5\r\n\r\n"), 807 MockRead("Hello"), 808 }; 809 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 810 arraysize(data_reads)); 811 EXPECT_EQ(OK, out.rv); 812 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 813 EXPECT_EQ("Hello", out.response_data); 814 } 815 // HTTP/1.0 816 { 817 MockRead data_reads[] = { 818 MockRead("HTTP/1.0 200 OK\r\n"), 819 MockRead("Content-Length: 5\r\n"), 820 MockRead("Content-Length: 5\r\n"), 821 MockRead("Content-Length: 5\r\n\r\n"), 822 MockRead("Hello"), 823 }; 824 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 825 arraysize(data_reads)); 826 EXPECT_EQ(OK, out.rv); 827 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 828 EXPECT_EQ("Hello", out.response_data); 829 } 830 // 2 dupes and one mismatched. 831 { 832 MockRead data_reads[] = { 833 MockRead("HTTP/1.1 200 OK\r\n"), 834 MockRead("Content-Length: 10\r\n"), 835 MockRead("Content-Length: 10\r\n"), 836 MockRead("Content-Length: 5\r\n\r\n"), 837 }; 838 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 839 arraysize(data_reads)); 840 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 841 } 842 } 843 844 TEST_P(HttpNetworkTransactionTest, 845 MultipleContentLengthHeadersTransferEncoding) { 846 MockRead data_reads[] = { 847 MockRead("HTTP/1.1 200 OK\r\n"), 848 MockRead("Content-Length: 666\r\n"), 849 MockRead("Content-Length: 1337\r\n"), 850 MockRead("Transfer-Encoding: chunked\r\n\r\n"), 851 MockRead("5\r\nHello\r\n"), 852 MockRead("1\r\n"), 853 MockRead(" \r\n"), 854 MockRead("5\r\nworld\r\n"), 855 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"), 856 MockRead(SYNCHRONOUS, OK), 857 }; 858 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 859 arraysize(data_reads)); 860 EXPECT_EQ(OK, out.rv); 861 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 862 EXPECT_EQ("Hello world", out.response_data); 863 } 864 865 // Next tests deal with http://crbug.com/98895. 866 867 // Checks that a single Content-Disposition header results in no error. 868 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) { 869 MockRead data_reads[] = { 870 MockRead("HTTP/1.1 200 OK\r\n"), 871 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"), 872 MockRead("Content-Length: 5\r\n\r\n"), 873 MockRead("Hello"), 874 }; 875 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 876 arraysize(data_reads)); 877 EXPECT_EQ(OK, out.rv); 878 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 879 EXPECT_EQ("Hello", out.response_data); 880 } 881 882 // Checks that two identical Content-Disposition headers result in no error. 883 TEST_P(HttpNetworkTransactionTest, 884 TwoIdenticalContentDispositionHeaders) { 885 MockRead data_reads[] = { 886 MockRead("HTTP/1.1 200 OK\r\n"), 887 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 888 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 889 MockRead("Content-Length: 5\r\n\r\n"), 890 MockRead("Hello"), 891 }; 892 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 893 arraysize(data_reads)); 894 EXPECT_EQ(OK, out.rv); 895 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 896 EXPECT_EQ("Hello", out.response_data); 897 } 898 899 // Checks that two distinct Content-Disposition headers result in an error. 900 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) { 901 MockRead data_reads[] = { 902 MockRead("HTTP/1.1 200 OK\r\n"), 903 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"), 904 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"), 905 MockRead("Content-Length: 5\r\n\r\n"), 906 MockRead("Hello"), 907 }; 908 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 909 arraysize(data_reads)); 910 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv); 911 } 912 913 // Checks that two identical Location headers result in no error. 914 // Also tests Location header behavior. 915 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) { 916 MockRead data_reads[] = { 917 MockRead("HTTP/1.1 302 Redirect\r\n"), 918 MockRead("Location: http://good.com/\r\n"), 919 MockRead("Location: http://good.com/\r\n"), 920 MockRead("Content-Length: 0\r\n\r\n"), 921 MockRead(SYNCHRONOUS, OK), 922 }; 923 924 HttpRequestInfo request; 925 request.method = "GET"; 926 request.url = GURL("http://redirect.com/"); 927 request.load_flags = 0; 928 929 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 930 scoped_ptr<HttpTransaction> trans( 931 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 932 933 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 934 session_deps_.socket_factory->AddSocketDataProvider(&data); 935 936 TestCompletionCallback callback; 937 938 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 939 EXPECT_EQ(ERR_IO_PENDING, rv); 940 941 EXPECT_EQ(OK, callback.WaitForResult()); 942 943 const HttpResponseInfo* response = trans->GetResponseInfo(); 944 ASSERT_TRUE(response != NULL && response->headers.get() != NULL); 945 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine()); 946 std::string url; 947 EXPECT_TRUE(response->headers->IsRedirect(&url)); 948 EXPECT_EQ("http://good.com/", url); 949 EXPECT_TRUE(response->proxy_server.IsEmpty()); 950 } 951 952 // Checks that two distinct Location headers result in an error. 953 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) { 954 MockRead data_reads[] = { 955 MockRead("HTTP/1.1 302 Redirect\r\n"), 956 MockRead("Location: http://good.com/\r\n"), 957 MockRead("Location: http://evil.com/\r\n"), 958 MockRead("Content-Length: 0\r\n\r\n"), 959 MockRead(SYNCHRONOUS, OK), 960 }; 961 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 962 arraysize(data_reads)); 963 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv); 964 } 965 966 // Do a request using the HEAD method. Verify that we don't try to read the 967 // message body (since HEAD has none). 968 TEST_P(HttpNetworkTransactionTest, Head) { 969 HttpRequestInfo request; 970 request.method = "HEAD"; 971 request.url = GURL("http://www.google.com/"); 972 request.load_flags = 0; 973 974 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 975 scoped_ptr<HttpTransaction> trans( 976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 977 978 MockWrite data_writes1[] = { 979 MockWrite("HEAD / HTTP/1.1\r\n" 980 "Host: www.google.com\r\n" 981 "Connection: keep-alive\r\n" 982 "Content-Length: 0\r\n\r\n"), 983 }; 984 MockRead data_reads1[] = { 985 MockRead("HTTP/1.1 404 Not Found\r\n"), 986 MockRead("Server: Blah\r\n"), 987 MockRead("Content-Length: 1234\r\n\r\n"), 988 989 // No response body because the test stops reading here. 990 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 991 }; 992 993 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 994 data_writes1, arraysize(data_writes1)); 995 session_deps_.socket_factory->AddSocketDataProvider(&data1); 996 997 TestCompletionCallback callback1; 998 999 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1000 EXPECT_EQ(ERR_IO_PENDING, rv); 1001 1002 rv = callback1.WaitForResult(); 1003 EXPECT_EQ(OK, rv); 1004 1005 const HttpResponseInfo* response = trans->GetResponseInfo(); 1006 ASSERT_TRUE(response != NULL); 1007 1008 // Check that the headers got parsed. 1009 EXPECT_TRUE(response->headers.get() != NULL); 1010 EXPECT_EQ(1234, response->headers->GetContentLength()); 1011 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine()); 1012 EXPECT_TRUE(response->proxy_server.IsEmpty()); 1013 1014 std::string server_header; 1015 void* iter = NULL; 1016 bool has_server_header = response->headers->EnumerateHeader( 1017 &iter, "Server", &server_header); 1018 EXPECT_TRUE(has_server_header); 1019 EXPECT_EQ("Blah", server_header); 1020 1021 // Reading should give EOF right away, since there is no message body 1022 // (despite non-zero content-length). 1023 std::string response_data; 1024 rv = ReadTransaction(trans.get(), &response_data); 1025 EXPECT_EQ(OK, rv); 1026 EXPECT_EQ("", response_data); 1027 } 1028 1029 TEST_P(HttpNetworkTransactionTest, ReuseConnection) { 1030 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1031 1032 MockRead data_reads[] = { 1033 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1034 MockRead("hello"), 1035 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1036 MockRead("world"), 1037 MockRead(SYNCHRONOUS, OK), 1038 }; 1039 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1040 session_deps_.socket_factory->AddSocketDataProvider(&data); 1041 1042 const char* const kExpectedResponseData[] = { 1043 "hello", "world" 1044 }; 1045 1046 for (int i = 0; i < 2; ++i) { 1047 HttpRequestInfo request; 1048 request.method = "GET"; 1049 request.url = GURL("http://www.google.com/"); 1050 request.load_flags = 0; 1051 1052 scoped_ptr<HttpTransaction> trans( 1053 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1054 1055 TestCompletionCallback callback; 1056 1057 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1058 EXPECT_EQ(ERR_IO_PENDING, rv); 1059 1060 rv = callback.WaitForResult(); 1061 EXPECT_EQ(OK, rv); 1062 1063 const HttpResponseInfo* response = trans->GetResponseInfo(); 1064 ASSERT_TRUE(response != NULL); 1065 1066 EXPECT_TRUE(response->headers.get() != NULL); 1067 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1068 EXPECT_TRUE(response->proxy_server.IsEmpty()); 1069 1070 std::string response_data; 1071 rv = ReadTransaction(trans.get(), &response_data); 1072 EXPECT_EQ(OK, rv); 1073 EXPECT_EQ(kExpectedResponseData[i], response_data); 1074 } 1075 } 1076 1077 TEST_P(HttpNetworkTransactionTest, Ignores100) { 1078 ScopedVector<UploadElementReader> element_readers; 1079 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 1080 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 1081 1082 HttpRequestInfo request; 1083 request.method = "POST"; 1084 request.url = GURL("http://www.foo.com/"); 1085 request.upload_data_stream = &upload_data_stream; 1086 request.load_flags = 0; 1087 1088 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1089 scoped_ptr<HttpTransaction> trans( 1090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1091 1092 MockRead data_reads[] = { 1093 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 1094 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 1095 MockRead("hello world"), 1096 MockRead(SYNCHRONOUS, OK), 1097 }; 1098 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1099 session_deps_.socket_factory->AddSocketDataProvider(&data); 1100 1101 TestCompletionCallback callback; 1102 1103 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1104 EXPECT_EQ(ERR_IO_PENDING, rv); 1105 1106 rv = callback.WaitForResult(); 1107 EXPECT_EQ(OK, rv); 1108 1109 const HttpResponseInfo* response = trans->GetResponseInfo(); 1110 ASSERT_TRUE(response != NULL); 1111 1112 EXPECT_TRUE(response->headers.get() != NULL); 1113 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 1114 1115 std::string response_data; 1116 rv = ReadTransaction(trans.get(), &response_data); 1117 EXPECT_EQ(OK, rv); 1118 EXPECT_EQ("hello world", response_data); 1119 } 1120 1121 // This test is almost the same as Ignores100 above, but the response contains 1122 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is 1123 // HTTP/1.1 and the two status headers are read in one read. 1124 TEST_P(HttpNetworkTransactionTest, Ignores1xx) { 1125 HttpRequestInfo request; 1126 request.method = "GET"; 1127 request.url = GURL("http://www.foo.com/"); 1128 request.load_flags = 0; 1129 1130 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1131 scoped_ptr<HttpTransaction> trans( 1132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1133 1134 MockRead data_reads[] = { 1135 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n" 1136 "HTTP/1.1 200 OK\r\n\r\n"), 1137 MockRead("hello world"), 1138 MockRead(SYNCHRONOUS, OK), 1139 }; 1140 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1141 session_deps_.socket_factory->AddSocketDataProvider(&data); 1142 1143 TestCompletionCallback callback; 1144 1145 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1146 EXPECT_EQ(ERR_IO_PENDING, rv); 1147 1148 rv = callback.WaitForResult(); 1149 EXPECT_EQ(OK, rv); 1150 1151 const HttpResponseInfo* response = trans->GetResponseInfo(); 1152 ASSERT_TRUE(response != NULL); 1153 1154 EXPECT_TRUE(response->headers.get() != NULL); 1155 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1156 1157 std::string response_data; 1158 rv = ReadTransaction(trans.get(), &response_data); 1159 EXPECT_EQ(OK, rv); 1160 EXPECT_EQ("hello world", response_data); 1161 } 1162 1163 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) { 1164 HttpRequestInfo request; 1165 request.method = "POST"; 1166 request.url = GURL("http://www.foo.com/"); 1167 request.load_flags = 0; 1168 1169 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1170 scoped_ptr<HttpTransaction> trans( 1171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1172 1173 MockRead data_reads[] = { 1174 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"), 1175 MockRead(ASYNC, 0), 1176 }; 1177 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1178 session_deps_.socket_factory->AddSocketDataProvider(&data); 1179 1180 TestCompletionCallback callback; 1181 1182 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1183 EXPECT_EQ(ERR_IO_PENDING, rv); 1184 1185 rv = callback.WaitForResult(); 1186 EXPECT_EQ(OK, rv); 1187 1188 std::string response_data; 1189 rv = ReadTransaction(trans.get(), &response_data); 1190 EXPECT_EQ(OK, rv); 1191 EXPECT_EQ("", response_data); 1192 } 1193 1194 TEST_P(HttpNetworkTransactionTest, EmptyResponse) { 1195 HttpRequestInfo request; 1196 request.method = "POST"; 1197 request.url = GURL("http://www.foo.com/"); 1198 request.load_flags = 0; 1199 1200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1201 scoped_ptr<HttpTransaction> trans( 1202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1203 1204 1205 MockRead data_reads[] = { 1206 MockRead(ASYNC, 0), 1207 }; 1208 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1209 session_deps_.socket_factory->AddSocketDataProvider(&data); 1210 1211 TestCompletionCallback callback; 1212 1213 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1214 EXPECT_EQ(ERR_IO_PENDING, rv); 1215 1216 rv = callback.WaitForResult(); 1217 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 1218 } 1219 1220 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest( 1221 const MockWrite* write_failure, 1222 const MockRead* read_failure) { 1223 HttpRequestInfo request; 1224 request.method = "GET"; 1225 request.url = GURL("http://www.foo.com/"); 1226 request.load_flags = 0; 1227 1228 CapturingNetLog net_log; 1229 session_deps_.net_log = &net_log; 1230 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1231 1232 // Written data for successfully sending both requests. 1233 MockWrite data1_writes[] = { 1234 MockWrite("GET / HTTP/1.1\r\n" 1235 "Host: www.foo.com\r\n" 1236 "Connection: keep-alive\r\n\r\n"), 1237 MockWrite("GET / HTTP/1.1\r\n" 1238 "Host: www.foo.com\r\n" 1239 "Connection: keep-alive\r\n\r\n") 1240 }; 1241 1242 // Read results for the first request. 1243 MockRead data1_reads[] = { 1244 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1245 MockRead("hello"), 1246 MockRead(ASYNC, OK), 1247 }; 1248 1249 if (write_failure) { 1250 ASSERT_FALSE(read_failure); 1251 data1_writes[1] = *write_failure; 1252 } else { 1253 ASSERT_TRUE(read_failure); 1254 data1_reads[2] = *read_failure; 1255 } 1256 1257 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), 1258 data1_writes, arraysize(data1_writes)); 1259 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1260 1261 MockRead data2_reads[] = { 1262 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1263 MockRead("world"), 1264 MockRead(ASYNC, OK), 1265 }; 1266 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 1267 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1268 1269 const char* kExpectedResponseData[] = { 1270 "hello", "world" 1271 }; 1272 1273 uint32 first_socket_log_id = NetLog::Source::kInvalidId; 1274 for (int i = 0; i < 2; ++i) { 1275 TestCompletionCallback callback; 1276 1277 scoped_ptr<HttpTransaction> trans( 1278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 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(OK, rv); 1285 1286 LoadTimingInfo load_timing_info; 1287 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1288 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 1289 if (i == 0) { 1290 first_socket_log_id = load_timing_info.socket_log_id; 1291 } else { 1292 // The second request should be using a new socket. 1293 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id); 1294 } 1295 1296 const HttpResponseInfo* response = trans->GetResponseInfo(); 1297 ASSERT_TRUE(response != NULL); 1298 1299 EXPECT_TRUE(response->headers.get() != NULL); 1300 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1301 1302 std::string response_data; 1303 rv = ReadTransaction(trans.get(), &response_data); 1304 EXPECT_EQ(OK, rv); 1305 EXPECT_EQ(kExpectedResponseData[i], response_data); 1306 } 1307 } 1308 1309 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest( 1310 const MockWrite* write_failure, 1311 const MockRead* read_failure, 1312 bool use_spdy) { 1313 HttpRequestInfo request; 1314 request.method = "GET"; 1315 request.url = GURL("https://www.foo.com/"); 1316 request.load_flags = 0; 1317 1318 CapturingNetLog net_log; 1319 session_deps_.net_log = &net_log; 1320 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1321 1322 SSLSocketDataProvider ssl1(ASYNC, OK); 1323 SSLSocketDataProvider ssl2(ASYNC, OK); 1324 if (use_spdy) { 1325 ssl1.SetNextProto(GetParam()); 1326 ssl2.SetNextProto(GetParam()); 1327 } 1328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); 1329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 1330 1331 // SPDY versions of the request and response. 1332 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet( 1333 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY)); 1334 scoped_ptr<SpdyFrame> spdy_response( 1335 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1336 scoped_ptr<SpdyFrame> spdy_data( 1337 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true)); 1338 1339 // HTTP/1.1 versions of the request and response. 1340 const char kHttpRequest[] = "GET / HTTP/1.1\r\n" 1341 "Host: www.foo.com\r\n" 1342 "Connection: keep-alive\r\n\r\n"; 1343 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"; 1344 const char kHttpData[] = "hello"; 1345 1346 std::vector<MockRead> data1_reads; 1347 std::vector<MockWrite> data1_writes; 1348 if (write_failure) { 1349 ASSERT_FALSE(read_failure); 1350 data1_writes.push_back(*write_failure); 1351 data1_reads.push_back(MockRead(ASYNC, OK)); 1352 } else { 1353 ASSERT_TRUE(read_failure); 1354 if (use_spdy) { 1355 data1_writes.push_back(CreateMockWrite(*spdy_request)); 1356 } else { 1357 data1_writes.push_back(MockWrite(kHttpRequest)); 1358 } 1359 data1_reads.push_back(*read_failure); 1360 } 1361 1362 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(), 1363 &data1_writes[0], data1_writes.size()); 1364 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1365 1366 std::vector<MockRead> data2_reads; 1367 std::vector<MockWrite> data2_writes; 1368 1369 if (use_spdy) { 1370 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC)); 1371 1372 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC)); 1373 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC)); 1374 data2_reads.push_back(MockRead(ASYNC, OK, 3)); 1375 } else { 1376 data2_writes.push_back( 1377 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0)); 1378 1379 data2_reads.push_back( 1380 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1)); 1381 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2)); 1382 data2_reads.push_back(MockRead(ASYNC, OK, 3)); 1383 } 1384 OrderedSocketData data2(&data2_reads[0], data2_reads.size(), 1385 &data2_writes[0], data2_writes.size()); 1386 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1387 1388 // Preconnect a socket. 1389 net::SSLConfig ssl_config; 1390 session->ssl_config_service()->GetSSLConfig(&ssl_config); 1391 session->GetNextProtos(&ssl_config.next_protos); 1392 session->http_stream_factory()->PreconnectStreams( 1393 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config); 1394 // Wait for the preconnect to complete. 1395 // TODO(davidben): Some way to wait for an idle socket count might be handy. 1396 base::RunLoop().RunUntilIdle(); 1397 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 1398 1399 // Make the request. 1400 TestCompletionCallback callback; 1401 1402 scoped_ptr<HttpTransaction> trans( 1403 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1404 1405 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1406 EXPECT_EQ(ERR_IO_PENDING, rv); 1407 1408 rv = callback.WaitForResult(); 1409 EXPECT_EQ(OK, rv); 1410 1411 LoadTimingInfo load_timing_info; 1412 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1413 TestLoadTimingNotReused( 1414 load_timing_info, 1415 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES); 1416 1417 const HttpResponseInfo* response = trans->GetResponseInfo(); 1418 ASSERT_TRUE(response != NULL); 1419 1420 EXPECT_TRUE(response->headers.get() != NULL); 1421 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1422 1423 std::string response_data; 1424 rv = ReadTransaction(trans.get(), &response_data); 1425 EXPECT_EQ(OK, rv); 1426 EXPECT_EQ(kHttpData, response_data); 1427 } 1428 1429 TEST_P(HttpNetworkTransactionTest, 1430 KeepAliveConnectionNotConnectedOnWrite) { 1431 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1432 KeepAliveConnectionResendRequestTest(&write_failure, NULL); 1433 } 1434 1435 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) { 1436 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1437 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1438 } 1439 1440 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { 1441 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1442 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1443 } 1444 1445 // Make sure that on a 408 response (Request Timeout), the request is retried, 1446 // if the socket was a reused keep alive socket. 1447 TEST_P(HttpNetworkTransactionTest, KeepAlive408) { 1448 MockRead read_failure(SYNCHRONOUS, 1449 "HTTP/1.1 408 Request Timeout\r\n" 1450 "Connection: Keep-Alive\r\n" 1451 "Content-Length: 6\r\n\r\n" 1452 "Pickle"); 1453 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1454 } 1455 1456 TEST_P(HttpNetworkTransactionTest, 1457 PreconnectErrorNotConnectedOnWrite) { 1458 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1459 PreconnectErrorResendRequestTest(&write_failure, NULL, false); 1460 } 1461 1462 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) { 1463 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1464 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1465 } 1466 1467 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) { 1468 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1469 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1470 } 1471 1472 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) { 1473 MockRead read_failure(ASYNC, OK); // EOF 1474 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1475 } 1476 1477 // Make sure that on a 408 response (Request Timeout), the request is retried, 1478 // if the socket was a preconnected (UNUSED_IDLE) socket. 1479 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) { 1480 MockRead read_failure(SYNCHRONOUS, 1481 "HTTP/1.1 408 Request Timeout\r\n" 1482 "Connection: Keep-Alive\r\n" 1483 "Content-Length: 6\r\n\r\n" 1484 "Pickle"); 1485 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1486 PreconnectErrorResendRequestTest(NULL, &read_failure, false); 1487 } 1488 1489 TEST_P(HttpNetworkTransactionTest, 1490 SpdyPreconnectErrorNotConnectedOnWrite) { 1491 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1492 PreconnectErrorResendRequestTest(&write_failure, NULL, true); 1493 } 1494 1495 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) { 1496 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1497 PreconnectErrorResendRequestTest(NULL, &read_failure, true); 1498 } 1499 1500 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) { 1501 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1502 PreconnectErrorResendRequestTest(NULL, &read_failure, true); 1503 } 1504 1505 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) { 1506 MockRead read_failure(ASYNC, OK); // EOF 1507 PreconnectErrorResendRequestTest(NULL, &read_failure, true); 1508 } 1509 1510 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { 1511 HttpRequestInfo request; 1512 request.method = "GET"; 1513 request.url = GURL("http://www.google.com/"); 1514 request.load_flags = 0; 1515 1516 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1517 scoped_ptr<HttpTransaction> trans( 1518 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1519 1520 MockRead data_reads[] = { 1521 MockRead(ASYNC, ERR_CONNECTION_RESET), 1522 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 1523 MockRead("hello world"), 1524 MockRead(SYNCHRONOUS, OK), 1525 }; 1526 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1527 session_deps_.socket_factory->AddSocketDataProvider(&data); 1528 1529 TestCompletionCallback callback; 1530 1531 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1532 EXPECT_EQ(ERR_IO_PENDING, rv); 1533 1534 rv = callback.WaitForResult(); 1535 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1536 1537 const HttpResponseInfo* response = trans->GetResponseInfo(); 1538 EXPECT_TRUE(response == NULL); 1539 } 1540 1541 // What do various browsers do when the server closes a non-keepalive 1542 // connection without sending any response header or body? 1543 // 1544 // IE7: error page 1545 // Safari 3.1.2 (Windows): error page 1546 // Firefox 3.0.1: blank page 1547 // Opera 9.52: after five attempts, blank page 1548 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE) 1549 // Us: error page (EMPTY_RESPONSE) 1550 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { 1551 MockRead data_reads[] = { 1552 MockRead(SYNCHRONOUS, OK), // EOF 1553 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 1554 MockRead("hello world"), 1555 MockRead(SYNCHRONOUS, OK), 1556 }; 1557 SimpleGetHelperResult out = SimpleGetHelper(data_reads, 1558 arraysize(data_reads)); 1559 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); 1560 } 1561 1562 // Test that network access can be deferred and resumed. 1563 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) { 1564 HttpRequestInfo request; 1565 request.method = "GET"; 1566 request.url = GURL("http://www.google.com/"); 1567 request.load_flags = 0; 1568 1569 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1570 scoped_ptr<HttpTransaction> trans( 1571 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1572 1573 // Defer on OnBeforeNetworkStart. 1574 BeforeNetworkStartHandler net_start_handler(true); // defer 1575 trans->SetBeforeNetworkStartCallback( 1576 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, 1577 base::Unretained(&net_start_handler))); 1578 1579 MockRead data_reads[] = { 1580 MockRead("HTTP/1.0 200 OK\r\n"), 1581 MockRead("Content-Length: 5\r\n\r\n"), 1582 MockRead("hello"), 1583 MockRead(SYNCHRONOUS, 0), 1584 }; 1585 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1586 session_deps_.socket_factory->AddSocketDataProvider(&data); 1587 1588 TestCompletionCallback callback; 1589 1590 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1591 EXPECT_EQ(ERR_IO_PENDING, rv); 1592 base::MessageLoop::current()->RunUntilIdle(); 1593 1594 // Should have deferred for network start. 1595 EXPECT_TRUE(net_start_handler.observed_before_network_start()); 1596 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); 1597 EXPECT_TRUE(trans->GetResponseInfo() == NULL); 1598 1599 trans->ResumeNetworkStart(); 1600 rv = callback.WaitForResult(); 1601 EXPECT_EQ(OK, rv); 1602 EXPECT_TRUE(trans->GetResponseInfo() != NULL); 1603 1604 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1605 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1606 if (rv == ERR_IO_PENDING) 1607 rv = callback.WaitForResult(); 1608 EXPECT_EQ(5, rv); 1609 trans.reset(); 1610 } 1611 1612 // Test that network use can be deferred and canceled. 1613 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) { 1614 HttpRequestInfo request; 1615 request.method = "GET"; 1616 request.url = GURL("http://www.google.com/"); 1617 request.load_flags = 0; 1618 1619 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1620 scoped_ptr<HttpTransaction> trans( 1621 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1622 1623 // Defer on OnBeforeNetworkStart. 1624 BeforeNetworkStartHandler net_start_handler(true); // defer 1625 trans->SetBeforeNetworkStartCallback( 1626 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, 1627 base::Unretained(&net_start_handler))); 1628 1629 TestCompletionCallback callback; 1630 1631 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1632 EXPECT_EQ(ERR_IO_PENDING, rv); 1633 base::MessageLoop::current()->RunUntilIdle(); 1634 1635 // Should have deferred for network start. 1636 EXPECT_TRUE(net_start_handler.observed_before_network_start()); 1637 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); 1638 EXPECT_TRUE(trans->GetResponseInfo() == NULL); 1639 } 1640 1641 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression 1642 // tests. There was a bug causing HttpNetworkTransaction to hang in the 1643 // destructor in such situations. 1644 // See http://crbug.com/154712 and http://crbug.com/156609. 1645 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) { 1646 HttpRequestInfo request; 1647 request.method = "GET"; 1648 request.url = GURL("http://www.google.com/"); 1649 request.load_flags = 0; 1650 1651 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1652 scoped_ptr<HttpTransaction> trans( 1653 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1654 1655 MockRead data_reads[] = { 1656 MockRead("HTTP/1.0 200 OK\r\n"), 1657 MockRead("Connection: keep-alive\r\n"), 1658 MockRead("Content-Length: 100\r\n\r\n"), 1659 MockRead("hello"), 1660 MockRead(SYNCHRONOUS, 0), 1661 }; 1662 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1663 session_deps_.socket_factory->AddSocketDataProvider(&data); 1664 1665 TestCompletionCallback callback; 1666 1667 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1668 EXPECT_EQ(ERR_IO_PENDING, rv); 1669 1670 rv = callback.WaitForResult(); 1671 EXPECT_EQ(OK, rv); 1672 1673 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1674 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1675 if (rv == ERR_IO_PENDING) 1676 rv = callback.WaitForResult(); 1677 EXPECT_EQ(5, rv); 1678 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1679 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 1680 1681 trans.reset(); 1682 base::MessageLoop::current()->RunUntilIdle(); 1683 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 1684 } 1685 1686 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) { 1687 HttpRequestInfo request; 1688 request.method = "GET"; 1689 request.url = GURL("http://www.google.com/"); 1690 request.load_flags = 0; 1691 1692 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1693 scoped_ptr<HttpTransaction> trans( 1694 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1695 1696 MockRead data_reads[] = { 1697 MockRead("HTTP/1.0 200 OK\r\n"), 1698 MockRead("Connection: keep-alive\r\n"), 1699 MockRead("Content-Length: 100\r\n\r\n"), 1700 MockRead(SYNCHRONOUS, 0), 1701 }; 1702 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 1703 session_deps_.socket_factory->AddSocketDataProvider(&data); 1704 1705 TestCompletionCallback callback; 1706 1707 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1708 EXPECT_EQ(ERR_IO_PENDING, rv); 1709 1710 rv = callback.WaitForResult(); 1711 EXPECT_EQ(OK, rv); 1712 1713 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); 1714 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 1715 if (rv == ERR_IO_PENDING) 1716 rv = callback.WaitForResult(); 1717 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 1718 1719 trans.reset(); 1720 base::MessageLoop::current()->RunUntilIdle(); 1721 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 1722 } 1723 1724 // Test that we correctly reuse a keep-alive connection after not explicitly 1725 // reading the body. 1726 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { 1727 HttpRequestInfo request; 1728 request.method = "GET"; 1729 request.url = GURL("http://www.foo.com/"); 1730 request.load_flags = 0; 1731 1732 CapturingNetLog net_log; 1733 session_deps_.net_log = &net_log; 1734 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1735 1736 // Note that because all these reads happen in the same 1737 // StaticSocketDataProvider, it shows that the same socket is being reused for 1738 // all transactions. 1739 MockRead data1_reads[] = { 1740 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 1741 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"), 1742 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"), 1743 MockRead("HTTP/1.1 302 Found\r\n" 1744 "Content-Length: 0\r\n\r\n"), 1745 MockRead("HTTP/1.1 302 Found\r\n" 1746 "Content-Length: 5\r\n\r\n" 1747 "hello"), 1748 MockRead("HTTP/1.1 301 Moved Permanently\r\n" 1749 "Content-Length: 0\r\n\r\n"), 1750 MockRead("HTTP/1.1 301 Moved Permanently\r\n" 1751 "Content-Length: 5\r\n\r\n" 1752 "hello"), 1753 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1754 MockRead("hello"), 1755 }; 1756 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0); 1757 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1758 1759 MockRead data2_reads[] = { 1760 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 1761 }; 1762 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 1763 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1764 1765 const int kNumUnreadBodies = arraysize(data1_reads) - 2; 1766 std::string response_lines[kNumUnreadBodies]; 1767 1768 uint32 first_socket_log_id = NetLog::Source::kInvalidId; 1769 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) { 1770 TestCompletionCallback callback; 1771 1772 scoped_ptr<HttpTransaction> trans( 1773 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1774 1775 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1776 EXPECT_EQ(ERR_IO_PENDING, rv); 1777 1778 rv = callback.WaitForResult(); 1779 EXPECT_EQ(OK, rv); 1780 1781 LoadTimingInfo load_timing_info; 1782 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 1783 if (i == 0) { 1784 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); 1785 first_socket_log_id = load_timing_info.socket_log_id; 1786 } else { 1787 TestLoadTimingReused(load_timing_info); 1788 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id); 1789 } 1790 1791 const HttpResponseInfo* response = trans->GetResponseInfo(); 1792 ASSERT_TRUE(response != NULL); 1793 1794 ASSERT_TRUE(response->headers.get() != NULL); 1795 response_lines[i] = response->headers->GetStatusLine(); 1796 1797 // We intentionally don't read the response bodies. 1798 } 1799 1800 const char* const kStatusLines[] = { 1801 "HTTP/1.1 204 No Content", 1802 "HTTP/1.1 205 Reset Content", 1803 "HTTP/1.1 304 Not Modified", 1804 "HTTP/1.1 302 Found", 1805 "HTTP/1.1 302 Found", 1806 "HTTP/1.1 301 Moved Permanently", 1807 "HTTP/1.1 301 Moved Permanently", 1808 }; 1809 1810 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines), 1811 forgot_to_update_kStatusLines); 1812 1813 for (int i = 0; i < kNumUnreadBodies; ++i) 1814 EXPECT_EQ(kStatusLines[i], response_lines[i]); 1815 1816 TestCompletionCallback callback; 1817 scoped_ptr<HttpTransaction> trans( 1818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 1819 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1820 EXPECT_EQ(ERR_IO_PENDING, rv); 1821 rv = callback.WaitForResult(); 1822 EXPECT_EQ(OK, rv); 1823 const HttpResponseInfo* response = trans->GetResponseInfo(); 1824 ASSERT_TRUE(response != NULL); 1825 ASSERT_TRUE(response->headers.get() != NULL); 1826 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1827 std::string response_data; 1828 rv = ReadTransaction(trans.get(), &response_data); 1829 EXPECT_EQ(OK, rv); 1830 EXPECT_EQ("hello", response_data); 1831 } 1832 1833 // Test the request-challenge-retry sequence for basic auth. 1834 // (basic auth is the easiest to mock, because it has no randomness). 1835 TEST_P(HttpNetworkTransactionTest, BasicAuth) { 1836 HttpRequestInfo request; 1837 request.method = "GET"; 1838 request.url = GURL("http://www.google.com/"); 1839 request.load_flags = 0; 1840 1841 CapturingNetLog log; 1842 session_deps_.net_log = &log; 1843 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1844 scoped_ptr<HttpTransaction> trans( 1845 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1846 1847 MockWrite data_writes1[] = { 1848 MockWrite("GET / HTTP/1.1\r\n" 1849 "Host: www.google.com\r\n" 1850 "Connection: keep-alive\r\n\r\n"), 1851 }; 1852 1853 MockRead data_reads1[] = { 1854 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1855 // Give a couple authenticate options (only the middle one is actually 1856 // supported). 1857 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed. 1858 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1859 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 1860 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1861 // Large content-length -- won't matter, as connection will be reset. 1862 MockRead("Content-Length: 10000\r\n\r\n"), 1863 MockRead(SYNCHRONOUS, ERR_FAILED), 1864 }; 1865 1866 // After calling trans->RestartWithAuth(), this is the request we should 1867 // be issuing -- the final header line contains the credentials. 1868 MockWrite data_writes2[] = { 1869 MockWrite("GET / HTTP/1.1\r\n" 1870 "Host: www.google.com\r\n" 1871 "Connection: keep-alive\r\n" 1872 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1873 }; 1874 1875 // Lastly, the server responds with the actual content. 1876 MockRead data_reads2[] = { 1877 MockRead("HTTP/1.0 200 OK\r\n"), 1878 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1879 MockRead("Content-Length: 100\r\n\r\n"), 1880 MockRead(SYNCHRONOUS, OK), 1881 }; 1882 1883 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1884 data_writes1, arraysize(data_writes1)); 1885 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1886 data_writes2, arraysize(data_writes2)); 1887 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1888 session_deps_.socket_factory->AddSocketDataProvider(&data2); 1889 1890 TestCompletionCallback callback1; 1891 1892 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 1893 EXPECT_EQ(ERR_IO_PENDING, rv); 1894 1895 rv = callback1.WaitForResult(); 1896 EXPECT_EQ(OK, rv); 1897 1898 LoadTimingInfo load_timing_info1; 1899 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); 1900 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); 1901 1902 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1)); 1903 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); 1904 1905 const HttpResponseInfo* response = trans->GetResponseInfo(); 1906 ASSERT_TRUE(response != NULL); 1907 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 1908 1909 TestCompletionCallback callback2; 1910 1911 rv = trans->RestartWithAuth( 1912 AuthCredentials(kFoo, kBar), callback2.callback()); 1913 EXPECT_EQ(ERR_IO_PENDING, rv); 1914 1915 rv = callback2.WaitForResult(); 1916 EXPECT_EQ(OK, rv); 1917 1918 LoadTimingInfo load_timing_info2; 1919 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); 1920 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES); 1921 // The load timing after restart should have a new socket ID, and times after 1922 // those of the first load timing. 1923 EXPECT_LE(load_timing_info1.receive_headers_end, 1924 load_timing_info2.connect_timing.connect_start); 1925 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 1926 1927 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2)); 1928 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes()); 1929 1930 response = trans->GetResponseInfo(); 1931 ASSERT_TRUE(response != NULL); 1932 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1933 EXPECT_EQ(100, response->headers->GetContentLength()); 1934 } 1935 1936 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) { 1937 HttpRequestInfo request; 1938 request.method = "GET"; 1939 request.url = GURL("http://www.google.com/"); 1940 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 1941 1942 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1943 scoped_ptr<HttpTransaction> trans( 1944 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1945 1946 MockWrite data_writes[] = { 1947 MockWrite("GET / HTTP/1.1\r\n" 1948 "Host: www.google.com\r\n" 1949 "Connection: keep-alive\r\n\r\n"), 1950 }; 1951 1952 MockRead data_reads[] = { 1953 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1954 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1955 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1956 // Large content-length -- won't matter, as connection will be reset. 1957 MockRead("Content-Length: 10000\r\n\r\n"), 1958 MockRead(SYNCHRONOUS, ERR_FAILED), 1959 }; 1960 1961 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 1962 data_writes, arraysize(data_writes)); 1963 session_deps_.socket_factory->AddSocketDataProvider(&data); 1964 TestCompletionCallback callback; 1965 1966 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 1967 EXPECT_EQ(ERR_IO_PENDING, rv); 1968 1969 rv = callback.WaitForResult(); 1970 EXPECT_EQ(0, rv); 1971 1972 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads)); 1973 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes()); 1974 1975 const HttpResponseInfo* response = trans->GetResponseInfo(); 1976 ASSERT_TRUE(response != NULL); 1977 EXPECT_TRUE(response->auth_challenge.get() == NULL); 1978 } 1979 1980 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 1981 // connection. 1982 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) { 1983 HttpRequestInfo request; 1984 request.method = "GET"; 1985 request.url = GURL("http://www.google.com/"); 1986 request.load_flags = 0; 1987 1988 CapturingNetLog log; 1989 session_deps_.net_log = &log; 1990 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1991 1992 MockWrite data_writes1[] = { 1993 MockWrite("GET / HTTP/1.1\r\n" 1994 "Host: www.google.com\r\n" 1995 "Connection: keep-alive\r\n\r\n"), 1996 1997 // After calling trans->RestartWithAuth(), this is the request we should 1998 // be issuing -- the final header line contains the credentials. 1999 MockWrite("GET / HTTP/1.1\r\n" 2000 "Host: www.google.com\r\n" 2001 "Connection: keep-alive\r\n" 2002 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2003 }; 2004 2005 MockRead data_reads1[] = { 2006 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2007 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2008 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2009 MockRead("Content-Length: 14\r\n\r\n"), 2010 MockRead("Unauthorized\r\n"), 2011 2012 // Lastly, the server responds with the actual content. 2013 MockRead("HTTP/1.1 200 OK\r\n"), 2014 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2015 MockRead("Content-Length: 5\r\n\r\n"), 2016 MockRead("Hello"), 2017 }; 2018 2019 // If there is a regression where we disconnect a Keep-Alive 2020 // connection during an auth roundtrip, we'll end up reading this. 2021 MockRead data_reads2[] = { 2022 MockRead(SYNCHRONOUS, ERR_FAILED), 2023 }; 2024 2025 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2026 data_writes1, arraysize(data_writes1)); 2027 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2028 NULL, 0); 2029 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2030 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2031 2032 TestCompletionCallback callback1; 2033 2034 scoped_ptr<HttpTransaction> trans( 2035 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2036 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2037 EXPECT_EQ(ERR_IO_PENDING, rv); 2038 2039 rv = callback1.WaitForResult(); 2040 EXPECT_EQ(OK, rv); 2041 2042 LoadTimingInfo load_timing_info1; 2043 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); 2044 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); 2045 2046 const HttpResponseInfo* response = trans->GetResponseInfo(); 2047 ASSERT_TRUE(response != NULL); 2048 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2049 2050 TestCompletionCallback callback2; 2051 2052 rv = trans->RestartWithAuth( 2053 AuthCredentials(kFoo, kBar), callback2.callback()); 2054 EXPECT_EQ(ERR_IO_PENDING, rv); 2055 2056 rv = callback2.WaitForResult(); 2057 EXPECT_EQ(OK, rv); 2058 2059 LoadTimingInfo load_timing_info2; 2060 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); 2061 TestLoadTimingReused(load_timing_info2); 2062 // The load timing after restart should have the same socket ID, and times 2063 // those of the first load timing. 2064 EXPECT_LE(load_timing_info1.receive_headers_end, 2065 load_timing_info2.send_start); 2066 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2067 2068 response = trans->GetResponseInfo(); 2069 ASSERT_TRUE(response != NULL); 2070 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2071 EXPECT_EQ(5, response->headers->GetContentLength()); 2072 2073 std::string response_data; 2074 rv = ReadTransaction(trans.get(), &response_data); 2075 EXPECT_EQ(OK, rv); 2076 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1)); 2077 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); 2078 } 2079 2080 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2081 // connection and with no response body to drain. 2082 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { 2083 HttpRequestInfo request; 2084 request.method = "GET"; 2085 request.url = GURL("http://www.google.com/"); 2086 request.load_flags = 0; 2087 2088 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2089 2090 MockWrite data_writes1[] = { 2091 MockWrite("GET / HTTP/1.1\r\n" 2092 "Host: www.google.com\r\n" 2093 "Connection: keep-alive\r\n\r\n"), 2094 2095 // After calling trans->RestartWithAuth(), this is the request we should 2096 // be issuing -- the final header line contains the credentials. 2097 MockWrite("GET / HTTP/1.1\r\n" 2098 "Host: www.google.com\r\n" 2099 "Connection: keep-alive\r\n" 2100 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2101 }; 2102 2103 MockRead data_reads1[] = { 2104 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2105 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2106 MockRead("Content-Length: 0\r\n\r\n"), // No response body. 2107 2108 // Lastly, the server responds with the actual content. 2109 MockRead("HTTP/1.1 200 OK\r\n"), 2110 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2111 MockRead("Content-Length: 5\r\n\r\n"), 2112 MockRead("hello"), 2113 }; 2114 2115 // An incorrect reconnect would cause this to be read. 2116 MockRead data_reads2[] = { 2117 MockRead(SYNCHRONOUS, ERR_FAILED), 2118 }; 2119 2120 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2121 data_writes1, arraysize(data_writes1)); 2122 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2123 NULL, 0); 2124 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2125 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2126 2127 TestCompletionCallback callback1; 2128 2129 scoped_ptr<HttpTransaction> trans( 2130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2131 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2132 EXPECT_EQ(ERR_IO_PENDING, rv); 2133 2134 rv = callback1.WaitForResult(); 2135 EXPECT_EQ(OK, rv); 2136 2137 const HttpResponseInfo* response = trans->GetResponseInfo(); 2138 ASSERT_TRUE(response != NULL); 2139 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2140 2141 TestCompletionCallback callback2; 2142 2143 rv = trans->RestartWithAuth( 2144 AuthCredentials(kFoo, kBar), callback2.callback()); 2145 EXPECT_EQ(ERR_IO_PENDING, rv); 2146 2147 rv = callback2.WaitForResult(); 2148 EXPECT_EQ(OK, rv); 2149 2150 response = trans->GetResponseInfo(); 2151 ASSERT_TRUE(response != NULL); 2152 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2153 EXPECT_EQ(5, response->headers->GetContentLength()); 2154 } 2155 2156 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2157 // connection and with a large response body to drain. 2158 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { 2159 HttpRequestInfo request; 2160 request.method = "GET"; 2161 request.url = GURL("http://www.google.com/"); 2162 request.load_flags = 0; 2163 2164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2165 2166 MockWrite data_writes1[] = { 2167 MockWrite("GET / HTTP/1.1\r\n" 2168 "Host: www.google.com\r\n" 2169 "Connection: keep-alive\r\n\r\n"), 2170 2171 // After calling trans->RestartWithAuth(), this is the request we should 2172 // be issuing -- the final header line contains the credentials. 2173 MockWrite("GET / HTTP/1.1\r\n" 2174 "Host: www.google.com\r\n" 2175 "Connection: keep-alive\r\n" 2176 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2177 }; 2178 2179 // Respond with 5 kb of response body. 2180 std::string large_body_string("Unauthorized"); 2181 large_body_string.append(5 * 1024, ' '); 2182 large_body_string.append("\r\n"); 2183 2184 MockRead data_reads1[] = { 2185 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2186 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2187 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2188 // 5134 = 12 + 5 * 1024 + 2 2189 MockRead("Content-Length: 5134\r\n\r\n"), 2190 MockRead(ASYNC, large_body_string.data(), large_body_string.size()), 2191 2192 // Lastly, the server responds with the actual content. 2193 MockRead("HTTP/1.1 200 OK\r\n"), 2194 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2195 MockRead("Content-Length: 5\r\n\r\n"), 2196 MockRead("hello"), 2197 }; 2198 2199 // An incorrect reconnect would cause this to be read. 2200 MockRead data_reads2[] = { 2201 MockRead(SYNCHRONOUS, ERR_FAILED), 2202 }; 2203 2204 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2205 data_writes1, arraysize(data_writes1)); 2206 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2207 NULL, 0); 2208 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2209 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2210 2211 TestCompletionCallback callback1; 2212 2213 scoped_ptr<HttpTransaction> trans( 2214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2215 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2216 EXPECT_EQ(ERR_IO_PENDING, rv); 2217 2218 rv = callback1.WaitForResult(); 2219 EXPECT_EQ(OK, rv); 2220 2221 const HttpResponseInfo* response = trans->GetResponseInfo(); 2222 ASSERT_TRUE(response != NULL); 2223 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2224 2225 TestCompletionCallback callback2; 2226 2227 rv = trans->RestartWithAuth( 2228 AuthCredentials(kFoo, kBar), callback2.callback()); 2229 EXPECT_EQ(ERR_IO_PENDING, rv); 2230 2231 rv = callback2.WaitForResult(); 2232 EXPECT_EQ(OK, rv); 2233 2234 response = trans->GetResponseInfo(); 2235 ASSERT_TRUE(response != NULL); 2236 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2237 EXPECT_EQ(5, response->headers->GetContentLength()); 2238 } 2239 2240 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2241 // connection, but the server gets impatient and closes the connection. 2242 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { 2243 HttpRequestInfo request; 2244 request.method = "GET"; 2245 request.url = GURL("http://www.google.com/"); 2246 request.load_flags = 0; 2247 2248 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2249 2250 MockWrite data_writes1[] = { 2251 MockWrite("GET / HTTP/1.1\r\n" 2252 "Host: www.google.com\r\n" 2253 "Connection: keep-alive\r\n\r\n"), 2254 // This simulates the seemingly successful write to a closed connection 2255 // if the bug is not fixed. 2256 MockWrite("GET / HTTP/1.1\r\n" 2257 "Host: www.google.com\r\n" 2258 "Connection: keep-alive\r\n" 2259 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2260 }; 2261 2262 MockRead data_reads1[] = { 2263 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 2264 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2265 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2266 MockRead("Content-Length: 14\r\n\r\n"), 2267 // Tell MockTCPClientSocket to simulate the server closing the connection. 2268 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 2269 MockRead("Unauthorized\r\n"), 2270 MockRead(SYNCHRONOUS, OK), // The server closes the connection. 2271 }; 2272 2273 // After calling trans->RestartWithAuth(), this is the request we should 2274 // be issuing -- the final header line contains the credentials. 2275 MockWrite data_writes2[] = { 2276 MockWrite("GET / HTTP/1.1\r\n" 2277 "Host: www.google.com\r\n" 2278 "Connection: keep-alive\r\n" 2279 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2280 }; 2281 2282 // Lastly, the server responds with the actual content. 2283 MockRead data_reads2[] = { 2284 MockRead("HTTP/1.1 200 OK\r\n"), 2285 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2286 MockRead("Content-Length: 5\r\n\r\n"), 2287 MockRead("hello"), 2288 }; 2289 2290 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2291 data_writes1, arraysize(data_writes1)); 2292 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2293 data_writes2, arraysize(data_writes2)); 2294 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2295 session_deps_.socket_factory->AddSocketDataProvider(&data2); 2296 2297 TestCompletionCallback callback1; 2298 2299 scoped_ptr<HttpTransaction> trans( 2300 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2301 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 2302 EXPECT_EQ(ERR_IO_PENDING, rv); 2303 2304 rv = callback1.WaitForResult(); 2305 EXPECT_EQ(OK, rv); 2306 2307 const HttpResponseInfo* response = trans->GetResponseInfo(); 2308 ASSERT_TRUE(response != NULL); 2309 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 2310 2311 TestCompletionCallback callback2; 2312 2313 rv = trans->RestartWithAuth( 2314 AuthCredentials(kFoo, kBar), callback2.callback()); 2315 EXPECT_EQ(ERR_IO_PENDING, rv); 2316 2317 rv = callback2.WaitForResult(); 2318 EXPECT_EQ(OK, rv); 2319 2320 response = trans->GetResponseInfo(); 2321 ASSERT_TRUE(response != NULL); 2322 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2323 EXPECT_EQ(5, response->headers->GetContentLength()); 2324 } 2325 2326 // Test the request-challenge-retry sequence for basic auth, over a connection 2327 // that requires a restart when setting up an SSL tunnel. 2328 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { 2329 HttpRequestInfo request; 2330 request.method = "GET"; 2331 request.url = GURL("https://www.google.com/"); 2332 // when the no authentication data flag is set. 2333 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 2334 2335 // Configure against proxy server "myproxy:70". 2336 session_deps_.proxy_service.reset( 2337 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 2338 CapturingBoundNetLog log; 2339 session_deps_.net_log = log.bound().net_log(); 2340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2341 2342 // Since we have proxy, should try to establish tunnel. 2343 MockWrite data_writes1[] = { 2344 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2345 "Host: www.google.com\r\n" 2346 "Proxy-Connection: keep-alive\r\n\r\n"), 2347 2348 // After calling trans->RestartWithAuth(), this is the request we should 2349 // be issuing -- the final header line contains the credentials. 2350 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2351 "Host: www.google.com\r\n" 2352 "Proxy-Connection: keep-alive\r\n" 2353 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2354 2355 MockWrite("GET / HTTP/1.1\r\n" 2356 "Host: www.google.com\r\n" 2357 "Connection: keep-alive\r\n\r\n"), 2358 }; 2359 2360 // The proxy responds to the connect with a 407, using a persistent 2361 // connection. 2362 MockRead data_reads1[] = { 2363 // No credentials. 2364 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2365 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2366 MockRead("Proxy-Connection: close\r\n\r\n"), 2367 2368 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2369 2370 MockRead("HTTP/1.1 200 OK\r\n"), 2371 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2372 MockRead("Content-Length: 5\r\n\r\n"), 2373 MockRead(SYNCHRONOUS, "hello"), 2374 }; 2375 2376 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2377 data_writes1, arraysize(data_writes1)); 2378 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2379 SSLSocketDataProvider ssl(ASYNC, OK); 2380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2381 2382 TestCompletionCallback callback1; 2383 2384 scoped_ptr<HttpTransaction> trans( 2385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2386 2387 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2388 EXPECT_EQ(ERR_IO_PENDING, rv); 2389 2390 rv = callback1.WaitForResult(); 2391 EXPECT_EQ(OK, rv); 2392 net::CapturingNetLog::CapturedEntryList entries; 2393 log.GetEntries(&entries); 2394 size_t pos = ExpectLogContainsSomewhere( 2395 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2396 NetLog::PHASE_NONE); 2397 ExpectLogContainsSomewhere( 2398 entries, pos, 2399 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2400 NetLog::PHASE_NONE); 2401 2402 const HttpResponseInfo* response = trans->GetResponseInfo(); 2403 ASSERT_TRUE(response != NULL); 2404 ASSERT_FALSE(response->headers.get() == NULL); 2405 EXPECT_EQ(407, response->headers->response_code()); 2406 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2407 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2408 2409 LoadTimingInfo load_timing_info; 2410 // CONNECT requests and responses are handled at the connect job level, so 2411 // the transaction does not yet have a connection. 2412 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); 2413 2414 TestCompletionCallback callback2; 2415 2416 rv = trans->RestartWithAuth( 2417 AuthCredentials(kFoo, kBar), callback2.callback()); 2418 EXPECT_EQ(ERR_IO_PENDING, rv); 2419 2420 rv = callback2.WaitForResult(); 2421 EXPECT_EQ(OK, rv); 2422 2423 response = trans->GetResponseInfo(); 2424 ASSERT_TRUE(response != NULL); 2425 2426 EXPECT_TRUE(response->headers->IsKeepAlive()); 2427 EXPECT_EQ(200, response->headers->response_code()); 2428 EXPECT_EQ(5, response->headers->GetContentLength()); 2429 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2430 2431 // The password prompt info should not be set. 2432 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2433 2434 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 2435 TestLoadTimingNotReusedWithPac(load_timing_info, 2436 CONNECT_TIMING_HAS_SSL_TIMES); 2437 2438 trans.reset(); 2439 session->CloseAllConnections(); 2440 } 2441 2442 // Test the request-challenge-retry sequence for basic auth, over a keep-alive 2443 // proxy connection, when setting up an SSL tunnel. 2444 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { 2445 HttpRequestInfo request; 2446 request.method = "GET"; 2447 request.url = GURL("https://www.google.com/"); 2448 // Ensure that proxy authentication is attempted even 2449 // when the no authentication data flag is set. 2450 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 2451 2452 // Configure against proxy server "myproxy:70". 2453 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2454 CapturingBoundNetLog log; 2455 session_deps_.net_log = log.bound().net_log(); 2456 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2457 2458 scoped_ptr<HttpTransaction> trans( 2459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2460 2461 // Since we have proxy, should try to establish tunnel. 2462 MockWrite data_writes1[] = { 2463 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2464 "Host: www.google.com\r\n" 2465 "Proxy-Connection: keep-alive\r\n\r\n"), 2466 2467 // After calling trans->RestartWithAuth(), this is the request we should 2468 // be issuing -- the final header line contains the credentials. 2469 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2470 "Host: www.google.com\r\n" 2471 "Proxy-Connection: keep-alive\r\n" 2472 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 2473 }; 2474 2475 // The proxy responds to the connect with a 407, using a persistent 2476 // connection. 2477 MockRead data_reads1[] = { 2478 // No credentials. 2479 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2480 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2481 MockRead("Content-Length: 10\r\n\r\n"), 2482 MockRead("0123456789"), 2483 2484 // Wrong credentials (wrong password). 2485 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2486 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2487 MockRead("Content-Length: 10\r\n\r\n"), 2488 // No response body because the test stops reading here. 2489 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 2490 }; 2491 2492 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2493 data_writes1, arraysize(data_writes1)); 2494 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2495 2496 TestCompletionCallback callback1; 2497 2498 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2499 EXPECT_EQ(ERR_IO_PENDING, rv); 2500 2501 rv = callback1.WaitForResult(); 2502 EXPECT_EQ(OK, rv); 2503 net::CapturingNetLog::CapturedEntryList entries; 2504 log.GetEntries(&entries); 2505 size_t pos = ExpectLogContainsSomewhere( 2506 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2507 NetLog::PHASE_NONE); 2508 ExpectLogContainsSomewhere( 2509 entries, pos, 2510 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2511 NetLog::PHASE_NONE); 2512 2513 const HttpResponseInfo* response = trans->GetResponseInfo(); 2514 ASSERT_TRUE(response != NULL); 2515 ASSERT_FALSE(response->headers.get() == NULL); 2516 EXPECT_TRUE(response->headers->IsKeepAlive()); 2517 EXPECT_EQ(407, response->headers->response_code()); 2518 EXPECT_EQ(10, response->headers->GetContentLength()); 2519 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2520 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2521 2522 TestCompletionCallback callback2; 2523 2524 // Wrong password (should be "bar"). 2525 rv = trans->RestartWithAuth( 2526 AuthCredentials(kFoo, kBaz), callback2.callback()); 2527 EXPECT_EQ(ERR_IO_PENDING, rv); 2528 2529 rv = callback2.WaitForResult(); 2530 EXPECT_EQ(OK, rv); 2531 2532 response = trans->GetResponseInfo(); 2533 ASSERT_TRUE(response != NULL); 2534 ASSERT_FALSE(response->headers.get() == NULL); 2535 EXPECT_TRUE(response->headers->IsKeepAlive()); 2536 EXPECT_EQ(407, response->headers->response_code()); 2537 EXPECT_EQ(10, response->headers->GetContentLength()); 2538 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2539 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 2540 2541 // Flush the idle socket before the NetLog and HttpNetworkTransaction go 2542 // out of scope. 2543 session->CloseAllConnections(); 2544 } 2545 2546 // Test that we don't read the response body when we fail to establish a tunnel, 2547 // even if the user cancels the proxy's auth attempt. 2548 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { 2549 HttpRequestInfo request; 2550 request.method = "GET"; 2551 request.url = GURL("https://www.google.com/"); 2552 request.load_flags = 0; 2553 2554 // Configure against proxy server "myproxy:70". 2555 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2556 2557 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2558 2559 scoped_ptr<HttpTransaction> trans( 2560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2561 2562 // Since we have proxy, should try to establish tunnel. 2563 MockWrite data_writes[] = { 2564 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2565 "Host: www.google.com\r\n" 2566 "Proxy-Connection: keep-alive\r\n\r\n"), 2567 }; 2568 2569 // The proxy responds to the connect with a 407. 2570 MockRead data_reads[] = { 2571 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2572 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2573 MockRead("Content-Length: 10\r\n\r\n"), 2574 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 2575 }; 2576 2577 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 2578 data_writes, arraysize(data_writes)); 2579 session_deps_.socket_factory->AddSocketDataProvider(&data); 2580 2581 TestCompletionCallback callback; 2582 2583 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 2584 EXPECT_EQ(ERR_IO_PENDING, rv); 2585 2586 rv = callback.WaitForResult(); 2587 EXPECT_EQ(OK, rv); 2588 2589 const HttpResponseInfo* response = trans->GetResponseInfo(); 2590 ASSERT_TRUE(response != NULL); 2591 2592 EXPECT_TRUE(response->headers->IsKeepAlive()); 2593 EXPECT_EQ(407, response->headers->response_code()); 2594 EXPECT_EQ(10, response->headers->GetContentLength()); 2595 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2596 2597 std::string response_data; 2598 rv = ReadTransaction(trans.get(), &response_data); 2599 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 2600 2601 // Flush the idle socket before the HttpNetworkTransaction goes out of scope. 2602 session->CloseAllConnections(); 2603 } 2604 2605 // Test when a server (non-proxy) returns a 407 (proxy-authenticate). 2606 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH. 2607 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) { 2608 HttpRequestInfo request; 2609 request.method = "GET"; 2610 request.url = GURL("http://www.google.com/"); 2611 request.load_flags = 0; 2612 2613 // We are using a DIRECT connection (i.e. no proxy) for this session. 2614 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2615 scoped_ptr<HttpTransaction> trans( 2616 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 2617 2618 MockWrite data_writes1[] = { 2619 MockWrite("GET / HTTP/1.1\r\n" 2620 "Host: www.google.com\r\n" 2621 "Connection: keep-alive\r\n\r\n"), 2622 }; 2623 2624 MockRead data_reads1[] = { 2625 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"), 2626 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2627 // Large content-length -- won't matter, as connection will be reset. 2628 MockRead("Content-Length: 10000\r\n\r\n"), 2629 MockRead(SYNCHRONOUS, ERR_FAILED), 2630 }; 2631 2632 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2633 data_writes1, arraysize(data_writes1)); 2634 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2635 2636 TestCompletionCallback callback; 2637 2638 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 2639 EXPECT_EQ(ERR_IO_PENDING, rv); 2640 2641 rv = callback.WaitForResult(); 2642 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 2643 } 2644 2645 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication) 2646 // through a non-authenticating proxy. The request should fail with 2647 // ERR_UNEXPECTED_PROXY_AUTH. 2648 // Note that it is impossible to detect if an HTTP server returns a 407 through 2649 // a non-authenticating proxy - there is nothing to indicate whether the 2650 // response came from the proxy or the server, so it is treated as if the proxy 2651 // issued the challenge. 2652 TEST_P(HttpNetworkTransactionTest, 2653 HttpsServerRequestsProxyAuthThroughProxy) { 2654 HttpRequestInfo request; 2655 request.method = "GET"; 2656 request.url = GURL("https://www.google.com/"); 2657 2658 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 2659 CapturingBoundNetLog log; 2660 session_deps_.net_log = log.bound().net_log(); 2661 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2662 2663 // Since we have proxy, should try to establish tunnel. 2664 MockWrite data_writes1[] = { 2665 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2666 "Host: www.google.com\r\n" 2667 "Proxy-Connection: keep-alive\r\n\r\n"), 2668 2669 MockWrite("GET / HTTP/1.1\r\n" 2670 "Host: www.google.com\r\n" 2671 "Connection: keep-alive\r\n\r\n"), 2672 }; 2673 2674 MockRead data_reads1[] = { 2675 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2676 2677 MockRead("HTTP/1.1 407 Unauthorized\r\n"), 2678 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2679 MockRead("\r\n"), 2680 MockRead(SYNCHRONOUS, OK), 2681 }; 2682 2683 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2684 data_writes1, arraysize(data_writes1)); 2685 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2686 SSLSocketDataProvider ssl(ASYNC, OK); 2687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2688 2689 TestCompletionCallback callback1; 2690 2691 scoped_ptr<HttpTransaction> trans( 2692 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2693 2694 int rv = trans->Start(&request, callback1.callback(), log.bound()); 2695 EXPECT_EQ(ERR_IO_PENDING, rv); 2696 2697 rv = callback1.WaitForResult(); 2698 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 2699 net::CapturingNetLog::CapturedEntryList entries; 2700 log.GetEntries(&entries); 2701 size_t pos = ExpectLogContainsSomewhere( 2702 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 2703 NetLog::PHASE_NONE); 2704 ExpectLogContainsSomewhere( 2705 entries, pos, 2706 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 2707 NetLog::PHASE_NONE); 2708 } 2709 2710 // Test the load timing for HTTPS requests with an HTTP proxy. 2711 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) { 2712 HttpRequestInfo request1; 2713 request1.method = "GET"; 2714 request1.url = GURL("https://www.google.com/1"); 2715 2716 HttpRequestInfo request2; 2717 request2.method = "GET"; 2718 request2.url = GURL("https://www.google.com/2"); 2719 2720 // Configure against proxy server "myproxy:70". 2721 session_deps_.proxy_service.reset( 2722 ProxyService::CreateFixed("PROXY myproxy:70")); 2723 CapturingBoundNetLog log; 2724 session_deps_.net_log = log.bound().net_log(); 2725 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2726 2727 // Since we have proxy, should try to establish tunnel. 2728 MockWrite data_writes1[] = { 2729 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2730 "Host: www.google.com\r\n" 2731 "Proxy-Connection: keep-alive\r\n\r\n"), 2732 2733 MockWrite("GET /1 HTTP/1.1\r\n" 2734 "Host: www.google.com\r\n" 2735 "Connection: keep-alive\r\n\r\n"), 2736 2737 MockWrite("GET /2 HTTP/1.1\r\n" 2738 "Host: www.google.com\r\n" 2739 "Connection: keep-alive\r\n\r\n"), 2740 }; 2741 2742 // The proxy responds to the connect with a 407, using a persistent 2743 // connection. 2744 MockRead data_reads1[] = { 2745 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2746 2747 MockRead("HTTP/1.1 200 OK\r\n"), 2748 MockRead("Content-Length: 1\r\n\r\n"), 2749 MockRead(SYNCHRONOUS, "1"), 2750 2751 MockRead("HTTP/1.1 200 OK\r\n"), 2752 MockRead("Content-Length: 2\r\n\r\n"), 2753 MockRead(SYNCHRONOUS, "22"), 2754 }; 2755 2756 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2757 data_writes1, arraysize(data_writes1)); 2758 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2759 SSLSocketDataProvider ssl(ASYNC, OK); 2760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2761 2762 TestCompletionCallback callback1; 2763 scoped_ptr<HttpTransaction> trans1( 2764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2765 2766 int rv = trans1->Start(&request1, callback1.callback(), log.bound()); 2767 EXPECT_EQ(ERR_IO_PENDING, rv); 2768 2769 rv = callback1.WaitForResult(); 2770 EXPECT_EQ(OK, rv); 2771 2772 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 2773 ASSERT_TRUE(response1 != NULL); 2774 ASSERT_TRUE(response1->headers.get() != NULL); 2775 EXPECT_EQ(1, response1->headers->GetContentLength()); 2776 2777 LoadTimingInfo load_timing_info1; 2778 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1)); 2779 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES); 2780 2781 trans1.reset(); 2782 2783 TestCompletionCallback callback2; 2784 scoped_ptr<HttpTransaction> trans2( 2785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2786 2787 rv = trans2->Start(&request2, callback2.callback(), log.bound()); 2788 EXPECT_EQ(ERR_IO_PENDING, rv); 2789 2790 rv = callback2.WaitForResult(); 2791 EXPECT_EQ(OK, rv); 2792 2793 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 2794 ASSERT_TRUE(response2 != NULL); 2795 ASSERT_TRUE(response2->headers.get() != NULL); 2796 EXPECT_EQ(2, response2->headers->GetContentLength()); 2797 2798 LoadTimingInfo load_timing_info2; 2799 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 2800 TestLoadTimingReused(load_timing_info2); 2801 2802 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2803 2804 trans2.reset(); 2805 session->CloseAllConnections(); 2806 } 2807 2808 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script. 2809 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) { 2810 HttpRequestInfo request1; 2811 request1.method = "GET"; 2812 request1.url = GURL("https://www.google.com/1"); 2813 2814 HttpRequestInfo request2; 2815 request2.method = "GET"; 2816 request2.url = GURL("https://www.google.com/2"); 2817 2818 // Configure against proxy server "myproxy:70". 2819 session_deps_.proxy_service.reset( 2820 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 2821 CapturingBoundNetLog log; 2822 session_deps_.net_log = log.bound().net_log(); 2823 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2824 2825 // Since we have proxy, should try to establish tunnel. 2826 MockWrite data_writes1[] = { 2827 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 2828 "Host: www.google.com\r\n" 2829 "Proxy-Connection: keep-alive\r\n\r\n"), 2830 2831 MockWrite("GET /1 HTTP/1.1\r\n" 2832 "Host: www.google.com\r\n" 2833 "Connection: keep-alive\r\n\r\n"), 2834 2835 MockWrite("GET /2 HTTP/1.1\r\n" 2836 "Host: www.google.com\r\n" 2837 "Connection: keep-alive\r\n\r\n"), 2838 }; 2839 2840 // The proxy responds to the connect with a 407, using a persistent 2841 // connection. 2842 MockRead data_reads1[] = { 2843 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 2844 2845 MockRead("HTTP/1.1 200 OK\r\n"), 2846 MockRead("Content-Length: 1\r\n\r\n"), 2847 MockRead(SYNCHRONOUS, "1"), 2848 2849 MockRead("HTTP/1.1 200 OK\r\n"), 2850 MockRead("Content-Length: 2\r\n\r\n"), 2851 MockRead(SYNCHRONOUS, "22"), 2852 }; 2853 2854 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2855 data_writes1, arraysize(data_writes1)); 2856 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2857 SSLSocketDataProvider ssl(ASYNC, OK); 2858 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2859 2860 TestCompletionCallback callback1; 2861 scoped_ptr<HttpTransaction> trans1( 2862 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2863 2864 int rv = trans1->Start(&request1, callback1.callback(), log.bound()); 2865 EXPECT_EQ(ERR_IO_PENDING, rv); 2866 2867 rv = callback1.WaitForResult(); 2868 EXPECT_EQ(OK, rv); 2869 2870 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 2871 ASSERT_TRUE(response1 != NULL); 2872 ASSERT_TRUE(response1->headers.get() != NULL); 2873 EXPECT_EQ(1, response1->headers->GetContentLength()); 2874 2875 LoadTimingInfo load_timing_info1; 2876 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1)); 2877 TestLoadTimingNotReusedWithPac(load_timing_info1, 2878 CONNECT_TIMING_HAS_SSL_TIMES); 2879 2880 trans1.reset(); 2881 2882 TestCompletionCallback callback2; 2883 scoped_ptr<HttpTransaction> trans2( 2884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 2885 2886 rv = trans2->Start(&request2, callback2.callback(), log.bound()); 2887 EXPECT_EQ(ERR_IO_PENDING, rv); 2888 2889 rv = callback2.WaitForResult(); 2890 EXPECT_EQ(OK, rv); 2891 2892 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 2893 ASSERT_TRUE(response2 != NULL); 2894 ASSERT_TRUE(response2->headers.get() != NULL); 2895 EXPECT_EQ(2, response2->headers->GetContentLength()); 2896 2897 LoadTimingInfo load_timing_info2; 2898 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 2899 TestLoadTimingReusedWithPac(load_timing_info2); 2900 2901 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 2902 2903 trans2.reset(); 2904 session->CloseAllConnections(); 2905 } 2906 2907 // Test a simple get through an HTTPS Proxy. 2908 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) { 2909 HttpRequestInfo request; 2910 request.method = "GET"; 2911 request.url = GURL("http://www.google.com/"); 2912 2913 // Configure against https proxy server "proxy:70". 2914 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2915 "https://proxy:70")); 2916 CapturingBoundNetLog log; 2917 session_deps_.net_log = log.bound().net_log(); 2918 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2919 2920 // Since we have proxy, should use full url 2921 MockWrite data_writes1[] = { 2922 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 2923 "Host: www.google.com\r\n" 2924 "Proxy-Connection: keep-alive\r\n\r\n"), 2925 }; 2926 2927 MockRead data_reads1[] = { 2928 MockRead("HTTP/1.1 200 OK\r\n"), 2929 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2930 MockRead("Content-Length: 100\r\n\r\n"), 2931 MockRead(SYNCHRONOUS, OK), 2932 }; 2933 2934 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2935 data_writes1, arraysize(data_writes1)); 2936 session_deps_.socket_factory->AddSocketDataProvider(&data1); 2937 SSLSocketDataProvider ssl(ASYNC, OK); 2938 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2939 2940 TestCompletionCallback callback1; 2941 2942 scoped_ptr<HttpTransaction> trans( 2943 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 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, 2954 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 2955 2956 const HttpResponseInfo* response = trans->GetResponseInfo(); 2957 ASSERT_TRUE(response != NULL); 2958 2959 EXPECT_TRUE(response->headers->IsKeepAlive()); 2960 EXPECT_EQ(200, response->headers->response_code()); 2961 EXPECT_EQ(100, response->headers->GetContentLength()); 2962 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 2963 2964 // The password prompt info should not be set. 2965 EXPECT_TRUE(response->auth_challenge.get() == NULL); 2966 } 2967 2968 // Test a SPDY get through an HTTPS Proxy. 2969 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) { 2970 HttpRequestInfo request; 2971 request.method = "GET"; 2972 request.url = GURL("http://www.google.com/"); 2973 request.load_flags = 0; 2974 2975 // Configure against https proxy server "proxy:70". 2976 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 2977 "https://proxy:70")); 2978 CapturingBoundNetLog log; 2979 session_deps_.net_log = log.bound().net_log(); 2980 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 2981 2982 // fetch http://www.google.com/ via SPDY 2983 scoped_ptr<SpdyFrame> req( 2984 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 2985 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 2986 2987 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2988 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2989 MockRead spdy_reads[] = { 2990 CreateMockRead(*resp), 2991 CreateMockRead(*data), 2992 MockRead(ASYNC, 0, 0), 2993 }; 2994 2995 DelayedSocketData spdy_data( 2996 1, // wait for one write to finish before reading. 2997 spdy_reads, arraysize(spdy_reads), 2998 spdy_writes, arraysize(spdy_writes)); 2999 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3000 3001 SSLSocketDataProvider ssl(ASYNC, OK); 3002 ssl.SetNextProto(GetParam()); 3003 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3004 3005 TestCompletionCallback callback1; 3006 3007 scoped_ptr<HttpTransaction> trans( 3008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3009 3010 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3011 EXPECT_EQ(ERR_IO_PENDING, rv); 3012 3013 rv = callback1.WaitForResult(); 3014 EXPECT_EQ(OK, rv); 3015 3016 LoadTimingInfo load_timing_info; 3017 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3018 TestLoadTimingNotReused(load_timing_info, 3019 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3020 3021 const HttpResponseInfo* response = trans->GetResponseInfo(); 3022 ASSERT_TRUE(response != NULL); 3023 ASSERT_TRUE(response->headers.get() != NULL); 3024 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3025 3026 std::string response_data; 3027 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3028 EXPECT_EQ(kUploadData, response_data); 3029 } 3030 3031 // Verifies that a session which races and wins against the owning transaction 3032 // (completing prior to host resolution), doesn't fail the transaction. 3033 // Regression test for crbug.com/334413. 3034 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) { 3035 HttpRequestInfo request; 3036 request.method = "GET"; 3037 request.url = GURL("http://www.google.com/"); 3038 request.load_flags = 0; 3039 3040 // Configure SPDY proxy server "proxy:70". 3041 session_deps_.proxy_service.reset( 3042 ProxyService::CreateFixed("https://proxy:70")); 3043 CapturingBoundNetLog log; 3044 session_deps_.net_log = log.bound().net_log(); 3045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3046 3047 // Fetch http://www.google.com/ through the SPDY proxy. 3048 scoped_ptr<SpdyFrame> req( 3049 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 3050 MockWrite spdy_writes[] = {CreateMockWrite(*req)}; 3051 3052 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3053 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3054 MockRead spdy_reads[] = { 3055 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0), 3056 }; 3057 3058 DelayedSocketData spdy_data( 3059 1, // wait for one write to finish before reading. 3060 spdy_reads, 3061 arraysize(spdy_reads), 3062 spdy_writes, 3063 arraysize(spdy_writes)); 3064 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3065 3066 SSLSocketDataProvider ssl(ASYNC, OK); 3067 ssl.SetNextProto(GetParam()); 3068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3069 3070 TestCompletionCallback callback1; 3071 3072 scoped_ptr<HttpTransaction> trans( 3073 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3074 3075 // Stall the hostname resolution begun by the transaction. 3076 session_deps_.host_resolver->set_synchronous_mode(false); 3077 session_deps_.host_resolver->set_ondemand_mode(true); 3078 3079 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3080 EXPECT_EQ(ERR_IO_PENDING, rv); 3081 3082 // Race a session to the proxy, which completes first. 3083 session_deps_.host_resolver->set_ondemand_mode(false); 3084 SpdySessionKey key( 3085 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 3086 base::WeakPtr<SpdySession> spdy_session = 3087 CreateSecureSpdySession(session, key, log.bound()); 3088 3089 // Unstall the resolution begun by the transaction. 3090 session_deps_.host_resolver->set_ondemand_mode(true); 3091 session_deps_.host_resolver->ResolveAllPending(); 3092 3093 EXPECT_FALSE(callback1.have_result()); 3094 rv = callback1.WaitForResult(); 3095 EXPECT_EQ(OK, rv); 3096 3097 const HttpResponseInfo* response = trans->GetResponseInfo(); 3098 ASSERT_TRUE(response != NULL); 3099 ASSERT_TRUE(response->headers.get() != NULL); 3100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3101 3102 std::string response_data; 3103 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3104 EXPECT_EQ(kUploadData, response_data); 3105 } 3106 3107 // Test a SPDY get through an HTTPS Proxy. 3108 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) { 3109 HttpRequestInfo request; 3110 request.method = "GET"; 3111 request.url = GURL("http://www.google.com/"); 3112 request.load_flags = 0; 3113 3114 // Configure against https proxy server "myproxy:70". 3115 session_deps_.proxy_service.reset( 3116 ProxyService::CreateFixed("https://myproxy:70")); 3117 CapturingBoundNetLog log; 3118 session_deps_.net_log = log.bound().net_log(); 3119 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3120 3121 // The first request will be a bare GET, the second request will be a 3122 // GET with a Proxy-Authorization header. 3123 scoped_ptr<SpdyFrame> req_get( 3124 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 3125 const char* const kExtraAuthorizationHeaders[] = { 3126 "proxy-authorization", "Basic Zm9vOmJhcg==" 3127 }; 3128 scoped_ptr<SpdyFrame> req_get_authorization( 3129 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders, 3130 arraysize(kExtraAuthorizationHeaders) / 2, 3131 false, 3132 3, 3133 LOWEST, 3134 false)); 3135 MockWrite spdy_writes[] = { 3136 CreateMockWrite(*req_get, 1), 3137 CreateMockWrite(*req_get_authorization, 4), 3138 }; 3139 3140 // The first response is a 407 proxy authentication challenge, and the second 3141 // response will be a 200 response since the second request includes a valid 3142 // Authorization header. 3143 const char* const kExtraAuthenticationHeaders[] = { 3144 "proxy-authenticate", "Basic realm=\"MyRealm1\"" 3145 }; 3146 scoped_ptr<SpdyFrame> resp_authentication( 3147 spdy_util_.ConstructSpdySynReplyError( 3148 "407 Proxy Authentication Required", 3149 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2, 3150 1)); 3151 scoped_ptr<SpdyFrame> body_authentication( 3152 spdy_util_.ConstructSpdyBodyFrame(1, true)); 3153 scoped_ptr<SpdyFrame> resp_data( 3154 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3155 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true)); 3156 MockRead spdy_reads[] = { 3157 CreateMockRead(*resp_authentication, 2), 3158 CreateMockRead(*body_authentication, 3), 3159 CreateMockRead(*resp_data, 5), 3160 CreateMockRead(*body_data, 6), 3161 MockRead(ASYNC, 0, 7), 3162 }; 3163 3164 OrderedSocketData data( 3165 spdy_reads, arraysize(spdy_reads), 3166 spdy_writes, arraysize(spdy_writes)); 3167 session_deps_.socket_factory->AddSocketDataProvider(&data); 3168 3169 SSLSocketDataProvider ssl(ASYNC, OK); 3170 ssl.SetNextProto(GetParam()); 3171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3172 3173 TestCompletionCallback callback1; 3174 3175 scoped_ptr<HttpTransaction> trans( 3176 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3177 3178 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3179 EXPECT_EQ(ERR_IO_PENDING, rv); 3180 3181 rv = callback1.WaitForResult(); 3182 EXPECT_EQ(OK, rv); 3183 3184 const HttpResponseInfo* const response = trans->GetResponseInfo(); 3185 3186 ASSERT_TRUE(response != NULL); 3187 ASSERT_TRUE(response->headers.get() != NULL); 3188 EXPECT_EQ(407, response->headers->response_code()); 3189 EXPECT_TRUE(response->was_fetched_via_spdy); 3190 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 3191 3192 TestCompletionCallback callback2; 3193 3194 rv = trans->RestartWithAuth( 3195 AuthCredentials(kFoo, kBar), callback2.callback()); 3196 EXPECT_EQ(ERR_IO_PENDING, rv); 3197 3198 rv = callback2.WaitForResult(); 3199 EXPECT_EQ(OK, rv); 3200 3201 const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 3202 3203 ASSERT_TRUE(response_restart != NULL); 3204 ASSERT_TRUE(response_restart->headers.get() != NULL); 3205 EXPECT_EQ(200, response_restart->headers->response_code()); 3206 // The password prompt info should not be set. 3207 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 3208 } 3209 3210 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server. 3211 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) { 3212 HttpRequestInfo request; 3213 request.method = "GET"; 3214 request.url = GURL("https://www.google.com/"); 3215 request.load_flags = 0; 3216 3217 // Configure against https proxy server "proxy:70". 3218 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3219 "https://proxy:70")); 3220 CapturingBoundNetLog log; 3221 session_deps_.net_log = log.bound().net_log(); 3222 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3223 3224 scoped_ptr<HttpTransaction> trans( 3225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3226 3227 // CONNECT to www.google.com:443 via SPDY 3228 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3229 LOWEST)); 3230 // fetch https://www.google.com/ via HTTP 3231 3232 const char get[] = "GET / HTTP/1.1\r\n" 3233 "Host: www.google.com\r\n" 3234 "Connection: keep-alive\r\n\r\n"; 3235 scoped_ptr<SpdyFrame> wrapped_get( 3236 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false)); 3237 scoped_ptr<SpdyFrame> conn_resp( 3238 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3239 const char resp[] = "HTTP/1.1 200 OK\r\n" 3240 "Content-Length: 10\r\n\r\n"; 3241 scoped_ptr<SpdyFrame> wrapped_get_resp( 3242 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false)); 3243 scoped_ptr<SpdyFrame> wrapped_body( 3244 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false)); 3245 scoped_ptr<SpdyFrame> window_update( 3246 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size())); 3247 3248 MockWrite spdy_writes[] = { 3249 CreateMockWrite(*connect, 1), 3250 CreateMockWrite(*wrapped_get, 3), 3251 CreateMockWrite(*window_update, 5), 3252 }; 3253 3254 MockRead spdy_reads[] = { 3255 CreateMockRead(*conn_resp, 2, ASYNC), 3256 CreateMockRead(*wrapped_get_resp, 4, ASYNC), 3257 CreateMockRead(*wrapped_body, 6, ASYNC), 3258 CreateMockRead(*wrapped_body, 7, ASYNC), 3259 MockRead(ASYNC, 0, 8), 3260 }; 3261 3262 OrderedSocketData spdy_data( 3263 spdy_reads, arraysize(spdy_reads), 3264 spdy_writes, arraysize(spdy_writes)); 3265 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3266 3267 SSLSocketDataProvider ssl(ASYNC, OK); 3268 ssl.SetNextProto(GetParam()); 3269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3270 SSLSocketDataProvider ssl2(ASYNC, OK); 3271 ssl2.was_npn_negotiated = false; 3272 ssl2.protocol_negotiated = kProtoUnknown; 3273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 3274 3275 TestCompletionCallback callback1; 3276 3277 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3278 EXPECT_EQ(ERR_IO_PENDING, rv); 3279 3280 rv = callback1.WaitForResult(); 3281 EXPECT_EQ(OK, rv); 3282 3283 LoadTimingInfo load_timing_info; 3284 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3285 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3286 3287 const HttpResponseInfo* response = trans->GetResponseInfo(); 3288 ASSERT_TRUE(response != NULL); 3289 ASSERT_TRUE(response->headers.get() != NULL); 3290 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3291 3292 std::string response_data; 3293 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3294 EXPECT_EQ("1234567890", response_data); 3295 } 3296 3297 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server. 3298 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) { 3299 HttpRequestInfo request; 3300 request.method = "GET"; 3301 request.url = GURL("https://www.google.com/"); 3302 request.load_flags = 0; 3303 3304 // Configure against https proxy server "proxy:70". 3305 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3306 "https://proxy:70")); 3307 CapturingBoundNetLog log; 3308 session_deps_.net_log = log.bound().net_log(); 3309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3310 3311 scoped_ptr<HttpTransaction> trans( 3312 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3313 3314 // CONNECT to www.google.com:443 via SPDY 3315 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3316 LOWEST)); 3317 // fetch https://www.google.com/ via SPDY 3318 const char* const kMyUrl = "https://www.google.com/"; 3319 scoped_ptr<SpdyFrame> get( 3320 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST)); 3321 scoped_ptr<SpdyFrame> wrapped_get( 3322 spdy_util_.ConstructWrappedSpdyFrame(get, 1)); 3323 scoped_ptr<SpdyFrame> conn_resp( 3324 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3325 scoped_ptr<SpdyFrame> get_resp( 3326 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3327 scoped_ptr<SpdyFrame> wrapped_get_resp( 3328 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1)); 3329 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3330 scoped_ptr<SpdyFrame> wrapped_body( 3331 spdy_util_.ConstructWrappedSpdyFrame(body, 1)); 3332 scoped_ptr<SpdyFrame> window_update_get_resp( 3333 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size())); 3334 scoped_ptr<SpdyFrame> window_update_body( 3335 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size())); 3336 3337 MockWrite spdy_writes[] = { 3338 CreateMockWrite(*connect, 1), 3339 CreateMockWrite(*wrapped_get, 3), 3340 CreateMockWrite(*window_update_get_resp, 5), 3341 CreateMockWrite(*window_update_body, 7), 3342 }; 3343 3344 MockRead spdy_reads[] = { 3345 CreateMockRead(*conn_resp, 2, ASYNC), 3346 CreateMockRead(*wrapped_get_resp, 4, ASYNC), 3347 CreateMockRead(*wrapped_body, 6, ASYNC), 3348 MockRead(ASYNC, 0, 8), 3349 }; 3350 3351 OrderedSocketData spdy_data( 3352 spdy_reads, arraysize(spdy_reads), 3353 spdy_writes, arraysize(spdy_writes)); 3354 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3355 3356 SSLSocketDataProvider ssl(ASYNC, OK); 3357 ssl.SetNextProto(GetParam()); 3358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3359 SSLSocketDataProvider ssl2(ASYNC, OK); 3360 ssl2.SetNextProto(GetParam()); 3361 ssl2.protocol_negotiated = GetParam(); 3362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 3363 3364 TestCompletionCallback callback1; 3365 3366 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3367 EXPECT_EQ(ERR_IO_PENDING, rv); 3368 3369 rv = callback1.WaitForResult(); 3370 EXPECT_EQ(OK, rv); 3371 3372 LoadTimingInfo load_timing_info; 3373 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3374 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3375 3376 const HttpResponseInfo* response = trans->GetResponseInfo(); 3377 ASSERT_TRUE(response != NULL); 3378 ASSERT_TRUE(response->headers.get() != NULL); 3379 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3380 3381 std::string response_data; 3382 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 3383 EXPECT_EQ(kUploadData, response_data); 3384 } 3385 3386 // Test a SPDY CONNECT failure through an HTTPS Proxy. 3387 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) { 3388 HttpRequestInfo request; 3389 request.method = "GET"; 3390 request.url = GURL("https://www.google.com/"); 3391 request.load_flags = 0; 3392 3393 // Configure against https proxy server "proxy:70". 3394 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3395 "https://proxy:70")); 3396 CapturingBoundNetLog log; 3397 session_deps_.net_log = log.bound().net_log(); 3398 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3399 3400 scoped_ptr<HttpTransaction> trans( 3401 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3402 3403 // CONNECT to www.google.com:443 via SPDY 3404 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3405 LOWEST)); 3406 scoped_ptr<SpdyFrame> get( 3407 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 3408 3409 MockWrite spdy_writes[] = { 3410 CreateMockWrite(*connect, 1), 3411 CreateMockWrite(*get, 3), 3412 }; 3413 3414 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1)); 3415 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3416 MockRead spdy_reads[] = { 3417 CreateMockRead(*resp, 2, ASYNC), 3418 MockRead(ASYNC, 0, 4), 3419 }; 3420 3421 OrderedSocketData spdy_data( 3422 spdy_reads, arraysize(spdy_reads), 3423 spdy_writes, arraysize(spdy_writes)); 3424 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 3425 3426 SSLSocketDataProvider ssl(ASYNC, OK); 3427 ssl.SetNextProto(GetParam()); 3428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3429 SSLSocketDataProvider ssl2(ASYNC, OK); 3430 ssl2.SetNextProto(GetParam()); 3431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 3432 3433 TestCompletionCallback callback1; 3434 3435 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3436 EXPECT_EQ(ERR_IO_PENDING, rv); 3437 3438 rv = callback1.WaitForResult(); 3439 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 3440 3441 // TODO(ttuttle): Anything else to check here? 3442 } 3443 3444 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY 3445 // HTTPS Proxy to different servers. 3446 TEST_P(HttpNetworkTransactionTest, 3447 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) { 3448 // Configure against https proxy server "proxy:70". 3449 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3450 "https://proxy:70")); 3451 CapturingBoundNetLog log; 3452 session_deps_.net_log = log.bound().net_log(); 3453 scoped_refptr<HttpNetworkSession> session( 3454 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3455 3456 HttpRequestInfo request1; 3457 request1.method = "GET"; 3458 request1.url = GURL("https://www.google.com/"); 3459 request1.load_flags = 0; 3460 3461 HttpRequestInfo request2; 3462 request2.method = "GET"; 3463 request2.url = GURL("https://news.google.com/"); 3464 request2.load_flags = 0; 3465 3466 // CONNECT to www.google.com:443 via SPDY. 3467 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3468 LOWEST)); 3469 scoped_ptr<SpdyFrame> conn_resp1( 3470 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3471 3472 // Fetch https://www.google.com/ via HTTP. 3473 const char get1[] = "GET / HTTP/1.1\r\n" 3474 "Host: www.google.com\r\n" 3475 "Connection: keep-alive\r\n\r\n"; 3476 scoped_ptr<SpdyFrame> wrapped_get1( 3477 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false)); 3478 const char resp1[] = "HTTP/1.1 200 OK\r\n" 3479 "Content-Length: 1\r\n\r\n"; 3480 scoped_ptr<SpdyFrame> wrapped_get_resp1( 3481 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false)); 3482 scoped_ptr<SpdyFrame> wrapped_body1( 3483 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false)); 3484 scoped_ptr<SpdyFrame> window_update( 3485 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size())); 3486 3487 // CONNECT to news.google.com:443 via SPDY. 3488 SpdySynStreamIR connect2_ir(3); 3489 spdy_util_.SetPriority(LOWEST, &connect2_ir); 3490 connect2_ir.SetHeader(spdy_util_.GetMethodKey(), "CONNECT"); 3491 connect2_ir.SetHeader(spdy_util_.GetPathKey(), "news.google.com:443"); 3492 connect2_ir.SetHeader(spdy_util_.GetHostKey(), "news.google.com"); 3493 spdy_util_.MaybeAddVersionHeader(&connect2_ir); 3494 scoped_ptr<SpdyFrame> connect2( 3495 spdy_util_.CreateFramer(false)->SerializeFrame(connect2_ir)); 3496 3497 scoped_ptr<SpdyFrame> conn_resp2( 3498 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3499 3500 // Fetch https://news.google.com/ via HTTP. 3501 const char get2[] = "GET / HTTP/1.1\r\n" 3502 "Host: news.google.com\r\n" 3503 "Connection: keep-alive\r\n\r\n"; 3504 scoped_ptr<SpdyFrame> wrapped_get2( 3505 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false)); 3506 const char resp2[] = "HTTP/1.1 200 OK\r\n" 3507 "Content-Length: 2\r\n\r\n"; 3508 scoped_ptr<SpdyFrame> wrapped_get_resp2( 3509 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false)); 3510 scoped_ptr<SpdyFrame> wrapped_body2( 3511 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false)); 3512 3513 MockWrite spdy_writes[] = { 3514 CreateMockWrite(*connect1, 0), 3515 CreateMockWrite(*wrapped_get1, 2), 3516 CreateMockWrite(*connect2, 5), 3517 CreateMockWrite(*wrapped_get2, 7), 3518 }; 3519 3520 MockRead spdy_reads[] = { 3521 CreateMockRead(*conn_resp1, 1, ASYNC), 3522 CreateMockRead(*wrapped_get_resp1, 3, ASYNC), 3523 CreateMockRead(*wrapped_body1, 4, ASYNC), 3524 CreateMockRead(*conn_resp2, 6, ASYNC), 3525 CreateMockRead(*wrapped_get_resp2, 8, ASYNC), 3526 CreateMockRead(*wrapped_body2, 9, ASYNC), 3527 MockRead(ASYNC, 0, 10), 3528 }; 3529 3530 DeterministicSocketData spdy_data( 3531 spdy_reads, arraysize(spdy_reads), 3532 spdy_writes, arraysize(spdy_writes)); 3533 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3534 3535 SSLSocketDataProvider ssl(ASYNC, OK); 3536 ssl.SetNextProto(GetParam()); 3537 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3538 SSLSocketDataProvider ssl2(ASYNC, OK); 3539 ssl2.was_npn_negotiated = false; 3540 ssl2.protocol_negotiated = kProtoUnknown; 3541 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 3542 SSLSocketDataProvider ssl3(ASYNC, OK); 3543 ssl3.was_npn_negotiated = false; 3544 ssl3.protocol_negotiated = kProtoUnknown; 3545 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3); 3546 3547 TestCompletionCallback callback; 3548 3549 scoped_ptr<HttpTransaction> trans( 3550 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3551 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3552 EXPECT_EQ(ERR_IO_PENDING, rv); 3553 // The first connect and request, each of their responses, and the body. 3554 spdy_data.RunFor(5); 3555 3556 rv = callback.WaitForResult(); 3557 EXPECT_EQ(OK, rv); 3558 3559 LoadTimingInfo load_timing_info; 3560 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3561 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3562 3563 const HttpResponseInfo* response = trans->GetResponseInfo(); 3564 ASSERT_TRUE(response != NULL); 3565 ASSERT_TRUE(response->headers.get() != NULL); 3566 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3567 3568 std::string response_data; 3569 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3570 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback())); 3571 3572 scoped_ptr<HttpTransaction> trans2( 3573 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3574 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3575 EXPECT_EQ(ERR_IO_PENDING, rv); 3576 3577 // The second connect and request, each of their responses, and the body. 3578 spdy_data.RunFor(5); 3579 rv = callback.WaitForResult(); 3580 EXPECT_EQ(OK, rv); 3581 3582 LoadTimingInfo load_timing_info2; 3583 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3584 // Even though the SPDY connection is reused, a new tunnelled connection has 3585 // to be created, so the socket's load timing looks like a fresh connection. 3586 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES); 3587 3588 // The requests should have different IDs, since they each are using their own 3589 // separate stream. 3590 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3591 3592 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback())); 3593 } 3594 3595 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY 3596 // HTTPS Proxy to the same server. 3597 TEST_P(HttpNetworkTransactionTest, 3598 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) { 3599 // Configure against https proxy server "proxy:70". 3600 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3601 "https://proxy:70")); 3602 CapturingBoundNetLog log; 3603 session_deps_.net_log = log.bound().net_log(); 3604 scoped_refptr<HttpNetworkSession> session( 3605 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3606 3607 HttpRequestInfo request1; 3608 request1.method = "GET"; 3609 request1.url = GURL("https://www.google.com/"); 3610 request1.load_flags = 0; 3611 3612 HttpRequestInfo request2; 3613 request2.method = "GET"; 3614 request2.url = GURL("https://www.google.com/2"); 3615 request2.load_flags = 0; 3616 3617 // CONNECT to www.google.com:443 via SPDY. 3618 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 3619 LOWEST)); 3620 scoped_ptr<SpdyFrame> conn_resp1( 3621 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3622 3623 // Fetch https://www.google.com/ via HTTP. 3624 const char get1[] = "GET / HTTP/1.1\r\n" 3625 "Host: www.google.com\r\n" 3626 "Connection: keep-alive\r\n\r\n"; 3627 scoped_ptr<SpdyFrame> wrapped_get1( 3628 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false)); 3629 const char resp1[] = "HTTP/1.1 200 OK\r\n" 3630 "Content-Length: 1\r\n\r\n"; 3631 scoped_ptr<SpdyFrame> wrapped_get_resp1( 3632 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false)); 3633 scoped_ptr<SpdyFrame> wrapped_body1( 3634 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false)); 3635 scoped_ptr<SpdyFrame> window_update( 3636 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size())); 3637 3638 // Fetch https://www.google.com/2 via HTTP. 3639 const char get2[] = "GET /2 HTTP/1.1\r\n" 3640 "Host: www.google.com\r\n" 3641 "Connection: keep-alive\r\n\r\n"; 3642 scoped_ptr<SpdyFrame> wrapped_get2( 3643 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false)); 3644 const char resp2[] = "HTTP/1.1 200 OK\r\n" 3645 "Content-Length: 2\r\n\r\n"; 3646 scoped_ptr<SpdyFrame> wrapped_get_resp2( 3647 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false)); 3648 scoped_ptr<SpdyFrame> wrapped_body2( 3649 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false)); 3650 3651 MockWrite spdy_writes[] = { 3652 CreateMockWrite(*connect1, 0), 3653 CreateMockWrite(*wrapped_get1, 2), 3654 CreateMockWrite(*wrapped_get2, 5), 3655 }; 3656 3657 MockRead spdy_reads[] = { 3658 CreateMockRead(*conn_resp1, 1, ASYNC), 3659 CreateMockRead(*wrapped_get_resp1, 3, ASYNC), 3660 CreateMockRead(*wrapped_body1, 4, ASYNC), 3661 CreateMockRead(*wrapped_get_resp2, 6, ASYNC), 3662 CreateMockRead(*wrapped_body2, 7, ASYNC), 3663 MockRead(ASYNC, 0, 8), 3664 }; 3665 3666 DeterministicSocketData spdy_data( 3667 spdy_reads, arraysize(spdy_reads), 3668 spdy_writes, arraysize(spdy_writes)); 3669 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3670 3671 SSLSocketDataProvider ssl(ASYNC, OK); 3672 ssl.SetNextProto(GetParam()); 3673 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3674 SSLSocketDataProvider ssl2(ASYNC, OK); 3675 ssl2.was_npn_negotiated = false; 3676 ssl2.protocol_negotiated = kProtoUnknown; 3677 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 3678 3679 TestCompletionCallback callback; 3680 3681 scoped_ptr<HttpTransaction> trans( 3682 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3683 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3684 EXPECT_EQ(ERR_IO_PENDING, rv); 3685 // The first connect and request, each of their responses, and the body. 3686 spdy_data.RunFor(5); 3687 3688 rv = callback.WaitForResult(); 3689 EXPECT_EQ(OK, rv); 3690 3691 LoadTimingInfo load_timing_info; 3692 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3693 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); 3694 3695 const HttpResponseInfo* response = trans->GetResponseInfo(); 3696 ASSERT_TRUE(response != NULL); 3697 ASSERT_TRUE(response->headers.get() != NULL); 3698 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3699 3700 std::string response_data; 3701 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3702 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback())); 3703 trans.reset(); 3704 3705 scoped_ptr<HttpTransaction> trans2( 3706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3707 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3708 EXPECT_EQ(ERR_IO_PENDING, rv); 3709 3710 // The second request, response, and body. There should not be a second 3711 // connect. 3712 spdy_data.RunFor(3); 3713 rv = callback.WaitForResult(); 3714 EXPECT_EQ(OK, rv); 3715 3716 LoadTimingInfo load_timing_info2; 3717 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3718 TestLoadTimingReused(load_timing_info2); 3719 3720 // The requests should have the same ID. 3721 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3722 3723 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback())); 3724 } 3725 3726 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS 3727 // Proxy to different servers. 3728 TEST_P(HttpNetworkTransactionTest, 3729 HttpsProxySpdyLoadTimingTwoHttpRequests) { 3730 // Configure against https proxy server "proxy:70". 3731 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 3732 "https://proxy:70")); 3733 CapturingBoundNetLog log; 3734 session_deps_.net_log = log.bound().net_log(); 3735 scoped_refptr<HttpNetworkSession> session( 3736 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 3737 3738 HttpRequestInfo request1; 3739 request1.method = "GET"; 3740 request1.url = GURL("http://www.google.com/"); 3741 request1.load_flags = 0; 3742 3743 HttpRequestInfo request2; 3744 request2.method = "GET"; 3745 request2.url = GURL("http://news.google.com/"); 3746 request2.load_flags = 0; 3747 3748 // http://www.google.com/ 3749 scoped_ptr<SpdyHeaderBlock> headers( 3750 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/")); 3751 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame( 3752 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0)); 3753 scoped_ptr<SpdyFrame> get_resp1( 3754 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3755 scoped_ptr<SpdyFrame> body1( 3756 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true)); 3757 3758 // http://news.google.com/ 3759 scoped_ptr<SpdyHeaderBlock> headers2( 3760 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/")); 3761 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame( 3762 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0)); 3763 scoped_ptr<SpdyFrame> get_resp2( 3764 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 3765 scoped_ptr<SpdyFrame> body2( 3766 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true)); 3767 3768 MockWrite spdy_writes[] = { 3769 CreateMockWrite(*get1, 0), 3770 CreateMockWrite(*get2, 3), 3771 }; 3772 3773 MockRead spdy_reads[] = { 3774 CreateMockRead(*get_resp1, 1, ASYNC), 3775 CreateMockRead(*body1, 2, ASYNC), 3776 CreateMockRead(*get_resp2, 4, ASYNC), 3777 CreateMockRead(*body2, 5, ASYNC), 3778 MockRead(ASYNC, 0, 6), 3779 }; 3780 3781 DeterministicSocketData spdy_data( 3782 spdy_reads, arraysize(spdy_reads), 3783 spdy_writes, arraysize(spdy_writes)); 3784 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data); 3785 3786 SSLSocketDataProvider ssl(ASYNC, OK); 3787 ssl.SetNextProto(GetParam()); 3788 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3789 3790 TestCompletionCallback callback; 3791 3792 scoped_ptr<HttpTransaction> trans( 3793 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3794 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 3795 EXPECT_EQ(ERR_IO_PENDING, rv); 3796 spdy_data.RunFor(2); 3797 3798 rv = callback.WaitForResult(); 3799 EXPECT_EQ(OK, rv); 3800 3801 LoadTimingInfo load_timing_info; 3802 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3803 TestLoadTimingNotReused(load_timing_info, 3804 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3805 3806 const HttpResponseInfo* response = trans->GetResponseInfo(); 3807 ASSERT_TRUE(response != NULL); 3808 ASSERT_TRUE(response->headers.get() != NULL); 3809 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3810 3811 std::string response_data; 3812 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 3813 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback())); 3814 spdy_data.RunFor(1); 3815 EXPECT_EQ(1, callback.WaitForResult()); 3816 // Delete the first request, so the second one can reuse the socket. 3817 trans.reset(); 3818 3819 scoped_ptr<HttpTransaction> trans2( 3820 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3821 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 3822 EXPECT_EQ(ERR_IO_PENDING, rv); 3823 3824 spdy_data.RunFor(2); 3825 rv = callback.WaitForResult(); 3826 EXPECT_EQ(OK, rv); 3827 3828 LoadTimingInfo load_timing_info2; 3829 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); 3830 TestLoadTimingReused(load_timing_info2); 3831 3832 // The requests should have the same ID. 3833 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); 3834 3835 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback())); 3836 spdy_data.RunFor(1); 3837 EXPECT_EQ(2, callback.WaitForResult()); 3838 } 3839 3840 // Test the challenge-response-retry sequence through an HTTPS Proxy 3841 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { 3842 HttpRequestInfo request; 3843 request.method = "GET"; 3844 request.url = GURL("http://www.google.com/"); 3845 // when the no authentication data flag is set. 3846 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 3847 3848 // Configure against https proxy server "myproxy:70". 3849 session_deps_.proxy_service.reset( 3850 ProxyService::CreateFixed("https://myproxy:70")); 3851 CapturingBoundNetLog log; 3852 session_deps_.net_log = log.bound().net_log(); 3853 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3854 3855 // Since we have proxy, should use full url 3856 MockWrite data_writes1[] = { 3857 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3858 "Host: www.google.com\r\n" 3859 "Proxy-Connection: keep-alive\r\n\r\n"), 3860 3861 // After calling trans->RestartWithAuth(), this is the request we should 3862 // be issuing -- the final header line contains the credentials. 3863 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 3864 "Host: www.google.com\r\n" 3865 "Proxy-Connection: keep-alive\r\n" 3866 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3867 }; 3868 3869 // The proxy responds to the GET with a 407, using a persistent 3870 // connection. 3871 MockRead data_reads1[] = { 3872 // No credentials. 3873 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 3874 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3875 MockRead("Proxy-Connection: keep-alive\r\n"), 3876 MockRead("Content-Length: 0\r\n\r\n"), 3877 3878 MockRead("HTTP/1.1 200 OK\r\n"), 3879 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 3880 MockRead("Content-Length: 100\r\n\r\n"), 3881 MockRead(SYNCHRONOUS, OK), 3882 }; 3883 3884 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3885 data_writes1, arraysize(data_writes1)); 3886 session_deps_.socket_factory->AddSocketDataProvider(&data1); 3887 SSLSocketDataProvider ssl(ASYNC, OK); 3888 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3889 3890 TestCompletionCallback callback1; 3891 3892 scoped_ptr<HttpTransaction> trans( 3893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3894 3895 int rv = trans->Start(&request, callback1.callback(), log.bound()); 3896 EXPECT_EQ(ERR_IO_PENDING, rv); 3897 3898 rv = callback1.WaitForResult(); 3899 EXPECT_EQ(OK, rv); 3900 3901 LoadTimingInfo load_timing_info; 3902 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3903 TestLoadTimingNotReused(load_timing_info, 3904 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 3905 3906 const HttpResponseInfo* response = trans->GetResponseInfo(); 3907 ASSERT_TRUE(response != NULL); 3908 ASSERT_FALSE(response->headers.get() == NULL); 3909 EXPECT_EQ(407, response->headers->response_code()); 3910 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 3911 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 3912 3913 TestCompletionCallback callback2; 3914 3915 rv = trans->RestartWithAuth( 3916 AuthCredentials(kFoo, kBar), callback2.callback()); 3917 EXPECT_EQ(ERR_IO_PENDING, rv); 3918 3919 rv = callback2.WaitForResult(); 3920 EXPECT_EQ(OK, rv); 3921 3922 load_timing_info = LoadTimingInfo(); 3923 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 3924 // Retrying with HTTP AUTH is considered to be reusing a socket. 3925 TestLoadTimingReused(load_timing_info); 3926 3927 response = trans->GetResponseInfo(); 3928 ASSERT_TRUE(response != NULL); 3929 3930 EXPECT_TRUE(response->headers->IsKeepAlive()); 3931 EXPECT_EQ(200, response->headers->response_code()); 3932 EXPECT_EQ(100, response->headers->GetContentLength()); 3933 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 3934 3935 // The password prompt info should not be set. 3936 EXPECT_TRUE(response->auth_challenge.get() == NULL); 3937 } 3938 3939 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( 3940 const MockRead& status, int expected_status) { 3941 HttpRequestInfo request; 3942 request.method = "GET"; 3943 request.url = GURL("https://www.google.com/"); 3944 request.load_flags = 0; 3945 3946 // Configure against proxy server "myproxy:70". 3947 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 3948 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 3949 3950 // Since we have proxy, should try to establish tunnel. 3951 MockWrite data_writes[] = { 3952 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 3953 "Host: www.google.com\r\n" 3954 "Proxy-Connection: keep-alive\r\n\r\n"), 3955 }; 3956 3957 MockRead data_reads[] = { 3958 status, 3959 MockRead("Content-Length: 10\r\n\r\n"), 3960 // No response body because the test stops reading here. 3961 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 3962 }; 3963 3964 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 3965 data_writes, arraysize(data_writes)); 3966 session_deps_.socket_factory->AddSocketDataProvider(&data); 3967 3968 TestCompletionCallback callback; 3969 3970 scoped_ptr<HttpTransaction> trans( 3971 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 3972 3973 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 3974 EXPECT_EQ(ERR_IO_PENDING, rv); 3975 3976 rv = callback.WaitForResult(); 3977 EXPECT_EQ(expected_status, rv); 3978 } 3979 3980 void HttpNetworkTransactionTest::ConnectStatusHelper( 3981 const MockRead& status) { 3982 ConnectStatusHelperWithExpectedStatus( 3983 status, ERR_TUNNEL_CONNECTION_FAILED); 3984 } 3985 3986 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) { 3987 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n")); 3988 } 3989 3990 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) { 3991 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n")); 3992 } 3993 3994 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) { 3995 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n")); 3996 } 3997 3998 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) { 3999 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n")); 4000 } 4001 4002 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) { 4003 ConnectStatusHelper( 4004 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n")); 4005 } 4006 4007 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) { 4008 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n")); 4009 } 4010 4011 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) { 4012 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n")); 4013 } 4014 4015 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) { 4016 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n")); 4017 } 4018 4019 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) { 4020 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n")); 4021 } 4022 4023 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) { 4024 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n")); 4025 } 4026 4027 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) { 4028 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n")); 4029 } 4030 4031 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) { 4032 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n")); 4033 } 4034 4035 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) { 4036 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n")); 4037 } 4038 4039 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) { 4040 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n")); 4041 } 4042 4043 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) { 4044 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n")); 4045 } 4046 4047 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) { 4048 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n")); 4049 } 4050 4051 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) { 4052 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n")); 4053 } 4054 4055 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) { 4056 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n")); 4057 } 4058 4059 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) { 4060 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n")); 4061 } 4062 4063 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) { 4064 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n")); 4065 } 4066 4067 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) { 4068 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n")); 4069 } 4070 4071 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) { 4072 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n")); 4073 } 4074 4075 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) { 4076 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n")); 4077 } 4078 4079 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) { 4080 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n")); 4081 } 4082 4083 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) { 4084 ConnectStatusHelperWithExpectedStatus( 4085 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 4086 ERR_PROXY_AUTH_UNSUPPORTED); 4087 } 4088 4089 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) { 4090 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n")); 4091 } 4092 4093 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) { 4094 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n")); 4095 } 4096 4097 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) { 4098 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n")); 4099 } 4100 4101 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) { 4102 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n")); 4103 } 4104 4105 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) { 4106 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n")); 4107 } 4108 4109 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) { 4110 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n")); 4111 } 4112 4113 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) { 4114 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n")); 4115 } 4116 4117 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) { 4118 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n")); 4119 } 4120 4121 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) { 4122 ConnectStatusHelper( 4123 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n")); 4124 } 4125 4126 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) { 4127 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n")); 4128 } 4129 4130 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) { 4131 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n")); 4132 } 4133 4134 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) { 4135 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n")); 4136 } 4137 4138 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) { 4139 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n")); 4140 } 4141 4142 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) { 4143 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n")); 4144 } 4145 4146 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) { 4147 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n")); 4148 } 4149 4150 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) { 4151 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n")); 4152 } 4153 4154 // Test the flow when both the proxy server AND origin server require 4155 // authentication. Again, this uses basic auth for both since that is 4156 // the simplest to mock. 4157 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { 4158 HttpRequestInfo request; 4159 request.method = "GET"; 4160 request.url = GURL("http://www.google.com/"); 4161 request.load_flags = 0; 4162 4163 // Configure against proxy server "myproxy:70". 4164 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 4165 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4166 4167 scoped_ptr<HttpTransaction> trans( 4168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 4169 4170 MockWrite data_writes1[] = { 4171 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 4172 "Host: www.google.com\r\n" 4173 "Proxy-Connection: keep-alive\r\n\r\n"), 4174 }; 4175 4176 MockRead data_reads1[] = { 4177 MockRead("HTTP/1.0 407 Unauthorized\r\n"), 4178 // Give a couple authenticate options (only the middle one is actually 4179 // supported). 4180 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed. 4181 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4182 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 4183 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4184 // Large content-length -- won't matter, as connection will be reset. 4185 MockRead("Content-Length: 10000\r\n\r\n"), 4186 MockRead(SYNCHRONOUS, ERR_FAILED), 4187 }; 4188 4189 // After calling trans->RestartWithAuth() the first time, this is the 4190 // request we should be issuing -- the final header line contains the 4191 // proxy's credentials. 4192 MockWrite data_writes2[] = { 4193 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 4194 "Host: www.google.com\r\n" 4195 "Proxy-Connection: keep-alive\r\n" 4196 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 4197 }; 4198 4199 // Now the proxy server lets the request pass through to origin server. 4200 // The origin server responds with a 401. 4201 MockRead data_reads2[] = { 4202 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4203 // Note: We are using the same realm-name as the proxy server. This is 4204 // completely valid, as realms are unique across hosts. 4205 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4206 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4207 MockRead("Content-Length: 2000\r\n\r\n"), 4208 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached. 4209 }; 4210 4211 // After calling trans->RestartWithAuth() the second time, we should send 4212 // the credentials for both the proxy and origin server. 4213 MockWrite data_writes3[] = { 4214 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 4215 "Host: www.google.com\r\n" 4216 "Proxy-Connection: keep-alive\r\n" 4217 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n" 4218 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 4219 }; 4220 4221 // Lastly we get the desired content. 4222 MockRead data_reads3[] = { 4223 MockRead("HTTP/1.0 200 OK\r\n"), 4224 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4225 MockRead("Content-Length: 100\r\n\r\n"), 4226 MockRead(SYNCHRONOUS, OK), 4227 }; 4228 4229 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4230 data_writes1, arraysize(data_writes1)); 4231 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4232 data_writes2, arraysize(data_writes2)); 4233 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4234 data_writes3, arraysize(data_writes3)); 4235 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4236 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4237 session_deps_.socket_factory->AddSocketDataProvider(&data3); 4238 4239 TestCompletionCallback callback1; 4240 4241 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4242 EXPECT_EQ(ERR_IO_PENDING, rv); 4243 4244 rv = callback1.WaitForResult(); 4245 EXPECT_EQ(OK, rv); 4246 4247 const HttpResponseInfo* response = trans->GetResponseInfo(); 4248 ASSERT_TRUE(response != NULL); 4249 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 4250 4251 TestCompletionCallback callback2; 4252 4253 rv = trans->RestartWithAuth( 4254 AuthCredentials(kFoo, kBar), callback2.callback()); 4255 EXPECT_EQ(ERR_IO_PENDING, rv); 4256 4257 rv = callback2.WaitForResult(); 4258 EXPECT_EQ(OK, rv); 4259 4260 response = trans->GetResponseInfo(); 4261 ASSERT_TRUE(response != NULL); 4262 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 4263 4264 TestCompletionCallback callback3; 4265 4266 rv = trans->RestartWithAuth( 4267 AuthCredentials(kFoo2, kBar2), callback3.callback()); 4268 EXPECT_EQ(ERR_IO_PENDING, rv); 4269 4270 rv = callback3.WaitForResult(); 4271 EXPECT_EQ(OK, rv); 4272 4273 response = trans->GetResponseInfo(); 4274 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4275 EXPECT_EQ(100, response->headers->GetContentLength()); 4276 } 4277 4278 // For the NTLM implementation using SSPI, we skip the NTLM tests since we 4279 // can't hook into its internals to cause it to generate predictable NTLM 4280 // authorization headers. 4281 #if defined(NTLM_PORTABLE) 4282 // The NTLM authentication unit tests were generated by capturing the HTTP 4283 // requests and responses using Fiddler 2 and inspecting the generated random 4284 // bytes in the debugger. 4285 4286 // Enter the correct password and authenticate successfully. 4287 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) { 4288 HttpRequestInfo request; 4289 request.method = "GET"; 4290 request.url = GURL("http://172.22.68.17/kids/login.aspx"); 4291 4292 // Ensure load is not disrupted by flags which suppress behaviour specific 4293 // to other auth schemes. 4294 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; 4295 4296 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, 4297 MockGetHostName); 4298 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4299 4300 MockWrite data_writes1[] = { 4301 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4302 "Host: 172.22.68.17\r\n" 4303 "Connection: keep-alive\r\n\r\n"), 4304 }; 4305 4306 MockRead data_reads1[] = { 4307 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4308 // Negotiate and NTLM are often requested together. However, we only want 4309 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 4310 // the header that requests Negotiate for this test. 4311 MockRead("WWW-Authenticate: NTLM\r\n"), 4312 MockRead("Connection: close\r\n"), 4313 MockRead("Content-Length: 42\r\n"), 4314 MockRead("Content-Type: text/html\r\n\r\n"), 4315 // Missing content -- won't matter, as connection will be reset. 4316 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4317 }; 4318 4319 MockWrite data_writes2[] = { 4320 // After restarting with a null identity, this is the 4321 // request we should be issuing -- the final header line contains a Type 4322 // 1 message. 4323 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4324 "Host: 172.22.68.17\r\n" 4325 "Connection: keep-alive\r\n" 4326 "Authorization: NTLM " 4327 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4328 4329 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4330 // (the credentials for the origin server). The second request continues 4331 // on the same connection. 4332 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4333 "Host: 172.22.68.17\r\n" 4334 "Connection: keep-alive\r\n" 4335 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4336 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4337 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW" 4338 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX" 4339 "ahlhx5I=\r\n\r\n"), 4340 }; 4341 4342 MockRead data_reads2[] = { 4343 // The origin server responds with a Type 2 message. 4344 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4345 MockRead("WWW-Authenticate: NTLM " 4346 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo" 4347 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4348 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4349 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4350 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4351 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4352 "BtAAAAAAA=\r\n"), 4353 MockRead("Content-Length: 42\r\n"), 4354 MockRead("Content-Type: text/html\r\n\r\n"), 4355 MockRead("You are not authorized to view this page\r\n"), 4356 4357 // Lastly we get the desired content. 4358 MockRead("HTTP/1.1 200 OK\r\n"), 4359 MockRead("Content-Type: text/html; charset=utf-8\r\n"), 4360 MockRead("Content-Length: 13\r\n\r\n"), 4361 MockRead("Please Login\r\n"), 4362 MockRead(SYNCHRONOUS, OK), 4363 }; 4364 4365 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4366 data_writes1, arraysize(data_writes1)); 4367 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4368 data_writes2, arraysize(data_writes2)); 4369 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4370 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4371 4372 TestCompletionCallback callback1; 4373 4374 scoped_ptr<HttpTransaction> trans( 4375 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4376 4377 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4378 EXPECT_EQ(ERR_IO_PENDING, rv); 4379 4380 rv = callback1.WaitForResult(); 4381 EXPECT_EQ(OK, rv); 4382 4383 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4384 4385 const HttpResponseInfo* response = trans->GetResponseInfo(); 4386 ASSERT_FALSE(response == NULL); 4387 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4388 4389 TestCompletionCallback callback2; 4390 4391 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), 4392 callback2.callback()); 4393 EXPECT_EQ(ERR_IO_PENDING, rv); 4394 4395 rv = callback2.WaitForResult(); 4396 EXPECT_EQ(OK, rv); 4397 4398 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4399 4400 response = trans->GetResponseInfo(); 4401 ASSERT_TRUE(response != NULL); 4402 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4403 4404 TestCompletionCallback callback3; 4405 4406 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); 4407 EXPECT_EQ(ERR_IO_PENDING, rv); 4408 4409 rv = callback3.WaitForResult(); 4410 EXPECT_EQ(OK, rv); 4411 4412 response = trans->GetResponseInfo(); 4413 ASSERT_TRUE(response != NULL); 4414 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4415 EXPECT_EQ(13, response->headers->GetContentLength()); 4416 } 4417 4418 // Enter a wrong password, and then the correct one. 4419 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) { 4420 HttpRequestInfo request; 4421 request.method = "GET"; 4422 request.url = GURL("http://172.22.68.17/kids/login.aspx"); 4423 request.load_flags = 0; 4424 4425 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2, 4426 MockGetHostName); 4427 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4428 4429 MockWrite data_writes1[] = { 4430 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4431 "Host: 172.22.68.17\r\n" 4432 "Connection: keep-alive\r\n\r\n"), 4433 }; 4434 4435 MockRead data_reads1[] = { 4436 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4437 // Negotiate and NTLM are often requested together. However, we only want 4438 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 4439 // the header that requests Negotiate for this test. 4440 MockRead("WWW-Authenticate: NTLM\r\n"), 4441 MockRead("Connection: close\r\n"), 4442 MockRead("Content-Length: 42\r\n"), 4443 MockRead("Content-Type: text/html\r\n\r\n"), 4444 // Missing content -- won't matter, as connection will be reset. 4445 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4446 }; 4447 4448 MockWrite data_writes2[] = { 4449 // After restarting with a null identity, this is the 4450 // request we should be issuing -- the final header line contains a Type 4451 // 1 message. 4452 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4453 "Host: 172.22.68.17\r\n" 4454 "Connection: keep-alive\r\n" 4455 "Authorization: NTLM " 4456 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4457 4458 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4459 // (the credentials for the origin server). The second request continues 4460 // on the same connection. 4461 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4462 "Host: 172.22.68.17\r\n" 4463 "Connection: keep-alive\r\n" 4464 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4465 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4466 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY" 4467 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj" 4468 "4Ww7b7E=\r\n\r\n"), 4469 }; 4470 4471 MockRead data_reads2[] = { 4472 // The origin server responds with a Type 2 message. 4473 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4474 MockRead("WWW-Authenticate: NTLM " 4475 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo" 4476 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4477 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4478 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4479 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4480 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4481 "BtAAAAAAA=\r\n"), 4482 MockRead("Content-Length: 42\r\n"), 4483 MockRead("Content-Type: text/html\r\n\r\n"), 4484 MockRead("You are not authorized to view this page\r\n"), 4485 4486 // Wrong password. 4487 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4488 MockRead("WWW-Authenticate: NTLM\r\n"), 4489 MockRead("Connection: close\r\n"), 4490 MockRead("Content-Length: 42\r\n"), 4491 MockRead("Content-Type: text/html\r\n\r\n"), 4492 // Missing content -- won't matter, as connection will be reset. 4493 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), 4494 }; 4495 4496 MockWrite data_writes3[] = { 4497 // After restarting with a null identity, this is the 4498 // request we should be issuing -- the final header line contains a Type 4499 // 1 message. 4500 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4501 "Host: 172.22.68.17\r\n" 4502 "Connection: keep-alive\r\n" 4503 "Authorization: NTLM " 4504 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 4505 4506 // After calling trans->RestartWithAuth(), we should send a Type 3 message 4507 // (the credentials for the origin server). The second request continues 4508 // on the same connection. 4509 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 4510 "Host: 172.22.68.17\r\n" 4511 "Connection: keep-alive\r\n" 4512 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 4513 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 4514 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54" 4515 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI" 4516 "+4MUm7c=\r\n\r\n"), 4517 }; 4518 4519 MockRead data_reads3[] = { 4520 // The origin server responds with a Type 2 message. 4521 MockRead("HTTP/1.1 401 Access Denied\r\n"), 4522 MockRead("WWW-Authenticate: NTLM " 4523 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo" 4524 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 4525 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 4526 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 4527 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 4528 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 4529 "BtAAAAAAA=\r\n"), 4530 MockRead("Content-Length: 42\r\n"), 4531 MockRead("Content-Type: text/html\r\n\r\n"), 4532 MockRead("You are not authorized to view this page\r\n"), 4533 4534 // Lastly we get the desired content. 4535 MockRead("HTTP/1.1 200 OK\r\n"), 4536 MockRead("Content-Type: text/html; charset=utf-8\r\n"), 4537 MockRead("Content-Length: 13\r\n\r\n"), 4538 MockRead("Please Login\r\n"), 4539 MockRead(SYNCHRONOUS, OK), 4540 }; 4541 4542 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4543 data_writes1, arraysize(data_writes1)); 4544 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4545 data_writes2, arraysize(data_writes2)); 4546 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4547 data_writes3, arraysize(data_writes3)); 4548 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4549 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4550 session_deps_.socket_factory->AddSocketDataProvider(&data3); 4551 4552 TestCompletionCallback callback1; 4553 4554 scoped_ptr<HttpTransaction> trans( 4555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4556 4557 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4558 EXPECT_EQ(ERR_IO_PENDING, rv); 4559 4560 rv = callback1.WaitForResult(); 4561 EXPECT_EQ(OK, rv); 4562 4563 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4564 4565 const HttpResponseInfo* response = trans->GetResponseInfo(); 4566 ASSERT_TRUE(response != NULL); 4567 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4568 4569 TestCompletionCallback callback2; 4570 4571 // Enter the wrong password. 4572 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword), 4573 callback2.callback()); 4574 EXPECT_EQ(ERR_IO_PENDING, rv); 4575 4576 rv = callback2.WaitForResult(); 4577 EXPECT_EQ(OK, rv); 4578 4579 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4580 TestCompletionCallback callback3; 4581 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); 4582 EXPECT_EQ(ERR_IO_PENDING, rv); 4583 rv = callback3.WaitForResult(); 4584 EXPECT_EQ(OK, rv); 4585 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4586 4587 response = trans->GetResponseInfo(); 4588 ASSERT_FALSE(response == NULL); 4589 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); 4590 4591 TestCompletionCallback callback4; 4592 4593 // Now enter the right password. 4594 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), 4595 callback4.callback()); 4596 EXPECT_EQ(ERR_IO_PENDING, rv); 4597 4598 rv = callback4.WaitForResult(); 4599 EXPECT_EQ(OK, rv); 4600 4601 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4602 4603 TestCompletionCallback callback5; 4604 4605 // One more roundtrip 4606 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback()); 4607 EXPECT_EQ(ERR_IO_PENDING, rv); 4608 4609 rv = callback5.WaitForResult(); 4610 EXPECT_EQ(OK, rv); 4611 4612 response = trans->GetResponseInfo(); 4613 EXPECT_TRUE(response->auth_challenge.get() == NULL); 4614 EXPECT_EQ(13, response->headers->GetContentLength()); 4615 } 4616 #endif // NTLM_PORTABLE 4617 4618 // Test reading a server response which has only headers, and no body. 4619 // After some maximum number of bytes is consumed, the transaction should 4620 // fail with ERR_RESPONSE_HEADERS_TOO_BIG. 4621 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) { 4622 HttpRequestInfo request; 4623 request.method = "GET"; 4624 request.url = GURL("http://www.google.com/"); 4625 request.load_flags = 0; 4626 4627 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4628 scoped_ptr<HttpTransaction> trans( 4629 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 4630 4631 // Respond with 300 kb of headers (we should fail after 256 kb). 4632 std::string large_headers_string; 4633 FillLargeHeadersString(&large_headers_string, 300 * 1024); 4634 4635 MockRead data_reads[] = { 4636 MockRead("HTTP/1.0 200 OK\r\n"), 4637 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()), 4638 MockRead("\r\nBODY"), 4639 MockRead(SYNCHRONOUS, OK), 4640 }; 4641 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4642 session_deps_.socket_factory->AddSocketDataProvider(&data); 4643 4644 TestCompletionCallback callback; 4645 4646 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4647 EXPECT_EQ(ERR_IO_PENDING, rv); 4648 4649 rv = callback.WaitForResult(); 4650 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv); 4651 4652 const HttpResponseInfo* response = trans->GetResponseInfo(); 4653 EXPECT_TRUE(response == NULL); 4654 } 4655 4656 // Make sure that we don't try to reuse a TCPClientSocket when failing to 4657 // establish tunnel. 4658 // http://code.google.com/p/chromium/issues/detail?id=3772 4659 TEST_P(HttpNetworkTransactionTest, 4660 DontRecycleTransportSocketForSSLTunnel) { 4661 HttpRequestInfo request; 4662 request.method = "GET"; 4663 request.url = GURL("https://www.google.com/"); 4664 request.load_flags = 0; 4665 4666 // Configure against proxy server "myproxy:70". 4667 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 4668 4669 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4670 4671 scoped_ptr<HttpTransaction> trans( 4672 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4673 4674 // Since we have proxy, should try to establish tunnel. 4675 MockWrite data_writes1[] = { 4676 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 4677 "Host: www.google.com\r\n" 4678 "Proxy-Connection: keep-alive\r\n\r\n"), 4679 }; 4680 4681 // The proxy responds to the connect with a 404, using a persistent 4682 // connection. Usually a proxy would return 501 (not implemented), 4683 // or 200 (tunnel established). 4684 MockRead data_reads1[] = { 4685 MockRead("HTTP/1.1 404 Not Found\r\n"), 4686 MockRead("Content-Length: 10\r\n\r\n"), 4687 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 4688 }; 4689 4690 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4691 data_writes1, arraysize(data_writes1)); 4692 session_deps_.socket_factory->AddSocketDataProvider(&data1); 4693 4694 TestCompletionCallback callback1; 4695 4696 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 4697 EXPECT_EQ(ERR_IO_PENDING, rv); 4698 4699 rv = callback1.WaitForResult(); 4700 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 4701 4702 const HttpResponseInfo* response = trans->GetResponseInfo(); 4703 EXPECT_TRUE(response == NULL); 4704 4705 // Empty the current queue. This is necessary because idle sockets are 4706 // added to the connection pool asynchronously with a PostTask. 4707 base::MessageLoop::current()->RunUntilIdle(); 4708 4709 // We now check to make sure the TCPClientSocket was not added back to 4710 // the pool. 4711 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4712 trans.reset(); 4713 base::MessageLoop::current()->RunUntilIdle(); 4714 // Make sure that the socket didn't get recycled after calling the destructor. 4715 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4716 } 4717 4718 // Make sure that we recycle a socket after reading all of the response body. 4719 TEST_P(HttpNetworkTransactionTest, RecycleSocket) { 4720 HttpRequestInfo request; 4721 request.method = "GET"; 4722 request.url = GURL("http://www.google.com/"); 4723 request.load_flags = 0; 4724 4725 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4726 4727 scoped_ptr<HttpTransaction> trans( 4728 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4729 4730 MockRead data_reads[] = { 4731 // A part of the response body is received with the response headers. 4732 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"), 4733 // The rest of the response body is received in two parts. 4734 MockRead("lo"), 4735 MockRead(" world"), 4736 MockRead("junk"), // Should not be read!! 4737 MockRead(SYNCHRONOUS, OK), 4738 }; 4739 4740 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4741 session_deps_.socket_factory->AddSocketDataProvider(&data); 4742 4743 TestCompletionCallback callback; 4744 4745 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4746 EXPECT_EQ(ERR_IO_PENDING, rv); 4747 4748 rv = callback.WaitForResult(); 4749 EXPECT_EQ(OK, rv); 4750 4751 const HttpResponseInfo* response = trans->GetResponseInfo(); 4752 ASSERT_TRUE(response != NULL); 4753 4754 EXPECT_TRUE(response->headers.get() != NULL); 4755 std::string status_line = response->headers->GetStatusLine(); 4756 EXPECT_EQ("HTTP/1.1 200 OK", status_line); 4757 4758 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4759 4760 std::string response_data; 4761 rv = ReadTransaction(trans.get(), &response_data); 4762 EXPECT_EQ(OK, rv); 4763 EXPECT_EQ("hello world", response_data); 4764 4765 // Empty the current queue. This is necessary because idle sockets are 4766 // added to the connection pool asynchronously with a PostTask. 4767 base::MessageLoop::current()->RunUntilIdle(); 4768 4769 // We now check to make sure the socket was added back to the pool. 4770 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 4771 } 4772 4773 // Make sure that we recycle a SSL socket after reading all of the response 4774 // body. 4775 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) { 4776 HttpRequestInfo request; 4777 request.method = "GET"; 4778 request.url = GURL("https://www.google.com/"); 4779 request.load_flags = 0; 4780 4781 MockWrite data_writes[] = { 4782 MockWrite("GET / HTTP/1.1\r\n" 4783 "Host: www.google.com\r\n" 4784 "Connection: keep-alive\r\n\r\n"), 4785 }; 4786 4787 MockRead data_reads[] = { 4788 MockRead("HTTP/1.1 200 OK\r\n"), 4789 MockRead("Content-Length: 11\r\n\r\n"), 4790 MockRead("hello world"), 4791 MockRead(SYNCHRONOUS, OK), 4792 }; 4793 4794 SSLSocketDataProvider ssl(ASYNC, OK); 4795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 4796 4797 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4798 data_writes, arraysize(data_writes)); 4799 session_deps_.socket_factory->AddSocketDataProvider(&data); 4800 4801 TestCompletionCallback callback; 4802 4803 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4804 scoped_ptr<HttpTransaction> trans( 4805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4806 4807 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4808 4809 EXPECT_EQ(ERR_IO_PENDING, rv); 4810 EXPECT_EQ(OK, callback.WaitForResult()); 4811 4812 const HttpResponseInfo* response = trans->GetResponseInfo(); 4813 ASSERT_TRUE(response != NULL); 4814 ASSERT_TRUE(response->headers.get() != NULL); 4815 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4816 4817 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4818 4819 std::string response_data; 4820 rv = ReadTransaction(trans.get(), &response_data); 4821 EXPECT_EQ(OK, rv); 4822 EXPECT_EQ("hello world", response_data); 4823 4824 // Empty the current queue. This is necessary because idle sockets are 4825 // added to the connection pool asynchronously with a PostTask. 4826 base::MessageLoop::current()->RunUntilIdle(); 4827 4828 // We now check to make sure the socket was added back to the pool. 4829 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4830 } 4831 4832 // Grab a SSL socket, use it, and put it back into the pool. Then, reuse it 4833 // from the pool and make sure that we recover okay. 4834 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) { 4835 HttpRequestInfo request; 4836 request.method = "GET"; 4837 request.url = GURL("https://www.google.com/"); 4838 request.load_flags = 0; 4839 4840 MockWrite data_writes[] = { 4841 MockWrite("GET / HTTP/1.1\r\n" 4842 "Host: www.google.com\r\n" 4843 "Connection: keep-alive\r\n\r\n"), 4844 MockWrite("GET / HTTP/1.1\r\n" 4845 "Host: www.google.com\r\n" 4846 "Connection: keep-alive\r\n\r\n"), 4847 }; 4848 4849 MockRead data_reads[] = { 4850 MockRead("HTTP/1.1 200 OK\r\n"), 4851 MockRead("Content-Length: 11\r\n\r\n"), 4852 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 4853 MockRead("hello world"), 4854 MockRead(ASYNC, 0, 0) // EOF 4855 }; 4856 4857 SSLSocketDataProvider ssl(ASYNC, OK); 4858 SSLSocketDataProvider ssl2(ASYNC, OK); 4859 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 4860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 4861 4862 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4863 data_writes, arraysize(data_writes)); 4864 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), 4865 data_writes, arraysize(data_writes)); 4866 session_deps_.socket_factory->AddSocketDataProvider(&data); 4867 session_deps_.socket_factory->AddSocketDataProvider(&data2); 4868 4869 TestCompletionCallback callback; 4870 4871 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4872 scoped_ptr<HttpTransaction> trans( 4873 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4874 4875 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4876 4877 EXPECT_EQ(ERR_IO_PENDING, rv); 4878 EXPECT_EQ(OK, callback.WaitForResult()); 4879 4880 const HttpResponseInfo* response = trans->GetResponseInfo(); 4881 ASSERT_TRUE(response != NULL); 4882 ASSERT_TRUE(response->headers.get() != NULL); 4883 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4884 4885 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4886 4887 std::string response_data; 4888 rv = ReadTransaction(trans.get(), &response_data); 4889 EXPECT_EQ(OK, rv); 4890 EXPECT_EQ("hello world", response_data); 4891 4892 // Empty the current queue. This is necessary because idle sockets are 4893 // added to the connection pool asynchronously with a PostTask. 4894 base::MessageLoop::current()->RunUntilIdle(); 4895 4896 // We now check to make sure the socket was added back to the pool. 4897 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4898 4899 // Now start the second transaction, which should reuse the previous socket. 4900 4901 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4902 4903 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4904 4905 EXPECT_EQ(ERR_IO_PENDING, rv); 4906 EXPECT_EQ(OK, callback.WaitForResult()); 4907 4908 response = trans->GetResponseInfo(); 4909 ASSERT_TRUE(response != NULL); 4910 ASSERT_TRUE(response->headers.get() != NULL); 4911 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4912 4913 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4914 4915 rv = ReadTransaction(trans.get(), &response_data); 4916 EXPECT_EQ(OK, rv); 4917 EXPECT_EQ("hello world", response_data); 4918 4919 // Empty the current queue. This is necessary because idle sockets are 4920 // added to the connection pool asynchronously with a PostTask. 4921 base::MessageLoop::current()->RunUntilIdle(); 4922 4923 // We now check to make sure the socket was added back to the pool. 4924 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); 4925 } 4926 4927 // Make sure that we recycle a socket after a zero-length response. 4928 // http://crbug.com/9880 4929 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { 4930 HttpRequestInfo request; 4931 request.method = "GET"; 4932 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&" 4933 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&" 4934 "e=17259,18167,19592,19773,19981,20133,20173,20233&" 4935 "rt=prt.2642,ol.2649,xjs.2951"); 4936 request.load_flags = 0; 4937 4938 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 4939 4940 scoped_ptr<HttpTransaction> trans( 4941 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 4942 4943 MockRead data_reads[] = { 4944 MockRead("HTTP/1.1 204 No Content\r\n" 4945 "Content-Length: 0\r\n" 4946 "Content-Type: text/html\r\n\r\n"), 4947 MockRead("junk"), // Should not be read!! 4948 MockRead(SYNCHRONOUS, OK), 4949 }; 4950 4951 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 4952 session_deps_.socket_factory->AddSocketDataProvider(&data); 4953 4954 TestCompletionCallback callback; 4955 4956 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 4957 EXPECT_EQ(ERR_IO_PENDING, rv); 4958 4959 rv = callback.WaitForResult(); 4960 EXPECT_EQ(OK, rv); 4961 4962 const HttpResponseInfo* response = trans->GetResponseInfo(); 4963 ASSERT_TRUE(response != NULL); 4964 4965 EXPECT_TRUE(response->headers.get() != NULL); 4966 std::string status_line = response->headers->GetStatusLine(); 4967 EXPECT_EQ("HTTP/1.1 204 No Content", status_line); 4968 4969 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); 4970 4971 std::string response_data; 4972 rv = ReadTransaction(trans.get(), &response_data); 4973 EXPECT_EQ(OK, rv); 4974 EXPECT_EQ("", response_data); 4975 4976 // Empty the current queue. This is necessary because idle sockets are 4977 // added to the connection pool asynchronously with a PostTask. 4978 base::MessageLoop::current()->RunUntilIdle(); 4979 4980 // We now check to make sure the socket was added back to the pool. 4981 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); 4982 } 4983 4984 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) { 4985 ScopedVector<UploadElementReader> element_readers; 4986 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 4987 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 4988 4989 HttpRequestInfo request[2]; 4990 // Transaction 1: a GET request that succeeds. The socket is recycled 4991 // after use. 4992 request[0].method = "GET"; 4993 request[0].url = GURL("http://www.google.com/"); 4994 request[0].load_flags = 0; 4995 // Transaction 2: a POST request. Reuses the socket kept alive from 4996 // transaction 1. The first attempts fails when writing the POST data. 4997 // This causes the transaction to retry with a new socket. The second 4998 // attempt succeeds. 4999 request[1].method = "POST"; 5000 request[1].url = GURL("http://www.google.com/login.cgi"); 5001 request[1].upload_data_stream = &upload_data_stream; 5002 request[1].load_flags = 0; 5003 5004 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5005 5006 // The first socket is used for transaction 1 and the first attempt of 5007 // transaction 2. 5008 5009 // The response of transaction 1. 5010 MockRead data_reads1[] = { 5011 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"), 5012 MockRead("hello world"), 5013 MockRead(SYNCHRONOUS, OK), 5014 }; 5015 // The mock write results of transaction 1 and the first attempt of 5016 // transaction 2. 5017 MockWrite data_writes1[] = { 5018 MockWrite(SYNCHRONOUS, 64), // GET 5019 MockWrite(SYNCHRONOUS, 93), // POST 5020 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data 5021 }; 5022 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5023 data_writes1, arraysize(data_writes1)); 5024 5025 // The second socket is used for the second attempt of transaction 2. 5026 5027 // The response of transaction 2. 5028 MockRead data_reads2[] = { 5029 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"), 5030 MockRead("welcome"), 5031 MockRead(SYNCHRONOUS, OK), 5032 }; 5033 // The mock write results of the second attempt of transaction 2. 5034 MockWrite data_writes2[] = { 5035 MockWrite(SYNCHRONOUS, 93), // POST 5036 MockWrite(SYNCHRONOUS, 3), // POST data 5037 }; 5038 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5039 data_writes2, arraysize(data_writes2)); 5040 5041 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5042 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5043 5044 const char* kExpectedResponseData[] = { 5045 "hello world", "welcome" 5046 }; 5047 5048 for (int i = 0; i < 2; ++i) { 5049 scoped_ptr<HttpTransaction> trans( 5050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5051 5052 TestCompletionCallback callback; 5053 5054 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog()); 5055 EXPECT_EQ(ERR_IO_PENDING, rv); 5056 5057 rv = callback.WaitForResult(); 5058 EXPECT_EQ(OK, rv); 5059 5060 const HttpResponseInfo* response = trans->GetResponseInfo(); 5061 ASSERT_TRUE(response != NULL); 5062 5063 EXPECT_TRUE(response->headers.get() != NULL); 5064 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 5065 5066 std::string response_data; 5067 rv = ReadTransaction(trans.get(), &response_data); 5068 EXPECT_EQ(OK, rv); 5069 EXPECT_EQ(kExpectedResponseData[i], response_data); 5070 } 5071 } 5072 5073 // Test the request-challenge-retry sequence for basic auth when there is 5074 // an identity in the URL. The request should be sent as normal, but when 5075 // it fails the identity from the URL is used to answer the challenge. 5076 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) { 5077 HttpRequestInfo request; 5078 request.method = "GET"; 5079 request.url = GURL("http://foo:b@r@www.google.com/"); 5080 request.load_flags = LOAD_NORMAL; 5081 5082 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5083 scoped_ptr<HttpTransaction> trans( 5084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5085 5086 // The password contains an escaped character -- for this test to pass it 5087 // will need to be unescaped by HttpNetworkTransaction. 5088 EXPECT_EQ("b%40r", request.url.password()); 5089 5090 MockWrite data_writes1[] = { 5091 MockWrite("GET / HTTP/1.1\r\n" 5092 "Host: www.google.com\r\n" 5093 "Connection: keep-alive\r\n\r\n"), 5094 }; 5095 5096 MockRead data_reads1[] = { 5097 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5098 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5099 MockRead("Content-Length: 10\r\n\r\n"), 5100 MockRead(SYNCHRONOUS, ERR_FAILED), 5101 }; 5102 5103 // After the challenge above, the transaction will be restarted using the 5104 // identity from the url (foo, b@r) to answer the challenge. 5105 MockWrite data_writes2[] = { 5106 MockWrite("GET / HTTP/1.1\r\n" 5107 "Host: www.google.com\r\n" 5108 "Connection: keep-alive\r\n" 5109 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"), 5110 }; 5111 5112 MockRead data_reads2[] = { 5113 MockRead("HTTP/1.0 200 OK\r\n"), 5114 MockRead("Content-Length: 100\r\n\r\n"), 5115 MockRead(SYNCHRONOUS, OK), 5116 }; 5117 5118 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5119 data_writes1, arraysize(data_writes1)); 5120 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5121 data_writes2, arraysize(data_writes2)); 5122 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5123 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5124 5125 TestCompletionCallback callback1; 5126 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5127 EXPECT_EQ(ERR_IO_PENDING, rv); 5128 rv = callback1.WaitForResult(); 5129 EXPECT_EQ(OK, rv); 5130 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5131 5132 TestCompletionCallback callback2; 5133 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5134 EXPECT_EQ(ERR_IO_PENDING, rv); 5135 rv = callback2.WaitForResult(); 5136 EXPECT_EQ(OK, rv); 5137 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5138 5139 const HttpResponseInfo* response = trans->GetResponseInfo(); 5140 ASSERT_TRUE(response != NULL); 5141 5142 // There is no challenge info, since the identity in URL worked. 5143 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5144 5145 EXPECT_EQ(100, response->headers->GetContentLength()); 5146 5147 // Empty the current queue. 5148 base::MessageLoop::current()->RunUntilIdle(); 5149 } 5150 5151 // Test the request-challenge-retry sequence for basic auth when there is an 5152 // incorrect identity in the URL. The identity from the URL should be used only 5153 // once. 5154 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) { 5155 HttpRequestInfo request; 5156 request.method = "GET"; 5157 // Note: the URL has a username:password in it. The password "baz" is 5158 // wrong (should be "bar"). 5159 request.url = GURL("http://foo:baz@www.google.com/"); 5160 5161 request.load_flags = LOAD_NORMAL; 5162 5163 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5164 scoped_ptr<HttpTransaction> trans( 5165 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5166 5167 MockWrite data_writes1[] = { 5168 MockWrite("GET / HTTP/1.1\r\n" 5169 "Host: www.google.com\r\n" 5170 "Connection: keep-alive\r\n\r\n"), 5171 }; 5172 5173 MockRead data_reads1[] = { 5174 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5175 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5176 MockRead("Content-Length: 10\r\n\r\n"), 5177 MockRead(SYNCHRONOUS, ERR_FAILED), 5178 }; 5179 5180 // After the challenge above, the transaction will be restarted using the 5181 // identity from the url (foo, baz) to answer the challenge. 5182 MockWrite data_writes2[] = { 5183 MockWrite("GET / HTTP/1.1\r\n" 5184 "Host: www.google.com\r\n" 5185 "Connection: keep-alive\r\n" 5186 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 5187 }; 5188 5189 MockRead data_reads2[] = { 5190 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5191 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5192 MockRead("Content-Length: 10\r\n\r\n"), 5193 MockRead(SYNCHRONOUS, ERR_FAILED), 5194 }; 5195 5196 // After the challenge above, the transaction will be restarted using the 5197 // identity supplied by the user (foo, bar) to answer the challenge. 5198 MockWrite data_writes3[] = { 5199 MockWrite("GET / HTTP/1.1\r\n" 5200 "Host: www.google.com\r\n" 5201 "Connection: keep-alive\r\n" 5202 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5203 }; 5204 5205 MockRead data_reads3[] = { 5206 MockRead("HTTP/1.0 200 OK\r\n"), 5207 MockRead("Content-Length: 100\r\n\r\n"), 5208 MockRead(SYNCHRONOUS, OK), 5209 }; 5210 5211 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5212 data_writes1, arraysize(data_writes1)); 5213 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5214 data_writes2, arraysize(data_writes2)); 5215 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 5216 data_writes3, arraysize(data_writes3)); 5217 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5218 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5219 session_deps_.socket_factory->AddSocketDataProvider(&data3); 5220 5221 TestCompletionCallback callback1; 5222 5223 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5224 EXPECT_EQ(ERR_IO_PENDING, rv); 5225 5226 rv = callback1.WaitForResult(); 5227 EXPECT_EQ(OK, rv); 5228 5229 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5230 TestCompletionCallback callback2; 5231 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5232 EXPECT_EQ(ERR_IO_PENDING, rv); 5233 rv = callback2.WaitForResult(); 5234 EXPECT_EQ(OK, rv); 5235 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5236 5237 const HttpResponseInfo* response = trans->GetResponseInfo(); 5238 ASSERT_TRUE(response != NULL); 5239 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5240 5241 TestCompletionCallback callback3; 5242 rv = trans->RestartWithAuth( 5243 AuthCredentials(kFoo, kBar), callback3.callback()); 5244 EXPECT_EQ(ERR_IO_PENDING, rv); 5245 rv = callback3.WaitForResult(); 5246 EXPECT_EQ(OK, rv); 5247 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5248 5249 response = trans->GetResponseInfo(); 5250 ASSERT_TRUE(response != NULL); 5251 5252 // There is no challenge info, since the identity worked. 5253 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5254 5255 EXPECT_EQ(100, response->headers->GetContentLength()); 5256 5257 // Empty the current queue. 5258 base::MessageLoop::current()->RunUntilIdle(); 5259 } 5260 5261 5262 // Test the request-challenge-retry sequence for basic auth when there is a 5263 // correct identity in the URL, but its use is being suppressed. The identity 5264 // from the URL should never be used. 5265 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) { 5266 HttpRequestInfo request; 5267 request.method = "GET"; 5268 request.url = GURL("http://foo:bar@www.google.com/"); 5269 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; 5270 5271 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5272 scoped_ptr<HttpTransaction> trans( 5273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5274 5275 MockWrite data_writes1[] = { 5276 MockWrite("GET / HTTP/1.1\r\n" 5277 "Host: www.google.com\r\n" 5278 "Connection: keep-alive\r\n\r\n"), 5279 }; 5280 5281 MockRead data_reads1[] = { 5282 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5283 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5284 MockRead("Content-Length: 10\r\n\r\n"), 5285 MockRead(SYNCHRONOUS, ERR_FAILED), 5286 }; 5287 5288 // After the challenge above, the transaction will be restarted using the 5289 // identity supplied by the user, not the one in the URL, to answer the 5290 // challenge. 5291 MockWrite data_writes3[] = { 5292 MockWrite("GET / HTTP/1.1\r\n" 5293 "Host: www.google.com\r\n" 5294 "Connection: keep-alive\r\n" 5295 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5296 }; 5297 5298 MockRead data_reads3[] = { 5299 MockRead("HTTP/1.0 200 OK\r\n"), 5300 MockRead("Content-Length: 100\r\n\r\n"), 5301 MockRead(SYNCHRONOUS, OK), 5302 }; 5303 5304 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5305 data_writes1, arraysize(data_writes1)); 5306 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 5307 data_writes3, arraysize(data_writes3)); 5308 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5309 session_deps_.socket_factory->AddSocketDataProvider(&data3); 5310 5311 TestCompletionCallback callback1; 5312 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5313 EXPECT_EQ(ERR_IO_PENDING, rv); 5314 rv = callback1.WaitForResult(); 5315 EXPECT_EQ(OK, rv); 5316 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5317 5318 const HttpResponseInfo* response = trans->GetResponseInfo(); 5319 ASSERT_TRUE(response != NULL); 5320 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5321 5322 TestCompletionCallback callback3; 5323 rv = trans->RestartWithAuth( 5324 AuthCredentials(kFoo, kBar), callback3.callback()); 5325 EXPECT_EQ(ERR_IO_PENDING, rv); 5326 rv = callback3.WaitForResult(); 5327 EXPECT_EQ(OK, rv); 5328 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5329 5330 response = trans->GetResponseInfo(); 5331 ASSERT_TRUE(response != NULL); 5332 5333 // There is no challenge info, since the identity worked. 5334 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5335 EXPECT_EQ(100, response->headers->GetContentLength()); 5336 5337 // Empty the current queue. 5338 base::MessageLoop::current()->RunUntilIdle(); 5339 } 5340 5341 // Test that previously tried username/passwords for a realm get re-used. 5342 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { 5343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5344 5345 // Transaction 1: authenticate (foo, bar) on MyRealm1 5346 { 5347 HttpRequestInfo request; 5348 request.method = "GET"; 5349 request.url = GURL("http://www.google.com/x/y/z"); 5350 request.load_flags = 0; 5351 5352 scoped_ptr<HttpTransaction> trans( 5353 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5354 5355 MockWrite data_writes1[] = { 5356 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5357 "Host: www.google.com\r\n" 5358 "Connection: keep-alive\r\n\r\n"), 5359 }; 5360 5361 MockRead data_reads1[] = { 5362 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5363 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5364 MockRead("Content-Length: 10000\r\n\r\n"), 5365 MockRead(SYNCHRONOUS, ERR_FAILED), 5366 }; 5367 5368 // Resend with authorization (username=foo, password=bar) 5369 MockWrite data_writes2[] = { 5370 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5371 "Host: www.google.com\r\n" 5372 "Connection: keep-alive\r\n" 5373 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5374 }; 5375 5376 // Sever accepts the authorization. 5377 MockRead data_reads2[] = { 5378 MockRead("HTTP/1.0 200 OK\r\n"), 5379 MockRead("Content-Length: 100\r\n\r\n"), 5380 MockRead(SYNCHRONOUS, OK), 5381 }; 5382 5383 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5384 data_writes1, arraysize(data_writes1)); 5385 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5386 data_writes2, arraysize(data_writes2)); 5387 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5388 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5389 5390 TestCompletionCallback callback1; 5391 5392 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5393 EXPECT_EQ(ERR_IO_PENDING, rv); 5394 5395 rv = callback1.WaitForResult(); 5396 EXPECT_EQ(OK, rv); 5397 5398 const HttpResponseInfo* response = trans->GetResponseInfo(); 5399 ASSERT_TRUE(response != NULL); 5400 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5401 5402 TestCompletionCallback callback2; 5403 5404 rv = trans->RestartWithAuth( 5405 AuthCredentials(kFoo, kBar), callback2.callback()); 5406 EXPECT_EQ(ERR_IO_PENDING, rv); 5407 5408 rv = callback2.WaitForResult(); 5409 EXPECT_EQ(OK, rv); 5410 5411 response = trans->GetResponseInfo(); 5412 ASSERT_TRUE(response != NULL); 5413 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5414 EXPECT_EQ(100, response->headers->GetContentLength()); 5415 } 5416 5417 // ------------------------------------------------------------------------ 5418 5419 // Transaction 2: authenticate (foo2, bar2) on MyRealm2 5420 { 5421 HttpRequestInfo request; 5422 request.method = "GET"; 5423 // Note that Transaction 1 was at /x/y/z, so this is in the same 5424 // protection space as MyRealm1. 5425 request.url = GURL("http://www.google.com/x/y/a/b"); 5426 request.load_flags = 0; 5427 5428 scoped_ptr<HttpTransaction> trans( 5429 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5430 5431 MockWrite data_writes1[] = { 5432 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5433 "Host: www.google.com\r\n" 5434 "Connection: keep-alive\r\n" 5435 // Send preemptive authorization for MyRealm1 5436 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5437 }; 5438 5439 // The server didn't like the preemptive authorization, and 5440 // challenges us for a different realm (MyRealm2). 5441 MockRead data_reads1[] = { 5442 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5443 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"), 5444 MockRead("Content-Length: 10000\r\n\r\n"), 5445 MockRead(SYNCHRONOUS, ERR_FAILED), 5446 }; 5447 5448 // Resend with authorization for MyRealm2 (username=foo2, password=bar2) 5449 MockWrite data_writes2[] = { 5450 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5451 "Host: www.google.com\r\n" 5452 "Connection: keep-alive\r\n" 5453 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 5454 }; 5455 5456 // Sever accepts the authorization. 5457 MockRead data_reads2[] = { 5458 MockRead("HTTP/1.0 200 OK\r\n"), 5459 MockRead("Content-Length: 100\r\n\r\n"), 5460 MockRead(SYNCHRONOUS, OK), 5461 }; 5462 5463 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5464 data_writes1, arraysize(data_writes1)); 5465 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5466 data_writes2, arraysize(data_writes2)); 5467 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5468 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5469 5470 TestCompletionCallback callback1; 5471 5472 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5473 EXPECT_EQ(ERR_IO_PENDING, rv); 5474 5475 rv = callback1.WaitForResult(); 5476 EXPECT_EQ(OK, rv); 5477 5478 const HttpResponseInfo* response = trans->GetResponseInfo(); 5479 ASSERT_TRUE(response != NULL); 5480 ASSERT_TRUE(response->auth_challenge.get()); 5481 EXPECT_FALSE(response->auth_challenge->is_proxy); 5482 EXPECT_EQ("www.google.com:80", 5483 response->auth_challenge->challenger.ToString()); 5484 EXPECT_EQ("MyRealm2", response->auth_challenge->realm); 5485 EXPECT_EQ("basic", response->auth_challenge->scheme); 5486 5487 TestCompletionCallback callback2; 5488 5489 rv = trans->RestartWithAuth( 5490 AuthCredentials(kFoo2, kBar2), callback2.callback()); 5491 EXPECT_EQ(ERR_IO_PENDING, rv); 5492 5493 rv = callback2.WaitForResult(); 5494 EXPECT_EQ(OK, rv); 5495 5496 response = trans->GetResponseInfo(); 5497 ASSERT_TRUE(response != NULL); 5498 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5499 EXPECT_EQ(100, response->headers->GetContentLength()); 5500 } 5501 5502 // ------------------------------------------------------------------------ 5503 5504 // Transaction 3: Resend a request in MyRealm's protection space -- 5505 // succeed with preemptive authorization. 5506 { 5507 HttpRequestInfo request; 5508 request.method = "GET"; 5509 request.url = GURL("http://www.google.com/x/y/z2"); 5510 request.load_flags = 0; 5511 5512 scoped_ptr<HttpTransaction> trans( 5513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5514 5515 MockWrite data_writes1[] = { 5516 MockWrite("GET /x/y/z2 HTTP/1.1\r\n" 5517 "Host: www.google.com\r\n" 5518 "Connection: keep-alive\r\n" 5519 // The authorization for MyRealm1 gets sent preemptively 5520 // (since the url is in the same protection space) 5521 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5522 }; 5523 5524 // Sever accepts the preemptive authorization 5525 MockRead data_reads1[] = { 5526 MockRead("HTTP/1.0 200 OK\r\n"), 5527 MockRead("Content-Length: 100\r\n\r\n"), 5528 MockRead(SYNCHRONOUS, OK), 5529 }; 5530 5531 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5532 data_writes1, arraysize(data_writes1)); 5533 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5534 5535 TestCompletionCallback callback1; 5536 5537 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5538 EXPECT_EQ(ERR_IO_PENDING, rv); 5539 5540 rv = callback1.WaitForResult(); 5541 EXPECT_EQ(OK, rv); 5542 5543 const HttpResponseInfo* response = trans->GetResponseInfo(); 5544 ASSERT_TRUE(response != NULL); 5545 5546 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5547 EXPECT_EQ(100, response->headers->GetContentLength()); 5548 } 5549 5550 // ------------------------------------------------------------------------ 5551 5552 // Transaction 4: request another URL in MyRealm (however the 5553 // url is not known to belong to the protection space, so no pre-auth). 5554 { 5555 HttpRequestInfo request; 5556 request.method = "GET"; 5557 request.url = GURL("http://www.google.com/x/1"); 5558 request.load_flags = 0; 5559 5560 scoped_ptr<HttpTransaction> trans( 5561 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5562 5563 MockWrite data_writes1[] = { 5564 MockWrite("GET /x/1 HTTP/1.1\r\n" 5565 "Host: www.google.com\r\n" 5566 "Connection: keep-alive\r\n\r\n"), 5567 }; 5568 5569 MockRead data_reads1[] = { 5570 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5571 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5572 MockRead("Content-Length: 10000\r\n\r\n"), 5573 MockRead(SYNCHRONOUS, ERR_FAILED), 5574 }; 5575 5576 // Resend with authorization from MyRealm's cache. 5577 MockWrite data_writes2[] = { 5578 MockWrite("GET /x/1 HTTP/1.1\r\n" 5579 "Host: www.google.com\r\n" 5580 "Connection: keep-alive\r\n" 5581 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5582 }; 5583 5584 // Sever accepts the authorization. 5585 MockRead data_reads2[] = { 5586 MockRead("HTTP/1.0 200 OK\r\n"), 5587 MockRead("Content-Length: 100\r\n\r\n"), 5588 MockRead(SYNCHRONOUS, OK), 5589 }; 5590 5591 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5592 data_writes1, arraysize(data_writes1)); 5593 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5594 data_writes2, arraysize(data_writes2)); 5595 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5596 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5597 5598 TestCompletionCallback callback1; 5599 5600 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5601 EXPECT_EQ(ERR_IO_PENDING, rv); 5602 5603 rv = callback1.WaitForResult(); 5604 EXPECT_EQ(OK, rv); 5605 5606 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5607 TestCompletionCallback callback2; 5608 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5609 EXPECT_EQ(ERR_IO_PENDING, rv); 5610 rv = callback2.WaitForResult(); 5611 EXPECT_EQ(OK, rv); 5612 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5613 5614 const HttpResponseInfo* response = trans->GetResponseInfo(); 5615 ASSERT_TRUE(response != NULL); 5616 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5617 EXPECT_EQ(100, response->headers->GetContentLength()); 5618 } 5619 5620 // ------------------------------------------------------------------------ 5621 5622 // Transaction 5: request a URL in MyRealm, but the server rejects the 5623 // cached identity. Should invalidate and re-prompt. 5624 { 5625 HttpRequestInfo request; 5626 request.method = "GET"; 5627 request.url = GURL("http://www.google.com/p/q/t"); 5628 request.load_flags = 0; 5629 5630 scoped_ptr<HttpTransaction> trans( 5631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5632 5633 MockWrite data_writes1[] = { 5634 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5635 "Host: www.google.com\r\n" 5636 "Connection: keep-alive\r\n\r\n"), 5637 }; 5638 5639 MockRead data_reads1[] = { 5640 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5641 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5642 MockRead("Content-Length: 10000\r\n\r\n"), 5643 MockRead(SYNCHRONOUS, ERR_FAILED), 5644 }; 5645 5646 // Resend with authorization from cache for MyRealm. 5647 MockWrite data_writes2[] = { 5648 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5649 "Host: www.google.com\r\n" 5650 "Connection: keep-alive\r\n" 5651 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5652 }; 5653 5654 // Sever rejects the authorization. 5655 MockRead data_reads2[] = { 5656 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5657 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5658 MockRead("Content-Length: 10000\r\n\r\n"), 5659 MockRead(SYNCHRONOUS, ERR_FAILED), 5660 }; 5661 5662 // At this point we should prompt for new credentials for MyRealm. 5663 // Restart with username=foo3, password=foo4. 5664 MockWrite data_writes3[] = { 5665 MockWrite("GET /p/q/t HTTP/1.1\r\n" 5666 "Host: www.google.com\r\n" 5667 "Connection: keep-alive\r\n" 5668 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"), 5669 }; 5670 5671 // Sever accepts the authorization. 5672 MockRead data_reads3[] = { 5673 MockRead("HTTP/1.0 200 OK\r\n"), 5674 MockRead("Content-Length: 100\r\n\r\n"), 5675 MockRead(SYNCHRONOUS, OK), 5676 }; 5677 5678 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5679 data_writes1, arraysize(data_writes1)); 5680 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5681 data_writes2, arraysize(data_writes2)); 5682 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 5683 data_writes3, arraysize(data_writes3)); 5684 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5685 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5686 session_deps_.socket_factory->AddSocketDataProvider(&data3); 5687 5688 TestCompletionCallback callback1; 5689 5690 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5691 EXPECT_EQ(ERR_IO_PENDING, rv); 5692 5693 rv = callback1.WaitForResult(); 5694 EXPECT_EQ(OK, rv); 5695 5696 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 5697 TestCompletionCallback callback2; 5698 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); 5699 EXPECT_EQ(ERR_IO_PENDING, rv); 5700 rv = callback2.WaitForResult(); 5701 EXPECT_EQ(OK, rv); 5702 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 5703 5704 const HttpResponseInfo* response = trans->GetResponseInfo(); 5705 ASSERT_TRUE(response != NULL); 5706 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 5707 5708 TestCompletionCallback callback3; 5709 5710 rv = trans->RestartWithAuth( 5711 AuthCredentials(kFoo3, kBar3), callback3.callback()); 5712 EXPECT_EQ(ERR_IO_PENDING, rv); 5713 5714 rv = callback3.WaitForResult(); 5715 EXPECT_EQ(OK, rv); 5716 5717 response = trans->GetResponseInfo(); 5718 ASSERT_TRUE(response != NULL); 5719 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5720 EXPECT_EQ(100, response->headers->GetContentLength()); 5721 } 5722 } 5723 5724 // Tests that nonce count increments when multiple auth attempts 5725 // are started with the same nonce. 5726 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) { 5727 HttpAuthHandlerDigest::Factory* digest_factory = 5728 new HttpAuthHandlerDigest::Factory(); 5729 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator = 5730 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef"); 5731 digest_factory->set_nonce_generator(nonce_generator); 5732 session_deps_.http_auth_handler_factory.reset(digest_factory); 5733 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5734 5735 // Transaction 1: authenticate (foo, bar) on MyRealm1 5736 { 5737 HttpRequestInfo request; 5738 request.method = "GET"; 5739 request.url = GURL("http://www.google.com/x/y/z"); 5740 request.load_flags = 0; 5741 5742 scoped_ptr<HttpTransaction> trans( 5743 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5744 5745 MockWrite data_writes1[] = { 5746 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5747 "Host: www.google.com\r\n" 5748 "Connection: keep-alive\r\n\r\n"), 5749 }; 5750 5751 MockRead data_reads1[] = { 5752 MockRead("HTTP/1.0 401 Unauthorized\r\n"), 5753 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", " 5754 "algorithm=MD5, qop=\"auth\"\r\n\r\n"), 5755 MockRead(SYNCHRONOUS, OK), 5756 }; 5757 5758 // Resend with authorization (username=foo, password=bar) 5759 MockWrite data_writes2[] = { 5760 MockWrite("GET /x/y/z HTTP/1.1\r\n" 5761 "Host: www.google.com\r\n" 5762 "Connection: keep-alive\r\n" 5763 "Authorization: Digest username=\"foo\", realm=\"digestive\", " 5764 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, " 5765 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, " 5766 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"), 5767 }; 5768 5769 // Sever accepts the authorization. 5770 MockRead data_reads2[] = { 5771 MockRead("HTTP/1.0 200 OK\r\n"), 5772 MockRead(SYNCHRONOUS, OK), 5773 }; 5774 5775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5776 data_writes1, arraysize(data_writes1)); 5777 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5778 data_writes2, arraysize(data_writes2)); 5779 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5780 session_deps_.socket_factory->AddSocketDataProvider(&data2); 5781 5782 TestCompletionCallback callback1; 5783 5784 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5785 EXPECT_EQ(ERR_IO_PENDING, rv); 5786 5787 rv = callback1.WaitForResult(); 5788 EXPECT_EQ(OK, rv); 5789 5790 const HttpResponseInfo* response = trans->GetResponseInfo(); 5791 ASSERT_TRUE(response != NULL); 5792 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get())); 5793 5794 TestCompletionCallback callback2; 5795 5796 rv = trans->RestartWithAuth( 5797 AuthCredentials(kFoo, kBar), callback2.callback()); 5798 EXPECT_EQ(ERR_IO_PENDING, rv); 5799 5800 rv = callback2.WaitForResult(); 5801 EXPECT_EQ(OK, rv); 5802 5803 response = trans->GetResponseInfo(); 5804 ASSERT_TRUE(response != NULL); 5805 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5806 } 5807 5808 // ------------------------------------------------------------------------ 5809 5810 // Transaction 2: Request another resource in digestive's protection space. 5811 // This will preemptively add an Authorization header which should have an 5812 // "nc" value of 2 (as compared to 1 in the first use. 5813 { 5814 HttpRequestInfo request; 5815 request.method = "GET"; 5816 // Note that Transaction 1 was at /x/y/z, so this is in the same 5817 // protection space as digest. 5818 request.url = GURL("http://www.google.com/x/y/a/b"); 5819 request.load_flags = 0; 5820 5821 scoped_ptr<HttpTransaction> trans( 5822 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 5823 5824 MockWrite data_writes1[] = { 5825 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 5826 "Host: www.google.com\r\n" 5827 "Connection: keep-alive\r\n" 5828 "Authorization: Digest username=\"foo\", realm=\"digestive\", " 5829 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, " 5830 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, " 5831 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"), 5832 }; 5833 5834 // Sever accepts the authorization. 5835 MockRead data_reads1[] = { 5836 MockRead("HTTP/1.0 200 OK\r\n"), 5837 MockRead("Content-Length: 100\r\n\r\n"), 5838 MockRead(SYNCHRONOUS, OK), 5839 }; 5840 5841 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5842 data_writes1, arraysize(data_writes1)); 5843 session_deps_.socket_factory->AddSocketDataProvider(&data1); 5844 5845 TestCompletionCallback callback1; 5846 5847 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 5848 EXPECT_EQ(ERR_IO_PENDING, rv); 5849 5850 rv = callback1.WaitForResult(); 5851 EXPECT_EQ(OK, rv); 5852 5853 const HttpResponseInfo* response = trans->GetResponseInfo(); 5854 ASSERT_TRUE(response != NULL); 5855 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5856 } 5857 } 5858 5859 // Test the ResetStateForRestart() private method. 5860 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) { 5861 // Create a transaction (the dependencies aren't important). 5862 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5863 scoped_ptr<HttpNetworkTransaction> trans( 5864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5865 5866 // Setup some state (which we expect ResetStateForRestart() will clear). 5867 trans->read_buf_ = new IOBuffer(15); 5868 trans->read_buf_len_ = 15; 5869 trans->request_headers_.SetHeader("Authorization", "NTLM"); 5870 5871 // Setup state in response_ 5872 HttpResponseInfo* response = &trans->response_; 5873 response->auth_challenge = new AuthChallengeInfo(); 5874 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical. 5875 response->response_time = base::Time::Now(); 5876 response->was_cached = true; // (Wouldn't ever actually be true...) 5877 5878 { // Setup state for response_.vary_data 5879 HttpRequestInfo request; 5880 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n"); 5881 std::replace(temp.begin(), temp.end(), '\n', '\0'); 5882 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp)); 5883 request.extra_headers.SetHeader("Foo", "1"); 5884 request.extra_headers.SetHeader("bar", "23"); 5885 EXPECT_TRUE(response->vary_data.Init(request, *headers.get())); 5886 } 5887 5888 // Cause the above state to be reset. 5889 trans->ResetStateForRestart(); 5890 5891 // Verify that the state that needed to be reset, has been reset. 5892 EXPECT_TRUE(trans->read_buf_.get() == NULL); 5893 EXPECT_EQ(0, trans->read_buf_len_); 5894 EXPECT_TRUE(trans->request_headers_.IsEmpty()); 5895 EXPECT_TRUE(response->auth_challenge.get() == NULL); 5896 EXPECT_TRUE(response->headers.get() == NULL); 5897 EXPECT_FALSE(response->was_cached); 5898 EXPECT_EQ(0U, response->ssl_info.cert_status); 5899 EXPECT_FALSE(response->vary_data.is_valid()); 5900 } 5901 5902 // Test HTTPS connections to a site with a bad certificate 5903 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) { 5904 HttpRequestInfo request; 5905 request.method = "GET"; 5906 request.url = GURL("https://www.google.com/"); 5907 request.load_flags = 0; 5908 5909 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 5910 scoped_ptr<HttpTransaction> trans( 5911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 5912 5913 MockWrite data_writes[] = { 5914 MockWrite("GET / HTTP/1.1\r\n" 5915 "Host: www.google.com\r\n" 5916 "Connection: keep-alive\r\n\r\n"), 5917 }; 5918 5919 MockRead data_reads[] = { 5920 MockRead("HTTP/1.0 200 OK\r\n"), 5921 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5922 MockRead("Content-Length: 100\r\n\r\n"), 5923 MockRead(SYNCHRONOUS, OK), 5924 }; 5925 5926 StaticSocketDataProvider ssl_bad_certificate; 5927 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5928 data_writes, arraysize(data_writes)); 5929 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 5930 SSLSocketDataProvider ssl(ASYNC, OK); 5931 5932 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 5933 session_deps_.socket_factory->AddSocketDataProvider(&data); 5934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 5935 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 5936 5937 TestCompletionCallback callback; 5938 5939 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5940 EXPECT_EQ(ERR_IO_PENDING, rv); 5941 5942 rv = callback.WaitForResult(); 5943 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 5944 5945 rv = trans->RestartIgnoringLastError(callback.callback()); 5946 EXPECT_EQ(ERR_IO_PENDING, rv); 5947 5948 rv = callback.WaitForResult(); 5949 EXPECT_EQ(OK, rv); 5950 5951 const HttpResponseInfo* response = trans->GetResponseInfo(); 5952 5953 ASSERT_TRUE(response != NULL); 5954 EXPECT_EQ(100, response->headers->GetContentLength()); 5955 } 5956 5957 // Test HTTPS connections to a site with a bad certificate, going through a 5958 // proxy 5959 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { 5960 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 5961 5962 HttpRequestInfo request; 5963 request.method = "GET"; 5964 request.url = GURL("https://www.google.com/"); 5965 request.load_flags = 0; 5966 5967 MockWrite proxy_writes[] = { 5968 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 5969 "Host: www.google.com\r\n" 5970 "Proxy-Connection: keep-alive\r\n\r\n"), 5971 }; 5972 5973 MockRead proxy_reads[] = { 5974 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 5975 MockRead(SYNCHRONOUS, OK) 5976 }; 5977 5978 MockWrite data_writes[] = { 5979 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 5980 "Host: www.google.com\r\n" 5981 "Proxy-Connection: keep-alive\r\n\r\n"), 5982 MockWrite("GET / HTTP/1.1\r\n" 5983 "Host: www.google.com\r\n" 5984 "Connection: keep-alive\r\n\r\n"), 5985 }; 5986 5987 MockRead data_reads[] = { 5988 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 5989 MockRead("HTTP/1.0 200 OK\r\n"), 5990 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5991 MockRead("Content-Length: 100\r\n\r\n"), 5992 MockRead(SYNCHRONOUS, OK), 5993 }; 5994 5995 StaticSocketDataProvider ssl_bad_certificate( 5996 proxy_reads, arraysize(proxy_reads), 5997 proxy_writes, arraysize(proxy_writes)); 5998 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5999 data_writes, arraysize(data_writes)); 6000 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 6001 SSLSocketDataProvider ssl(ASYNC, OK); 6002 6003 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 6004 session_deps_.socket_factory->AddSocketDataProvider(&data); 6005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 6006 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6007 6008 TestCompletionCallback callback; 6009 6010 for (int i = 0; i < 2; i++) { 6011 session_deps_.socket_factory->ResetNextMockIndexes(); 6012 6013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6014 scoped_ptr<HttpTransaction> trans( 6015 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6016 6017 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6018 EXPECT_EQ(ERR_IO_PENDING, rv); 6019 6020 rv = callback.WaitForResult(); 6021 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 6022 6023 rv = trans->RestartIgnoringLastError(callback.callback()); 6024 EXPECT_EQ(ERR_IO_PENDING, rv); 6025 6026 rv = callback.WaitForResult(); 6027 EXPECT_EQ(OK, rv); 6028 6029 const HttpResponseInfo* response = trans->GetResponseInfo(); 6030 6031 ASSERT_TRUE(response != NULL); 6032 EXPECT_EQ(100, response->headers->GetContentLength()); 6033 } 6034 } 6035 6036 6037 // Test HTTPS connections to a site, going through an HTTPS proxy 6038 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { 6039 session_deps_.proxy_service.reset( 6040 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 6041 CapturingNetLog net_log; 6042 session_deps_.net_log = &net_log; 6043 6044 HttpRequestInfo request; 6045 request.method = "GET"; 6046 request.url = GURL("https://www.google.com/"); 6047 request.load_flags = 0; 6048 6049 MockWrite data_writes[] = { 6050 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6051 "Host: www.google.com\r\n" 6052 "Proxy-Connection: keep-alive\r\n\r\n"), 6053 MockWrite("GET / HTTP/1.1\r\n" 6054 "Host: www.google.com\r\n" 6055 "Connection: keep-alive\r\n\r\n"), 6056 }; 6057 6058 MockRead data_reads[] = { 6059 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6060 MockRead("HTTP/1.1 200 OK\r\n"), 6061 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6062 MockRead("Content-Length: 100\r\n\r\n"), 6063 MockRead(SYNCHRONOUS, OK), 6064 }; 6065 6066 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6067 data_writes, arraysize(data_writes)); 6068 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6069 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel 6070 6071 session_deps_.socket_factory->AddSocketDataProvider(&data); 6072 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6073 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl); 6074 6075 TestCompletionCallback callback; 6076 6077 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6078 scoped_ptr<HttpTransaction> trans( 6079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6080 6081 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6082 EXPECT_EQ(ERR_IO_PENDING, rv); 6083 6084 rv = callback.WaitForResult(); 6085 EXPECT_EQ(OK, rv); 6086 const HttpResponseInfo* response = trans->GetResponseInfo(); 6087 6088 ASSERT_TRUE(response != NULL); 6089 6090 EXPECT_TRUE(response->headers->IsKeepAlive()); 6091 EXPECT_EQ(200, response->headers->response_code()); 6092 EXPECT_EQ(100, response->headers->GetContentLength()); 6093 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6094 6095 LoadTimingInfo load_timing_info; 6096 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6097 TestLoadTimingNotReusedWithPac(load_timing_info, 6098 CONNECT_TIMING_HAS_SSL_TIMES); 6099 } 6100 6101 // Test an HTTPS Proxy's ability to redirect a CONNECT request 6102 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { 6103 session_deps_.proxy_service.reset( 6104 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 6105 CapturingNetLog net_log; 6106 session_deps_.net_log = &net_log; 6107 6108 HttpRequestInfo request; 6109 request.method = "GET"; 6110 request.url = GURL("https://www.google.com/"); 6111 request.load_flags = 0; 6112 6113 MockWrite data_writes[] = { 6114 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6115 "Host: www.google.com\r\n" 6116 "Proxy-Connection: keep-alive\r\n\r\n"), 6117 }; 6118 6119 MockRead data_reads[] = { 6120 MockRead("HTTP/1.1 302 Redirect\r\n"), 6121 MockRead("Location: http://login.example.com/\r\n"), 6122 MockRead("Content-Length: 0\r\n\r\n"), 6123 MockRead(SYNCHRONOUS, OK), 6124 }; 6125 6126 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6127 data_writes, arraysize(data_writes)); 6128 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6129 6130 session_deps_.socket_factory->AddSocketDataProvider(&data); 6131 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6132 6133 TestCompletionCallback callback; 6134 6135 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6136 scoped_ptr<HttpTransaction> trans( 6137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6138 6139 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6140 EXPECT_EQ(ERR_IO_PENDING, rv); 6141 6142 rv = callback.WaitForResult(); 6143 EXPECT_EQ(OK, rv); 6144 const HttpResponseInfo* response = trans->GetResponseInfo(); 6145 6146 ASSERT_TRUE(response != NULL); 6147 6148 EXPECT_EQ(302, response->headers->response_code()); 6149 std::string url; 6150 EXPECT_TRUE(response->headers->IsRedirect(&url)); 6151 EXPECT_EQ("http://login.example.com/", url); 6152 6153 // In the case of redirects from proxies, HttpNetworkTransaction returns 6154 // timing for the proxy connection instead of the connection to the host, 6155 // and no send / receive times. 6156 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse. 6157 LoadTimingInfo load_timing_info; 6158 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6159 6160 EXPECT_FALSE(load_timing_info.socket_reused); 6161 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 6162 6163 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); 6164 EXPECT_LE(load_timing_info.proxy_resolve_start, 6165 load_timing_info.proxy_resolve_end); 6166 EXPECT_LE(load_timing_info.proxy_resolve_end, 6167 load_timing_info.connect_timing.connect_start); 6168 ExpectConnectTimingHasTimes( 6169 load_timing_info.connect_timing, 6170 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES); 6171 6172 EXPECT_TRUE(load_timing_info.send_start.is_null()); 6173 EXPECT_TRUE(load_timing_info.send_end.is_null()); 6174 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 6175 } 6176 6177 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request 6178 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { 6179 session_deps_.proxy_service.reset( 6180 ProxyService::CreateFixed("https://proxy:70")); 6181 6182 HttpRequestInfo request; 6183 request.method = "GET"; 6184 request.url = GURL("https://www.google.com/"); 6185 request.load_flags = 0; 6186 6187 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 6188 LOWEST)); 6189 scoped_ptr<SpdyFrame> goaway( 6190 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 6191 MockWrite data_writes[] = { 6192 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS), 6193 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS), 6194 }; 6195 6196 static const char* const kExtraHeaders[] = { 6197 "location", 6198 "http://login.example.com/", 6199 }; 6200 scoped_ptr<SpdyFrame> resp( 6201 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders, 6202 arraysize(kExtraHeaders)/2, 1)); 6203 MockRead data_reads[] = { 6204 CreateMockRead(*resp.get(), 1, SYNCHRONOUS), 6205 MockRead(ASYNC, 0, 2), // EOF 6206 }; 6207 6208 DelayedSocketData data( 6209 1, // wait for one write to finish before reading. 6210 data_reads, arraysize(data_reads), 6211 data_writes, arraysize(data_writes)); 6212 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6213 proxy_ssl.SetNextProto(GetParam()); 6214 6215 session_deps_.socket_factory->AddSocketDataProvider(&data); 6216 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6217 6218 TestCompletionCallback callback; 6219 6220 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6221 scoped_ptr<HttpTransaction> trans( 6222 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6223 6224 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6225 EXPECT_EQ(ERR_IO_PENDING, rv); 6226 6227 rv = callback.WaitForResult(); 6228 EXPECT_EQ(OK, rv); 6229 const HttpResponseInfo* response = trans->GetResponseInfo(); 6230 6231 ASSERT_TRUE(response != NULL); 6232 6233 EXPECT_EQ(302, response->headers->response_code()); 6234 std::string url; 6235 EXPECT_TRUE(response->headers->IsRedirect(&url)); 6236 EXPECT_EQ("http://login.example.com/", url); 6237 } 6238 6239 // Test that an HTTPS proxy's response to a CONNECT request is filtered. 6240 TEST_P(HttpNetworkTransactionTest, 6241 ErrorResponseToHttpsConnectViaHttpsProxy) { 6242 session_deps_.proxy_service.reset( 6243 ProxyService::CreateFixed("https://proxy:70")); 6244 6245 HttpRequestInfo request; 6246 request.method = "GET"; 6247 request.url = GURL("https://www.google.com/"); 6248 request.load_flags = 0; 6249 6250 MockWrite data_writes[] = { 6251 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6252 "Host: www.google.com\r\n" 6253 "Proxy-Connection: keep-alive\r\n\r\n"), 6254 }; 6255 6256 MockRead data_reads[] = { 6257 MockRead("HTTP/1.1 404 Not Found\r\n"), 6258 MockRead("Content-Length: 23\r\n\r\n"), 6259 MockRead("The host does not exist"), 6260 MockRead(SYNCHRONOUS, OK), 6261 }; 6262 6263 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6264 data_writes, arraysize(data_writes)); 6265 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6266 6267 session_deps_.socket_factory->AddSocketDataProvider(&data); 6268 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6269 6270 TestCompletionCallback callback; 6271 6272 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6273 scoped_ptr<HttpTransaction> trans( 6274 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6275 6276 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6277 EXPECT_EQ(ERR_IO_PENDING, rv); 6278 6279 rv = callback.WaitForResult(); 6280 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 6281 6282 // TODO(ttuttle): Anything else to check here? 6283 } 6284 6285 // Test that a SPDY proxy's response to a CONNECT request is filtered. 6286 TEST_P(HttpNetworkTransactionTest, 6287 ErrorResponseToHttpsConnectViaSpdyProxy) { 6288 session_deps_.proxy_service.reset( 6289 ProxyService::CreateFixed("https://proxy:70")); 6290 6291 HttpRequestInfo request; 6292 request.method = "GET"; 6293 request.url = GURL("https://www.google.com/"); 6294 request.load_flags = 0; 6295 6296 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 6297 LOWEST)); 6298 scoped_ptr<SpdyFrame> rst( 6299 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 6300 MockWrite data_writes[] = { 6301 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS), 6302 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS), 6303 }; 6304 6305 static const char* const kExtraHeaders[] = { 6306 "location", 6307 "http://login.example.com/", 6308 }; 6309 scoped_ptr<SpdyFrame> resp( 6310 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders, 6311 arraysize(kExtraHeaders)/2, 1)); 6312 scoped_ptr<SpdyFrame> body( 6313 spdy_util_.ConstructSpdyBodyFrame( 6314 1, "The host does not exist", 23, true)); 6315 MockRead data_reads[] = { 6316 CreateMockRead(*resp.get(), 1, SYNCHRONOUS), 6317 CreateMockRead(*body.get(), 2, SYNCHRONOUS), 6318 MockRead(ASYNC, 0, 4), // EOF 6319 }; 6320 6321 DelayedSocketData data( 6322 1, // wait for one write to finish before reading. 6323 data_reads, arraysize(data_reads), 6324 data_writes, arraysize(data_writes)); 6325 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy 6326 proxy_ssl.SetNextProto(GetParam()); 6327 6328 session_deps_.socket_factory->AddSocketDataProvider(&data); 6329 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); 6330 6331 TestCompletionCallback callback; 6332 6333 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6334 scoped_ptr<HttpTransaction> trans( 6335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6336 6337 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6338 EXPECT_EQ(ERR_IO_PENDING, rv); 6339 6340 rv = callback.WaitForResult(); 6341 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 6342 6343 // TODO(ttuttle): Anything else to check here? 6344 } 6345 6346 // Test the request-challenge-retry sequence for basic auth, through 6347 // a SPDY proxy over a single SPDY session. 6348 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) { 6349 HttpRequestInfo request; 6350 request.method = "GET"; 6351 request.url = GURL("https://www.google.com/"); 6352 // when the no authentication data flag is set. 6353 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 6354 6355 // Configure against https proxy server "myproxy:70". 6356 session_deps_.proxy_service.reset( 6357 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); 6358 CapturingBoundNetLog log; 6359 session_deps_.net_log = log.bound().net_log(); 6360 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6361 6362 // Since we have proxy, should try to establish tunnel. 6363 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 6364 LOWEST)); 6365 scoped_ptr<SpdyFrame> rst( 6366 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 6367 6368 // After calling trans->RestartWithAuth(), this is the request we should 6369 // be issuing -- the final header line contains the credentials. 6370 const char* const kAuthCredentials[] = { 6371 "proxy-authorization", "Basic Zm9vOmJhcg==", 6372 }; 6373 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect( 6374 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST)); 6375 // fetch https://www.google.com/ via HTTP 6376 const char get[] = "GET / HTTP/1.1\r\n" 6377 "Host: www.google.com\r\n" 6378 "Connection: keep-alive\r\n\r\n"; 6379 scoped_ptr<SpdyFrame> wrapped_get( 6380 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false)); 6381 6382 MockWrite spdy_writes[] = { 6383 CreateMockWrite(*req, 1, ASYNC), 6384 CreateMockWrite(*rst, 4, ASYNC), 6385 CreateMockWrite(*connect2, 5), 6386 CreateMockWrite(*wrapped_get, 8), 6387 }; 6388 6389 // The proxy responds to the connect with a 407, using a persistent 6390 // connection. 6391 const char* const kAuthChallenge[] = { 6392 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required", 6393 spdy_util_.GetVersionKey(), "HTTP/1.1", 6394 "proxy-authenticate", "Basic realm=\"MyRealm1\"", 6395 }; 6396 6397 scoped_ptr<SpdyFrame> conn_auth_resp( 6398 spdy_util_.ConstructSpdyControlFrame(NULL, 6399 0, 6400 false, 6401 1, 6402 LOWEST, 6403 SYN_REPLY, 6404 CONTROL_FLAG_NONE, 6405 kAuthChallenge, 6406 arraysize(kAuthChallenge), 6407 0)); 6408 6409 scoped_ptr<SpdyFrame> conn_resp( 6410 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 6411 const char resp[] = "HTTP/1.1 200 OK\r\n" 6412 "Content-Length: 5\r\n\r\n"; 6413 6414 scoped_ptr<SpdyFrame> wrapped_get_resp( 6415 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false)); 6416 scoped_ptr<SpdyFrame> wrapped_body( 6417 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false)); 6418 MockRead spdy_reads[] = { 6419 CreateMockRead(*conn_auth_resp, 2, ASYNC), 6420 CreateMockRead(*conn_resp, 6, ASYNC), 6421 CreateMockRead(*wrapped_get_resp, 9, ASYNC), 6422 CreateMockRead(*wrapped_body, 10, ASYNC), 6423 MockRead(ASYNC, OK, 11), // EOF. May or may not be read. 6424 }; 6425 6426 OrderedSocketData spdy_data( 6427 spdy_reads, arraysize(spdy_reads), 6428 spdy_writes, arraysize(spdy_writes)); 6429 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6430 // Negotiate SPDY to the proxy 6431 SSLSocketDataProvider proxy(ASYNC, OK); 6432 proxy.SetNextProto(GetParam()); 6433 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6434 // Vanilla SSL to the server 6435 SSLSocketDataProvider server(ASYNC, OK); 6436 session_deps_.socket_factory->AddSSLSocketDataProvider(&server); 6437 6438 TestCompletionCallback callback1; 6439 6440 scoped_ptr<HttpTransaction> trans( 6441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6442 6443 int rv = trans->Start(&request, callback1.callback(), log.bound()); 6444 EXPECT_EQ(ERR_IO_PENDING, rv); 6445 6446 rv = callback1.WaitForResult(); 6447 EXPECT_EQ(OK, rv); 6448 net::CapturingNetLog::CapturedEntryList entries; 6449 log.GetEntries(&entries); 6450 size_t pos = ExpectLogContainsSomewhere( 6451 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 6452 NetLog::PHASE_NONE); 6453 ExpectLogContainsSomewhere( 6454 entries, pos, 6455 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 6456 NetLog::PHASE_NONE); 6457 6458 const HttpResponseInfo* response = trans->GetResponseInfo(); 6459 ASSERT_TRUE(response != NULL); 6460 ASSERT_FALSE(response->headers.get() == NULL); 6461 EXPECT_EQ(407, response->headers->response_code()); 6462 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6463 EXPECT_TRUE(response->auth_challenge.get() != NULL); 6464 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); 6465 6466 TestCompletionCallback callback2; 6467 6468 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), 6469 callback2.callback()); 6470 EXPECT_EQ(ERR_IO_PENDING, rv); 6471 6472 rv = callback2.WaitForResult(); 6473 EXPECT_EQ(OK, rv); 6474 6475 response = trans->GetResponseInfo(); 6476 ASSERT_TRUE(response != NULL); 6477 6478 EXPECT_TRUE(response->headers->IsKeepAlive()); 6479 EXPECT_EQ(200, response->headers->response_code()); 6480 EXPECT_EQ(5, response->headers->GetContentLength()); 6481 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6482 6483 // The password prompt info should not be set. 6484 EXPECT_TRUE(response->auth_challenge.get() == NULL); 6485 6486 LoadTimingInfo load_timing_info; 6487 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6488 TestLoadTimingNotReusedWithPac(load_timing_info, 6489 CONNECT_TIMING_HAS_SSL_TIMES); 6490 6491 trans.reset(); 6492 session->CloseAllConnections(); 6493 } 6494 6495 // Test that an explicitly trusted SPDY proxy can push a resource from an 6496 // origin that is different from that of its associated resource. 6497 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) { 6498 HttpRequestInfo request; 6499 HttpRequestInfo push_request; 6500 6501 request.method = "GET"; 6502 request.url = GURL("http://www.google.com/"); 6503 push_request.method = "GET"; 6504 push_request.url = GURL("http://www.another-origin.com/foo.dat"); 6505 6506 // Configure against https proxy server "myproxy:70". 6507 session_deps_.proxy_service.reset( 6508 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); 6509 CapturingBoundNetLog log; 6510 session_deps_.net_log = log.bound().net_log(); 6511 6512 // Enable cross-origin push. 6513 session_deps_.trusted_spdy_proxy = "myproxy:70"; 6514 6515 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6516 6517 scoped_ptr<SpdyFrame> stream1_syn( 6518 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 6519 6520 MockWrite spdy_writes[] = { 6521 CreateMockWrite(*stream1_syn, 1, ASYNC), 6522 }; 6523 6524 scoped_ptr<SpdyFrame> 6525 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 6526 6527 scoped_ptr<SpdyFrame> 6528 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6529 6530 scoped_ptr<SpdyFrame> 6531 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 6532 0, 6533 2, 6534 1, 6535 "http://www.another-origin.com/foo.dat")); 6536 const char kPushedData[] = "pushed"; 6537 scoped_ptr<SpdyFrame> stream2_body( 6538 spdy_util_.ConstructSpdyBodyFrame( 6539 2, kPushedData, strlen(kPushedData), true)); 6540 6541 MockRead spdy_reads[] = { 6542 CreateMockRead(*stream1_reply, 2, ASYNC), 6543 CreateMockRead(*stream2_syn, 3, ASYNC), 6544 CreateMockRead(*stream1_body, 4, ASYNC), 6545 CreateMockRead(*stream2_body, 5, ASYNC), 6546 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 6547 }; 6548 6549 OrderedSocketData spdy_data( 6550 spdy_reads, arraysize(spdy_reads), 6551 spdy_writes, arraysize(spdy_writes)); 6552 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6553 // Negotiate SPDY to the proxy 6554 SSLSocketDataProvider proxy(ASYNC, OK); 6555 proxy.SetNextProto(GetParam()); 6556 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6557 6558 scoped_ptr<HttpTransaction> trans( 6559 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6560 TestCompletionCallback callback; 6561 int rv = trans->Start(&request, callback.callback(), log.bound()); 6562 EXPECT_EQ(ERR_IO_PENDING, rv); 6563 6564 rv = callback.WaitForResult(); 6565 EXPECT_EQ(OK, rv); 6566 const HttpResponseInfo* response = trans->GetResponseInfo(); 6567 6568 scoped_ptr<HttpTransaction> push_trans( 6569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6570 rv = push_trans->Start(&push_request, callback.callback(), log.bound()); 6571 EXPECT_EQ(ERR_IO_PENDING, rv); 6572 6573 rv = callback.WaitForResult(); 6574 EXPECT_EQ(OK, rv); 6575 const HttpResponseInfo* push_response = push_trans->GetResponseInfo(); 6576 6577 ASSERT_TRUE(response != NULL); 6578 EXPECT_TRUE(response->headers->IsKeepAlive()); 6579 6580 EXPECT_EQ(200, response->headers->response_code()); 6581 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6582 6583 std::string response_data; 6584 rv = ReadTransaction(trans.get(), &response_data); 6585 EXPECT_EQ(OK, rv); 6586 EXPECT_EQ("hello!", response_data); 6587 6588 LoadTimingInfo load_timing_info; 6589 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 6590 TestLoadTimingNotReusedWithPac(load_timing_info, 6591 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 6592 6593 // Verify the pushed stream. 6594 EXPECT_TRUE(push_response->headers.get() != NULL); 6595 EXPECT_EQ(200, push_response->headers->response_code()); 6596 6597 rv = ReadTransaction(push_trans.get(), &response_data); 6598 EXPECT_EQ(OK, rv); 6599 EXPECT_EQ("pushed", response_data); 6600 6601 LoadTimingInfo push_load_timing_info; 6602 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info)); 6603 TestLoadTimingReusedWithPac(push_load_timing_info); 6604 // The transactions should share a socket ID, despite being for different 6605 // origins. 6606 EXPECT_EQ(load_timing_info.socket_log_id, 6607 push_load_timing_info.socket_log_id); 6608 6609 trans.reset(); 6610 push_trans.reset(); 6611 session->CloseAllConnections(); 6612 } 6613 6614 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content. 6615 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) { 6616 HttpRequestInfo request; 6617 6618 request.method = "GET"; 6619 request.url = GURL("http://www.google.com/"); 6620 6621 // Configure against https proxy server "myproxy:70". 6622 session_deps_.proxy_service.reset( 6623 ProxyService::CreateFixed("https://myproxy:70")); 6624 CapturingBoundNetLog log; 6625 session_deps_.net_log = log.bound().net_log(); 6626 6627 // Enable cross-origin push. 6628 session_deps_.trusted_spdy_proxy = "myproxy:70"; 6629 6630 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6631 6632 scoped_ptr<SpdyFrame> stream1_syn( 6633 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 6634 6635 scoped_ptr<SpdyFrame> push_rst( 6636 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 6637 6638 MockWrite spdy_writes[] = { 6639 CreateMockWrite(*stream1_syn, 1, ASYNC), 6640 CreateMockWrite(*push_rst, 4), 6641 }; 6642 6643 scoped_ptr<SpdyFrame> 6644 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 6645 6646 scoped_ptr<SpdyFrame> 6647 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6648 6649 scoped_ptr<SpdyFrame> 6650 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 6651 0, 6652 2, 6653 1, 6654 "https://www.another-origin.com/foo.dat")); 6655 6656 MockRead spdy_reads[] = { 6657 CreateMockRead(*stream1_reply, 2, ASYNC), 6658 CreateMockRead(*stream2_syn, 3, ASYNC), 6659 CreateMockRead(*stream1_body, 5, ASYNC), 6660 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 6661 }; 6662 6663 OrderedSocketData spdy_data( 6664 spdy_reads, arraysize(spdy_reads), 6665 spdy_writes, arraysize(spdy_writes)); 6666 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 6667 // Negotiate SPDY to the proxy 6668 SSLSocketDataProvider proxy(ASYNC, OK); 6669 proxy.SetNextProto(GetParam()); 6670 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); 6671 6672 scoped_ptr<HttpTransaction> trans( 6673 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6674 TestCompletionCallback callback; 6675 int rv = trans->Start(&request, callback.callback(), log.bound()); 6676 EXPECT_EQ(ERR_IO_PENDING, rv); 6677 6678 rv = callback.WaitForResult(); 6679 EXPECT_EQ(OK, rv); 6680 const HttpResponseInfo* response = trans->GetResponseInfo(); 6681 6682 ASSERT_TRUE(response != NULL); 6683 EXPECT_TRUE(response->headers->IsKeepAlive()); 6684 6685 EXPECT_EQ(200, response->headers->response_code()); 6686 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 6687 6688 std::string response_data; 6689 rv = ReadTransaction(trans.get(), &response_data); 6690 EXPECT_EQ(OK, rv); 6691 EXPECT_EQ("hello!", response_data); 6692 6693 trans.reset(); 6694 session->CloseAllConnections(); 6695 } 6696 6697 // Test HTTPS connections to a site with a bad certificate, going through an 6698 // HTTPS proxy 6699 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) { 6700 session_deps_.proxy_service.reset(ProxyService::CreateFixed( 6701 "https://proxy:70")); 6702 6703 HttpRequestInfo request; 6704 request.method = "GET"; 6705 request.url = GURL("https://www.google.com/"); 6706 request.load_flags = 0; 6707 6708 // Attempt to fetch the URL from a server with a bad cert 6709 MockWrite bad_cert_writes[] = { 6710 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6711 "Host: www.google.com\r\n" 6712 "Proxy-Connection: keep-alive\r\n\r\n"), 6713 }; 6714 6715 MockRead bad_cert_reads[] = { 6716 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6717 MockRead(SYNCHRONOUS, OK) 6718 }; 6719 6720 // Attempt to fetch the URL with a good cert 6721 MockWrite good_data_writes[] = { 6722 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6723 "Host: www.google.com\r\n" 6724 "Proxy-Connection: keep-alive\r\n\r\n"), 6725 MockWrite("GET / HTTP/1.1\r\n" 6726 "Host: www.google.com\r\n" 6727 "Connection: keep-alive\r\n\r\n"), 6728 }; 6729 6730 MockRead good_cert_reads[] = { 6731 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 6732 MockRead("HTTP/1.0 200 OK\r\n"), 6733 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6734 MockRead("Content-Length: 100\r\n\r\n"), 6735 MockRead(SYNCHRONOUS, OK), 6736 }; 6737 6738 StaticSocketDataProvider ssl_bad_certificate( 6739 bad_cert_reads, arraysize(bad_cert_reads), 6740 bad_cert_writes, arraysize(bad_cert_writes)); 6741 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads), 6742 good_data_writes, arraysize(good_data_writes)); 6743 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID); 6744 SSLSocketDataProvider ssl(ASYNC, OK); 6745 6746 // SSL to the proxy, then CONNECT request, then SSL with bad certificate 6747 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6748 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate); 6749 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad); 6750 6751 // SSL to the proxy, then CONNECT request, then valid SSL certificate 6752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6753 session_deps_.socket_factory->AddSocketDataProvider(&data); 6754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 6755 6756 TestCompletionCallback callback; 6757 6758 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6759 scoped_ptr<HttpTransaction> trans( 6760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6761 6762 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6763 EXPECT_EQ(ERR_IO_PENDING, rv); 6764 6765 rv = callback.WaitForResult(); 6766 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 6767 6768 rv = trans->RestartIgnoringLastError(callback.callback()); 6769 EXPECT_EQ(ERR_IO_PENDING, rv); 6770 6771 rv = callback.WaitForResult(); 6772 EXPECT_EQ(OK, rv); 6773 6774 const HttpResponseInfo* response = trans->GetResponseInfo(); 6775 6776 ASSERT_TRUE(response != NULL); 6777 EXPECT_EQ(100, response->headers->GetContentLength()); 6778 } 6779 6780 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) { 6781 HttpRequestInfo request; 6782 request.method = "GET"; 6783 request.url = GURL("http://www.google.com/"); 6784 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 6785 "Chromium Ultra Awesome X Edition"); 6786 6787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6788 scoped_ptr<HttpTransaction> trans( 6789 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6790 6791 MockWrite data_writes[] = { 6792 MockWrite("GET / HTTP/1.1\r\n" 6793 "Host: www.google.com\r\n" 6794 "Connection: keep-alive\r\n" 6795 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 6796 }; 6797 6798 // Lastly, the server responds with the actual content. 6799 MockRead data_reads[] = { 6800 MockRead("HTTP/1.0 200 OK\r\n"), 6801 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6802 MockRead("Content-Length: 100\r\n\r\n"), 6803 MockRead(SYNCHRONOUS, OK), 6804 }; 6805 6806 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6807 data_writes, arraysize(data_writes)); 6808 session_deps_.socket_factory->AddSocketDataProvider(&data); 6809 6810 TestCompletionCallback callback; 6811 6812 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6813 EXPECT_EQ(ERR_IO_PENDING, rv); 6814 6815 rv = callback.WaitForResult(); 6816 EXPECT_EQ(OK, rv); 6817 } 6818 6819 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) { 6820 HttpRequestInfo request; 6821 request.method = "GET"; 6822 request.url = GURL("https://www.google.com/"); 6823 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 6824 "Chromium Ultra Awesome X Edition"); 6825 6826 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 6827 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6828 scoped_ptr<HttpTransaction> trans( 6829 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6830 6831 MockWrite data_writes[] = { 6832 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6833 "Host: www.google.com\r\n" 6834 "Proxy-Connection: keep-alive\r\n" 6835 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 6836 }; 6837 MockRead data_reads[] = { 6838 // Return an error, so the transaction stops here (this test isn't 6839 // interested in the rest). 6840 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 6841 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 6842 MockRead("Proxy-Connection: close\r\n\r\n"), 6843 }; 6844 6845 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6846 data_writes, arraysize(data_writes)); 6847 session_deps_.socket_factory->AddSocketDataProvider(&data); 6848 6849 TestCompletionCallback callback; 6850 6851 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6852 EXPECT_EQ(ERR_IO_PENDING, rv); 6853 6854 rv = callback.WaitForResult(); 6855 EXPECT_EQ(OK, rv); 6856 } 6857 6858 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) { 6859 HttpRequestInfo request; 6860 request.method = "GET"; 6861 request.url = GURL("http://www.google.com/"); 6862 request.load_flags = 0; 6863 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer, 6864 "http://the.previous.site.com/"); 6865 6866 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6867 scoped_ptr<HttpTransaction> trans( 6868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6869 6870 MockWrite data_writes[] = { 6871 MockWrite("GET / HTTP/1.1\r\n" 6872 "Host: www.google.com\r\n" 6873 "Connection: keep-alive\r\n" 6874 "Referer: http://the.previous.site.com/\r\n\r\n"), 6875 }; 6876 6877 // Lastly, the server responds with the actual content. 6878 MockRead data_reads[] = { 6879 MockRead("HTTP/1.0 200 OK\r\n"), 6880 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6881 MockRead("Content-Length: 100\r\n\r\n"), 6882 MockRead(SYNCHRONOUS, OK), 6883 }; 6884 6885 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6886 data_writes, arraysize(data_writes)); 6887 session_deps_.socket_factory->AddSocketDataProvider(&data); 6888 6889 TestCompletionCallback callback; 6890 6891 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6892 EXPECT_EQ(ERR_IO_PENDING, rv); 6893 6894 rv = callback.WaitForResult(); 6895 EXPECT_EQ(OK, rv); 6896 } 6897 6898 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) { 6899 HttpRequestInfo request; 6900 request.method = "POST"; 6901 request.url = GURL("http://www.google.com/"); 6902 6903 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6904 scoped_ptr<HttpTransaction> trans( 6905 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6906 6907 MockWrite data_writes[] = { 6908 MockWrite("POST / HTTP/1.1\r\n" 6909 "Host: www.google.com\r\n" 6910 "Connection: keep-alive\r\n" 6911 "Content-Length: 0\r\n\r\n"), 6912 }; 6913 6914 // Lastly, the server responds with the actual content. 6915 MockRead data_reads[] = { 6916 MockRead("HTTP/1.0 200 OK\r\n"), 6917 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6918 MockRead("Content-Length: 100\r\n\r\n"), 6919 MockRead(SYNCHRONOUS, OK), 6920 }; 6921 6922 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6923 data_writes, arraysize(data_writes)); 6924 session_deps_.socket_factory->AddSocketDataProvider(&data); 6925 6926 TestCompletionCallback callback; 6927 6928 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6929 EXPECT_EQ(ERR_IO_PENDING, rv); 6930 6931 rv = callback.WaitForResult(); 6932 EXPECT_EQ(OK, rv); 6933 } 6934 6935 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) { 6936 HttpRequestInfo request; 6937 request.method = "PUT"; 6938 request.url = GURL("http://www.google.com/"); 6939 6940 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6941 scoped_ptr<HttpTransaction> trans( 6942 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6943 6944 MockWrite data_writes[] = { 6945 MockWrite("PUT / HTTP/1.1\r\n" 6946 "Host: www.google.com\r\n" 6947 "Connection: keep-alive\r\n" 6948 "Content-Length: 0\r\n\r\n"), 6949 }; 6950 6951 // Lastly, the server responds with the actual content. 6952 MockRead data_reads[] = { 6953 MockRead("HTTP/1.0 200 OK\r\n"), 6954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6955 MockRead("Content-Length: 100\r\n\r\n"), 6956 MockRead(SYNCHRONOUS, OK), 6957 }; 6958 6959 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6960 data_writes, arraysize(data_writes)); 6961 session_deps_.socket_factory->AddSocketDataProvider(&data); 6962 6963 TestCompletionCallback callback; 6964 6965 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6966 EXPECT_EQ(ERR_IO_PENDING, rv); 6967 6968 rv = callback.WaitForResult(); 6969 EXPECT_EQ(OK, rv); 6970 } 6971 6972 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) { 6973 HttpRequestInfo request; 6974 request.method = "HEAD"; 6975 request.url = GURL("http://www.google.com/"); 6976 6977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 6978 scoped_ptr<HttpTransaction> trans( 6979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 6980 6981 MockWrite data_writes[] = { 6982 MockWrite("HEAD / HTTP/1.1\r\n" 6983 "Host: www.google.com\r\n" 6984 "Connection: keep-alive\r\n" 6985 "Content-Length: 0\r\n\r\n"), 6986 }; 6987 6988 // Lastly, the server responds with the actual content. 6989 MockRead data_reads[] = { 6990 MockRead("HTTP/1.0 200 OK\r\n"), 6991 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 6992 MockRead("Content-Length: 100\r\n\r\n"), 6993 MockRead(SYNCHRONOUS, OK), 6994 }; 6995 6996 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 6997 data_writes, arraysize(data_writes)); 6998 session_deps_.socket_factory->AddSocketDataProvider(&data); 6999 7000 TestCompletionCallback callback; 7001 7002 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7003 EXPECT_EQ(ERR_IO_PENDING, rv); 7004 7005 rv = callback.WaitForResult(); 7006 EXPECT_EQ(OK, rv); 7007 } 7008 7009 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) { 7010 HttpRequestInfo request; 7011 request.method = "GET"; 7012 request.url = GURL("http://www.google.com/"); 7013 request.load_flags = LOAD_BYPASS_CACHE; 7014 7015 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7016 scoped_ptr<HttpTransaction> trans( 7017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7018 7019 MockWrite data_writes[] = { 7020 MockWrite("GET / HTTP/1.1\r\n" 7021 "Host: www.google.com\r\n" 7022 "Connection: keep-alive\r\n" 7023 "Pragma: no-cache\r\n" 7024 "Cache-Control: no-cache\r\n\r\n"), 7025 }; 7026 7027 // Lastly, the server responds with the actual content. 7028 MockRead data_reads[] = { 7029 MockRead("HTTP/1.0 200 OK\r\n"), 7030 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7031 MockRead("Content-Length: 100\r\n\r\n"), 7032 MockRead(SYNCHRONOUS, OK), 7033 }; 7034 7035 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7036 data_writes, arraysize(data_writes)); 7037 session_deps_.socket_factory->AddSocketDataProvider(&data); 7038 7039 TestCompletionCallback callback; 7040 7041 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7042 EXPECT_EQ(ERR_IO_PENDING, rv); 7043 7044 rv = callback.WaitForResult(); 7045 EXPECT_EQ(OK, rv); 7046 } 7047 7048 TEST_P(HttpNetworkTransactionTest, 7049 BuildRequest_CacheControlValidateCache) { 7050 HttpRequestInfo request; 7051 request.method = "GET"; 7052 request.url = GURL("http://www.google.com/"); 7053 request.load_flags = LOAD_VALIDATE_CACHE; 7054 7055 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7056 scoped_ptr<HttpTransaction> trans( 7057 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7058 7059 MockWrite data_writes[] = { 7060 MockWrite("GET / HTTP/1.1\r\n" 7061 "Host: www.google.com\r\n" 7062 "Connection: keep-alive\r\n" 7063 "Cache-Control: max-age=0\r\n\r\n"), 7064 }; 7065 7066 // Lastly, the server responds with the actual content. 7067 MockRead data_reads[] = { 7068 MockRead("HTTP/1.0 200 OK\r\n"), 7069 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7070 MockRead("Content-Length: 100\r\n\r\n"), 7071 MockRead(SYNCHRONOUS, OK), 7072 }; 7073 7074 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7075 data_writes, arraysize(data_writes)); 7076 session_deps_.socket_factory->AddSocketDataProvider(&data); 7077 7078 TestCompletionCallback callback; 7079 7080 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7081 EXPECT_EQ(ERR_IO_PENDING, rv); 7082 7083 rv = callback.WaitForResult(); 7084 EXPECT_EQ(OK, rv); 7085 } 7086 7087 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) { 7088 HttpRequestInfo request; 7089 request.method = "GET"; 7090 request.url = GURL("http://www.google.com/"); 7091 request.extra_headers.SetHeader("FooHeader", "Bar"); 7092 7093 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7094 scoped_ptr<HttpTransaction> trans( 7095 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7096 7097 MockWrite data_writes[] = { 7098 MockWrite("GET / HTTP/1.1\r\n" 7099 "Host: www.google.com\r\n" 7100 "Connection: keep-alive\r\n" 7101 "FooHeader: Bar\r\n\r\n"), 7102 }; 7103 7104 // Lastly, the server responds with the actual content. 7105 MockRead data_reads[] = { 7106 MockRead("HTTP/1.0 200 OK\r\n"), 7107 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7108 MockRead("Content-Length: 100\r\n\r\n"), 7109 MockRead(SYNCHRONOUS, OK), 7110 }; 7111 7112 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7113 data_writes, arraysize(data_writes)); 7114 session_deps_.socket_factory->AddSocketDataProvider(&data); 7115 7116 TestCompletionCallback callback; 7117 7118 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7119 EXPECT_EQ(ERR_IO_PENDING, rv); 7120 7121 rv = callback.WaitForResult(); 7122 EXPECT_EQ(OK, rv); 7123 } 7124 7125 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) { 7126 HttpRequestInfo request; 7127 request.method = "GET"; 7128 request.url = GURL("http://www.google.com/"); 7129 request.extra_headers.SetHeader("referer", "www.foo.com"); 7130 request.extra_headers.SetHeader("hEllo", "Kitty"); 7131 request.extra_headers.SetHeader("FoO", "bar"); 7132 7133 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7134 scoped_ptr<HttpTransaction> trans( 7135 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7136 7137 MockWrite data_writes[] = { 7138 MockWrite("GET / HTTP/1.1\r\n" 7139 "Host: www.google.com\r\n" 7140 "Connection: keep-alive\r\n" 7141 "referer: www.foo.com\r\n" 7142 "hEllo: Kitty\r\n" 7143 "FoO: bar\r\n\r\n"), 7144 }; 7145 7146 // Lastly, the server responds with the actual content. 7147 MockRead data_reads[] = { 7148 MockRead("HTTP/1.0 200 OK\r\n"), 7149 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7150 MockRead("Content-Length: 100\r\n\r\n"), 7151 MockRead(SYNCHRONOUS, OK), 7152 }; 7153 7154 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7155 data_writes, arraysize(data_writes)); 7156 session_deps_.socket_factory->AddSocketDataProvider(&data); 7157 7158 TestCompletionCallback callback; 7159 7160 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7161 EXPECT_EQ(ERR_IO_PENDING, rv); 7162 7163 rv = callback.WaitForResult(); 7164 EXPECT_EQ(OK, rv); 7165 } 7166 7167 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) { 7168 HttpRequestInfo request; 7169 request.method = "GET"; 7170 request.url = GURL("http://www.google.com/"); 7171 request.load_flags = 0; 7172 7173 session_deps_.proxy_service.reset( 7174 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080")); 7175 CapturingNetLog net_log; 7176 session_deps_.net_log = &net_log; 7177 7178 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7179 scoped_ptr<HttpTransaction> trans( 7180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7181 7182 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; 7183 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 7184 7185 MockWrite data_writes[] = { 7186 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)), 7187 MockWrite("GET / HTTP/1.1\r\n" 7188 "Host: www.google.com\r\n" 7189 "Connection: keep-alive\r\n\r\n") 7190 }; 7191 7192 MockRead data_reads[] = { 7193 MockRead(ASYNC, read_buffer, arraysize(read_buffer)), 7194 MockRead("HTTP/1.0 200 OK\r\n"), 7195 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7196 MockRead("Payload"), 7197 MockRead(SYNCHRONOUS, OK) 7198 }; 7199 7200 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7201 data_writes, arraysize(data_writes)); 7202 session_deps_.socket_factory->AddSocketDataProvider(&data); 7203 7204 TestCompletionCallback callback; 7205 7206 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7207 EXPECT_EQ(ERR_IO_PENDING, rv); 7208 7209 rv = callback.WaitForResult(); 7210 EXPECT_EQ(OK, rv); 7211 7212 const HttpResponseInfo* response = trans->GetResponseInfo(); 7213 ASSERT_TRUE(response != NULL); 7214 7215 LoadTimingInfo load_timing_info; 7216 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7217 TestLoadTimingNotReusedWithPac(load_timing_info, 7218 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 7219 7220 std::string response_text; 7221 rv = ReadTransaction(trans.get(), &response_text); 7222 EXPECT_EQ(OK, rv); 7223 EXPECT_EQ("Payload", response_text); 7224 } 7225 7226 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) { 7227 HttpRequestInfo request; 7228 request.method = "GET"; 7229 request.url = GURL("https://www.google.com/"); 7230 request.load_flags = 0; 7231 7232 session_deps_.proxy_service.reset( 7233 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080")); 7234 CapturingNetLog net_log; 7235 session_deps_.net_log = &net_log; 7236 7237 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7238 scoped_ptr<HttpTransaction> trans( 7239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7240 7241 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 }; 7242 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 7243 7244 MockWrite data_writes[] = { 7245 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer), 7246 arraysize(write_buffer)), 7247 MockWrite("GET / HTTP/1.1\r\n" 7248 "Host: www.google.com\r\n" 7249 "Connection: keep-alive\r\n\r\n") 7250 }; 7251 7252 MockRead data_reads[] = { 7253 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer), 7254 arraysize(read_buffer)), 7255 MockRead("HTTP/1.0 200 OK\r\n"), 7256 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7257 MockRead("Payload"), 7258 MockRead(SYNCHRONOUS, OK) 7259 }; 7260 7261 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7262 data_writes, arraysize(data_writes)); 7263 session_deps_.socket_factory->AddSocketDataProvider(&data); 7264 7265 SSLSocketDataProvider ssl(ASYNC, OK); 7266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 7267 7268 TestCompletionCallback callback; 7269 7270 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7271 EXPECT_EQ(ERR_IO_PENDING, rv); 7272 7273 rv = callback.WaitForResult(); 7274 EXPECT_EQ(OK, rv); 7275 7276 LoadTimingInfo load_timing_info; 7277 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7278 TestLoadTimingNotReusedWithPac(load_timing_info, 7279 CONNECT_TIMING_HAS_SSL_TIMES); 7280 7281 const HttpResponseInfo* response = trans->GetResponseInfo(); 7282 ASSERT_TRUE(response != NULL); 7283 7284 std::string response_text; 7285 rv = ReadTransaction(trans.get(), &response_text); 7286 EXPECT_EQ(OK, rv); 7287 EXPECT_EQ("Payload", response_text); 7288 } 7289 7290 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) { 7291 HttpRequestInfo request; 7292 request.method = "GET"; 7293 request.url = GURL("http://www.google.com/"); 7294 request.load_flags = 0; 7295 7296 session_deps_.proxy_service.reset( 7297 ProxyService::CreateFixed("socks4://myproxy:1080")); 7298 CapturingNetLog net_log; 7299 session_deps_.net_log = &net_log; 7300 7301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7302 scoped_ptr<HttpTransaction> trans( 7303 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7304 7305 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; 7306 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 7307 7308 MockWrite data_writes[] = { 7309 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)), 7310 MockWrite("GET / HTTP/1.1\r\n" 7311 "Host: www.google.com\r\n" 7312 "Connection: keep-alive\r\n\r\n") 7313 }; 7314 7315 MockRead data_reads[] = { 7316 MockRead(ASYNC, read_buffer, arraysize(read_buffer)), 7317 MockRead("HTTP/1.0 200 OK\r\n"), 7318 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7319 MockRead("Payload"), 7320 MockRead(SYNCHRONOUS, OK) 7321 }; 7322 7323 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7324 data_writes, arraysize(data_writes)); 7325 session_deps_.socket_factory->AddSocketDataProvider(&data); 7326 7327 TestCompletionCallback callback; 7328 7329 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7330 EXPECT_EQ(ERR_IO_PENDING, rv); 7331 7332 rv = callback.WaitForResult(); 7333 EXPECT_EQ(OK, rv); 7334 7335 const HttpResponseInfo* response = trans->GetResponseInfo(); 7336 ASSERT_TRUE(response != NULL); 7337 7338 LoadTimingInfo load_timing_info; 7339 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7340 TestLoadTimingNotReused(load_timing_info, 7341 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 7342 7343 std::string response_text; 7344 rv = ReadTransaction(trans.get(), &response_text); 7345 EXPECT_EQ(OK, rv); 7346 EXPECT_EQ("Payload", response_text); 7347 } 7348 7349 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) { 7350 HttpRequestInfo request; 7351 request.method = "GET"; 7352 request.url = GURL("http://www.google.com/"); 7353 request.load_flags = 0; 7354 7355 session_deps_.proxy_service.reset( 7356 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080")); 7357 CapturingNetLog net_log; 7358 session_deps_.net_log = &net_log; 7359 7360 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7361 scoped_ptr<HttpTransaction> trans( 7362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7363 7364 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 7365 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 7366 const char kSOCKS5OkRequest[] = { 7367 0x05, // Version 7368 0x01, // Command (CONNECT) 7369 0x00, // Reserved. 7370 0x03, // Address type (DOMAINNAME). 7371 0x0E, // Length of domain (14) 7372 // Domain string: 7373 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 7374 0x00, 0x50, // 16-bit port (80) 7375 }; 7376 const char kSOCKS5OkResponse[] = 7377 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 }; 7378 7379 MockWrite data_writes[] = { 7380 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 7381 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)), 7382 MockWrite("GET / HTTP/1.1\r\n" 7383 "Host: www.google.com\r\n" 7384 "Connection: keep-alive\r\n\r\n") 7385 }; 7386 7387 MockRead data_reads[] = { 7388 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 7389 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 7390 MockRead("HTTP/1.0 200 OK\r\n"), 7391 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7392 MockRead("Payload"), 7393 MockRead(SYNCHRONOUS, OK) 7394 }; 7395 7396 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7397 data_writes, arraysize(data_writes)); 7398 session_deps_.socket_factory->AddSocketDataProvider(&data); 7399 7400 TestCompletionCallback callback; 7401 7402 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7403 EXPECT_EQ(ERR_IO_PENDING, rv); 7404 7405 rv = callback.WaitForResult(); 7406 EXPECT_EQ(OK, rv); 7407 7408 const HttpResponseInfo* response = trans->GetResponseInfo(); 7409 ASSERT_TRUE(response != NULL); 7410 7411 LoadTimingInfo load_timing_info; 7412 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7413 TestLoadTimingNotReusedWithPac(load_timing_info, 7414 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 7415 7416 std::string response_text; 7417 rv = ReadTransaction(trans.get(), &response_text); 7418 EXPECT_EQ(OK, rv); 7419 EXPECT_EQ("Payload", response_text); 7420 } 7421 7422 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) { 7423 HttpRequestInfo request; 7424 request.method = "GET"; 7425 request.url = GURL("https://www.google.com/"); 7426 request.load_flags = 0; 7427 7428 session_deps_.proxy_service.reset( 7429 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080")); 7430 CapturingNetLog net_log; 7431 session_deps_.net_log = &net_log; 7432 7433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7434 scoped_ptr<HttpTransaction> trans( 7435 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7436 7437 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 7438 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 7439 const unsigned char kSOCKS5OkRequest[] = { 7440 0x05, // Version 7441 0x01, // Command (CONNECT) 7442 0x00, // Reserved. 7443 0x03, // Address type (DOMAINNAME). 7444 0x0E, // Length of domain (14) 7445 // Domain string: 7446 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 7447 0x01, 0xBB, // 16-bit port (443) 7448 }; 7449 7450 const char kSOCKS5OkResponse[] = 7451 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 }; 7452 7453 MockWrite data_writes[] = { 7454 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 7455 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest), 7456 arraysize(kSOCKS5OkRequest)), 7457 MockWrite("GET / HTTP/1.1\r\n" 7458 "Host: www.google.com\r\n" 7459 "Connection: keep-alive\r\n\r\n") 7460 }; 7461 7462 MockRead data_reads[] = { 7463 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 7464 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 7465 MockRead("HTTP/1.0 200 OK\r\n"), 7466 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 7467 MockRead("Payload"), 7468 MockRead(SYNCHRONOUS, OK) 7469 }; 7470 7471 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7472 data_writes, arraysize(data_writes)); 7473 session_deps_.socket_factory->AddSocketDataProvider(&data); 7474 7475 SSLSocketDataProvider ssl(ASYNC, OK); 7476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 7477 7478 TestCompletionCallback callback; 7479 7480 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7481 EXPECT_EQ(ERR_IO_PENDING, rv); 7482 7483 rv = callback.WaitForResult(); 7484 EXPECT_EQ(OK, rv); 7485 7486 const HttpResponseInfo* response = trans->GetResponseInfo(); 7487 ASSERT_TRUE(response != NULL); 7488 7489 LoadTimingInfo load_timing_info; 7490 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 7491 TestLoadTimingNotReusedWithPac(load_timing_info, 7492 CONNECT_TIMING_HAS_SSL_TIMES); 7493 7494 std::string response_text; 7495 rv = ReadTransaction(trans.get(), &response_text); 7496 EXPECT_EQ(OK, rv); 7497 EXPECT_EQ("Payload", response_text); 7498 } 7499 7500 namespace { 7501 7502 // Tests that for connection endpoints the group names are correctly set. 7503 7504 struct GroupNameTest { 7505 std::string proxy_server; 7506 std::string url; 7507 std::string expected_group_name; 7508 bool ssl; 7509 }; 7510 7511 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests( 7512 NextProto next_proto, 7513 SpdySessionDependencies* session_deps_) { 7514 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_)); 7515 7516 base::WeakPtr<HttpServerProperties> http_server_properties = 7517 session->http_server_properties(); 7518 http_server_properties->SetAlternateProtocol( 7519 HostPortPair("host.with.alternate", 80), 443, 7520 AlternateProtocolFromNextProto(next_proto)); 7521 7522 return session; 7523 } 7524 7525 int GroupNameTransactionHelper( 7526 const std::string& url, 7527 const scoped_refptr<HttpNetworkSession>& session) { 7528 HttpRequestInfo request; 7529 request.method = "GET"; 7530 request.url = GURL(url); 7531 request.load_flags = 0; 7532 7533 scoped_ptr<HttpTransaction> trans( 7534 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7535 7536 TestCompletionCallback callback; 7537 7538 // We do not complete this request, the dtor will clean the transaction up. 7539 return trans->Start(&request, callback.callback(), BoundNetLog()); 7540 } 7541 7542 } // namespace 7543 7544 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) { 7545 const GroupNameTest tests[] = { 7546 { 7547 "", // unused 7548 "http://www.google.com/direct", 7549 "www.google.com:80", 7550 false, 7551 }, 7552 { 7553 "", // unused 7554 "http://[2001:1418:13:1::25]/direct", 7555 "[2001:1418:13:1::25]:80", 7556 false, 7557 }, 7558 7559 // SSL Tests 7560 { 7561 "", // unused 7562 "https://www.google.com/direct_ssl", 7563 "ssl/www.google.com:443", 7564 true, 7565 }, 7566 { 7567 "", // unused 7568 "https://[2001:1418:13:1::25]/direct", 7569 "ssl/[2001:1418:13:1::25]:443", 7570 true, 7571 }, 7572 { 7573 "", // unused 7574 "http://host.with.alternate/direct", 7575 "ssl/host.with.alternate:443", 7576 true, 7577 }, 7578 }; 7579 7580 session_deps_.use_alternate_protocols = true; 7581 7582 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7583 session_deps_.proxy_service.reset( 7584 ProxyService::CreateFixed(tests[i].proxy_server)); 7585 scoped_refptr<HttpNetworkSession> session( 7586 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7587 7588 HttpNetworkSessionPeer peer(session); 7589 CaptureGroupNameTransportSocketPool* transport_conn_pool = 7590 new CaptureGroupNameTransportSocketPool(NULL, NULL); 7591 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7592 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7593 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7594 new MockClientSocketPoolManager); 7595 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 7596 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); 7597 peer.SetClientSocketPoolManager( 7598 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7599 7600 EXPECT_EQ(ERR_IO_PENDING, 7601 GroupNameTransactionHelper(tests[i].url, session)); 7602 if (tests[i].ssl) 7603 EXPECT_EQ(tests[i].expected_group_name, 7604 ssl_conn_pool->last_group_name_received()); 7605 else 7606 EXPECT_EQ(tests[i].expected_group_name, 7607 transport_conn_pool->last_group_name_received()); 7608 } 7609 7610 } 7611 7612 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) { 7613 const GroupNameTest tests[] = { 7614 { 7615 "http_proxy", 7616 "http://www.google.com/http_proxy_normal", 7617 "www.google.com:80", 7618 false, 7619 }, 7620 7621 // SSL Tests 7622 { 7623 "http_proxy", 7624 "https://www.google.com/http_connect_ssl", 7625 "ssl/www.google.com:443", 7626 true, 7627 }, 7628 7629 { 7630 "http_proxy", 7631 "http://host.with.alternate/direct", 7632 "ssl/host.with.alternate:443", 7633 true, 7634 }, 7635 7636 { 7637 "http_proxy", 7638 "ftp://ftp.google.com/http_proxy_normal", 7639 "ftp/ftp.google.com:21", 7640 false, 7641 }, 7642 }; 7643 7644 session_deps_.use_alternate_protocols = true; 7645 7646 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7647 session_deps_.proxy_service.reset( 7648 ProxyService::CreateFixed(tests[i].proxy_server)); 7649 scoped_refptr<HttpNetworkSession> session( 7650 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7651 7652 HttpNetworkSessionPeer peer(session); 7653 7654 HostPortPair proxy_host("http_proxy", 80); 7655 CaptureGroupNameHttpProxySocketPool* http_proxy_pool = 7656 new CaptureGroupNameHttpProxySocketPool(NULL, NULL); 7657 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7658 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7659 7660 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7661 new MockClientSocketPoolManager); 7662 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); 7663 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 7664 peer.SetClientSocketPoolManager( 7665 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7666 7667 EXPECT_EQ(ERR_IO_PENDING, 7668 GroupNameTransactionHelper(tests[i].url, session)); 7669 if (tests[i].ssl) 7670 EXPECT_EQ(tests[i].expected_group_name, 7671 ssl_conn_pool->last_group_name_received()); 7672 else 7673 EXPECT_EQ(tests[i].expected_group_name, 7674 http_proxy_pool->last_group_name_received()); 7675 } 7676 } 7677 7678 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) { 7679 const GroupNameTest tests[] = { 7680 { 7681 "socks4://socks_proxy:1080", 7682 "http://www.google.com/socks4_direct", 7683 "socks4/www.google.com:80", 7684 false, 7685 }, 7686 { 7687 "socks5://socks_proxy:1080", 7688 "http://www.google.com/socks5_direct", 7689 "socks5/www.google.com:80", 7690 false, 7691 }, 7692 7693 // SSL Tests 7694 { 7695 "socks4://socks_proxy:1080", 7696 "https://www.google.com/socks4_ssl", 7697 "socks4/ssl/www.google.com:443", 7698 true, 7699 }, 7700 { 7701 "socks5://socks_proxy:1080", 7702 "https://www.google.com/socks5_ssl", 7703 "socks5/ssl/www.google.com:443", 7704 true, 7705 }, 7706 7707 { 7708 "socks4://socks_proxy:1080", 7709 "http://host.with.alternate/direct", 7710 "socks4/ssl/host.with.alternate:443", 7711 true, 7712 }, 7713 }; 7714 7715 session_deps_.use_alternate_protocols = true; 7716 7717 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 7718 session_deps_.proxy_service.reset( 7719 ProxyService::CreateFixed(tests[i].proxy_server)); 7720 scoped_refptr<HttpNetworkSession> session( 7721 SetupSessionForGroupNameTests(GetParam(), &session_deps_)); 7722 7723 HttpNetworkSessionPeer peer(session); 7724 7725 HostPortPair proxy_host("socks_proxy", 1080); 7726 CaptureGroupNameSOCKSSocketPool* socks_conn_pool = 7727 new CaptureGroupNameSOCKSSocketPool(NULL, NULL); 7728 CaptureGroupNameSSLSocketPool* ssl_conn_pool = 7729 new CaptureGroupNameSSLSocketPool(NULL, NULL); 7730 7731 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 7732 new MockClientSocketPoolManager); 7733 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool); 7734 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 7735 peer.SetClientSocketPoolManager( 7736 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 7737 7738 scoped_ptr<HttpTransaction> trans( 7739 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7740 7741 EXPECT_EQ(ERR_IO_PENDING, 7742 GroupNameTransactionHelper(tests[i].url, session)); 7743 if (tests[i].ssl) 7744 EXPECT_EQ(tests[i].expected_group_name, 7745 ssl_conn_pool->last_group_name_received()); 7746 else 7747 EXPECT_EQ(tests[i].expected_group_name, 7748 socks_conn_pool->last_group_name_received()); 7749 } 7750 } 7751 7752 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) { 7753 HttpRequestInfo request; 7754 request.method = "GET"; 7755 request.url = GURL("http://www.google.com/"); 7756 7757 session_deps_.proxy_service.reset( 7758 ProxyService::CreateFixed("myproxy:70;foobar:80")); 7759 7760 // This simulates failure resolving all hostnames; that means we will fail 7761 // connecting to both proxies (myproxy:70 and foobar:80). 7762 session_deps_.host_resolver->rules()->AddSimulatedFailure("*"); 7763 7764 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7765 scoped_ptr<HttpTransaction> trans( 7766 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7767 7768 TestCompletionCallback callback; 7769 7770 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7771 EXPECT_EQ(ERR_IO_PENDING, rv); 7772 7773 rv = callback.WaitForResult(); 7774 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv); 7775 } 7776 7777 // Base test to make sure that when the load flags for a request specify to 7778 // bypass the cache, the DNS cache is not used. 7779 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper( 7780 int load_flags) { 7781 // Issue a request, asking to bypass the cache(s). 7782 HttpRequestInfo request; 7783 request.method = "GET"; 7784 request.load_flags = load_flags; 7785 request.url = GURL("http://www.google.com/"); 7786 7787 // Select a host resolver that does caching. 7788 session_deps_.host_resolver.reset(new MockCachingHostResolver); 7789 7790 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7791 scoped_ptr<HttpTransaction> trans( 7792 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7793 7794 // Warm up the host cache so it has an entry for "www.google.com". 7795 AddressList addrlist; 7796 TestCompletionCallback callback; 7797 int rv = session_deps_.host_resolver->Resolve( 7798 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), 7799 DEFAULT_PRIORITY, 7800 &addrlist, 7801 callback.callback(), 7802 NULL, 7803 BoundNetLog()); 7804 EXPECT_EQ(ERR_IO_PENDING, rv); 7805 rv = callback.WaitForResult(); 7806 EXPECT_EQ(OK, rv); 7807 7808 // Verify that it was added to host cache, by doing a subsequent async lookup 7809 // and confirming it completes synchronously. 7810 rv = session_deps_.host_resolver->Resolve( 7811 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), 7812 DEFAULT_PRIORITY, 7813 &addrlist, 7814 callback.callback(), 7815 NULL, 7816 BoundNetLog()); 7817 ASSERT_EQ(OK, rv); 7818 7819 // Inject a failure the next time that "www.google.com" is resolved. This way 7820 // we can tell if the next lookup hit the cache, or the "network". 7821 // (cache --> success, "network" --> failure). 7822 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com"); 7823 7824 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the 7825 // first read -- this won't be reached as the host resolution will fail first. 7826 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) }; 7827 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7828 session_deps_.socket_factory->AddSocketDataProvider(&data); 7829 7830 // Run the request. 7831 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7832 ASSERT_EQ(ERR_IO_PENDING, rv); 7833 rv = callback.WaitForResult(); 7834 7835 // If we bypassed the cache, we would have gotten a failure while resolving 7836 // "www.google.com". 7837 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); 7838 } 7839 7840 // There are multiple load flags that should trigger the host cache bypass. 7841 // Test each in isolation: 7842 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) { 7843 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE); 7844 } 7845 7846 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) { 7847 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE); 7848 } 7849 7850 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) { 7851 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE); 7852 } 7853 7854 // Make sure we can handle an error when writing the request. 7855 TEST_P(HttpNetworkTransactionTest, RequestWriteError) { 7856 HttpRequestInfo request; 7857 request.method = "GET"; 7858 request.url = GURL("http://www.foo.com/"); 7859 request.load_flags = 0; 7860 7861 MockWrite write_failure[] = { 7862 MockWrite(ASYNC, ERR_CONNECTION_RESET), 7863 }; 7864 StaticSocketDataProvider data(NULL, 0, 7865 write_failure, arraysize(write_failure)); 7866 session_deps_.socket_factory->AddSocketDataProvider(&data); 7867 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7868 7869 TestCompletionCallback callback; 7870 7871 scoped_ptr<HttpTransaction> trans( 7872 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7873 7874 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7875 EXPECT_EQ(ERR_IO_PENDING, rv); 7876 7877 rv = callback.WaitForResult(); 7878 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 7879 } 7880 7881 // Check that a connection closed after the start of the headers finishes ok. 7882 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) { 7883 HttpRequestInfo request; 7884 request.method = "GET"; 7885 request.url = GURL("http://www.foo.com/"); 7886 request.load_flags = 0; 7887 7888 MockRead data_reads[] = { 7889 MockRead("HTTP/1."), 7890 MockRead(SYNCHRONOUS, OK), 7891 }; 7892 7893 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 7894 session_deps_.socket_factory->AddSocketDataProvider(&data); 7895 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7896 7897 TestCompletionCallback callback; 7898 7899 scoped_ptr<HttpTransaction> trans( 7900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 7901 7902 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 7903 EXPECT_EQ(ERR_IO_PENDING, rv); 7904 7905 rv = callback.WaitForResult(); 7906 EXPECT_EQ(OK, rv); 7907 7908 const HttpResponseInfo* response = trans->GetResponseInfo(); 7909 ASSERT_TRUE(response != NULL); 7910 7911 EXPECT_TRUE(response->headers.get() != NULL); 7912 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 7913 7914 std::string response_data; 7915 rv = ReadTransaction(trans.get(), &response_data); 7916 EXPECT_EQ(OK, rv); 7917 EXPECT_EQ("", response_data); 7918 } 7919 7920 // Make sure that a dropped connection while draining the body for auth 7921 // restart does the right thing. 7922 TEST_P(HttpNetworkTransactionTest, DrainResetOK) { 7923 HttpRequestInfo request; 7924 request.method = "GET"; 7925 request.url = GURL("http://www.google.com/"); 7926 request.load_flags = 0; 7927 7928 MockWrite data_writes1[] = { 7929 MockWrite("GET / HTTP/1.1\r\n" 7930 "Host: www.google.com\r\n" 7931 "Connection: keep-alive\r\n\r\n"), 7932 }; 7933 7934 MockRead data_reads1[] = { 7935 MockRead("HTTP/1.1 401 Unauthorized\r\n"), 7936 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 7937 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7938 MockRead("Content-Length: 14\r\n\r\n"), 7939 MockRead("Unauth"), 7940 MockRead(ASYNC, ERR_CONNECTION_RESET), 7941 }; 7942 7943 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 7944 data_writes1, arraysize(data_writes1)); 7945 session_deps_.socket_factory->AddSocketDataProvider(&data1); 7946 7947 // After calling trans->RestartWithAuth(), this is the request we should 7948 // be issuing -- the final header line contains the credentials. 7949 MockWrite data_writes2[] = { 7950 MockWrite("GET / HTTP/1.1\r\n" 7951 "Host: www.google.com\r\n" 7952 "Connection: keep-alive\r\n" 7953 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 7954 }; 7955 7956 // Lastly, the server responds with the actual content. 7957 MockRead data_reads2[] = { 7958 MockRead("HTTP/1.1 200 OK\r\n"), 7959 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 7960 MockRead("Content-Length: 100\r\n\r\n"), 7961 MockRead(SYNCHRONOUS, OK), 7962 }; 7963 7964 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 7965 data_writes2, arraysize(data_writes2)); 7966 session_deps_.socket_factory->AddSocketDataProvider(&data2); 7967 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 7968 7969 TestCompletionCallback callback1; 7970 7971 scoped_ptr<HttpTransaction> trans( 7972 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 7973 7974 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 7975 EXPECT_EQ(ERR_IO_PENDING, rv); 7976 7977 rv = callback1.WaitForResult(); 7978 EXPECT_EQ(OK, rv); 7979 7980 const HttpResponseInfo* response = trans->GetResponseInfo(); 7981 ASSERT_TRUE(response != NULL); 7982 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); 7983 7984 TestCompletionCallback callback2; 7985 7986 rv = trans->RestartWithAuth( 7987 AuthCredentials(kFoo, kBar), callback2.callback()); 7988 EXPECT_EQ(ERR_IO_PENDING, rv); 7989 7990 rv = callback2.WaitForResult(); 7991 EXPECT_EQ(OK, rv); 7992 7993 response = trans->GetResponseInfo(); 7994 ASSERT_TRUE(response != NULL); 7995 EXPECT_TRUE(response->auth_challenge.get() == NULL); 7996 EXPECT_EQ(100, response->headers->GetContentLength()); 7997 } 7998 7999 // Test HTTPS connections going through a proxy that sends extra data. 8000 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) { 8001 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 8002 8003 HttpRequestInfo request; 8004 request.method = "GET"; 8005 request.url = GURL("https://www.google.com/"); 8006 request.load_flags = 0; 8007 8008 MockRead proxy_reads[] = { 8009 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"), 8010 MockRead(SYNCHRONOUS, OK) 8011 }; 8012 8013 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0); 8014 SSLSocketDataProvider ssl(ASYNC, OK); 8015 8016 session_deps_.socket_factory->AddSocketDataProvider(&data); 8017 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8018 8019 TestCompletionCallback callback; 8020 8021 session_deps_.socket_factory->ResetNextMockIndexes(); 8022 8023 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8024 scoped_ptr<HttpTransaction> trans( 8025 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 8026 8027 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8028 EXPECT_EQ(ERR_IO_PENDING, rv); 8029 8030 rv = callback.WaitForResult(); 8031 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 8032 } 8033 8034 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) { 8035 HttpRequestInfo request; 8036 request.method = "GET"; 8037 request.url = GURL("http://www.google.com/"); 8038 request.load_flags = 0; 8039 8040 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8041 scoped_ptr<HttpTransaction> trans( 8042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 8043 8044 MockRead data_reads[] = { 8045 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"), 8046 MockRead(SYNCHRONOUS, OK), 8047 }; 8048 8049 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 8050 session_deps_.socket_factory->AddSocketDataProvider(&data); 8051 8052 TestCompletionCallback callback; 8053 8054 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8055 EXPECT_EQ(ERR_IO_PENDING, rv); 8056 8057 EXPECT_EQ(OK, callback.WaitForResult()); 8058 8059 const HttpResponseInfo* response = trans->GetResponseInfo(); 8060 ASSERT_TRUE(response != NULL); 8061 8062 EXPECT_TRUE(response->headers.get() != NULL); 8063 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 8064 8065 std::string response_data; 8066 rv = ReadTransaction(trans.get(), &response_data); 8067 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); 8068 } 8069 8070 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) { 8071 base::FilePath temp_file_path; 8072 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path)); 8073 const uint64 kFakeSize = 100000; // file is actually blank 8074 UploadFileElementReader::ScopedOverridingContentLengthForTests 8075 overriding_content_length(kFakeSize); 8076 8077 ScopedVector<UploadElementReader> element_readers; 8078 element_readers.push_back( 8079 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 8080 temp_file_path, 8081 0, 8082 kuint64max, 8083 base::Time())); 8084 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 8085 8086 HttpRequestInfo request; 8087 request.method = "POST"; 8088 request.url = GURL("http://www.google.com/upload"); 8089 request.upload_data_stream = &upload_data_stream; 8090 request.load_flags = 0; 8091 8092 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8093 scoped_ptr<HttpTransaction> trans( 8094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 8095 8096 MockRead data_reads[] = { 8097 MockRead("HTTP/1.0 200 OK\r\n\r\n"), 8098 MockRead("hello world"), 8099 MockRead(SYNCHRONOUS, OK), 8100 }; 8101 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 8102 session_deps_.socket_factory->AddSocketDataProvider(&data); 8103 8104 TestCompletionCallback callback; 8105 8106 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8107 EXPECT_EQ(ERR_IO_PENDING, rv); 8108 8109 rv = callback.WaitForResult(); 8110 EXPECT_EQ(OK, rv); 8111 8112 const HttpResponseInfo* response = trans->GetResponseInfo(); 8113 ASSERT_TRUE(response != NULL); 8114 8115 EXPECT_TRUE(response->headers.get() != NULL); 8116 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 8117 8118 std::string response_data; 8119 rv = ReadTransaction(trans.get(), &response_data); 8120 EXPECT_EQ(OK, rv); 8121 EXPECT_EQ("hello world", response_data); 8122 8123 base::DeleteFile(temp_file_path, false); 8124 } 8125 8126 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) { 8127 base::FilePath temp_file; 8128 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file)); 8129 std::string temp_file_content("Unreadable file."); 8130 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(), 8131 temp_file_content.length())); 8132 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file)); 8133 8134 ScopedVector<UploadElementReader> element_readers; 8135 element_readers.push_back( 8136 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 8137 temp_file, 8138 0, 8139 kuint64max, 8140 base::Time())); 8141 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 8142 8143 HttpRequestInfo request; 8144 request.method = "POST"; 8145 request.url = GURL("http://www.google.com/upload"); 8146 request.upload_data_stream = &upload_data_stream; 8147 request.load_flags = 0; 8148 8149 // If we try to upload an unreadable file, the transaction should fail. 8150 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8151 scoped_ptr<HttpTransaction> trans( 8152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 8153 8154 StaticSocketDataProvider data(NULL, 0, NULL, 0); 8155 session_deps_.socket_factory->AddSocketDataProvider(&data); 8156 8157 TestCompletionCallback callback; 8158 8159 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8160 EXPECT_EQ(ERR_IO_PENDING, rv); 8161 8162 rv = callback.WaitForResult(); 8163 EXPECT_EQ(ERR_ACCESS_DENIED, rv); 8164 8165 const HttpResponseInfo* response = trans->GetResponseInfo(); 8166 EXPECT_FALSE(response); 8167 8168 base::DeleteFile(temp_file, false); 8169 } 8170 8171 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) { 8172 class FakeUploadElementReader : public UploadElementReader { 8173 public: 8174 FakeUploadElementReader() {} 8175 virtual ~FakeUploadElementReader() {} 8176 8177 const CompletionCallback& callback() const { return callback_; } 8178 8179 // UploadElementReader overrides: 8180 virtual int Init(const CompletionCallback& callback) OVERRIDE { 8181 callback_ = callback; 8182 return ERR_IO_PENDING; 8183 } 8184 virtual uint64 GetContentLength() const OVERRIDE { return 0; } 8185 virtual uint64 BytesRemaining() const OVERRIDE { return 0; } 8186 virtual int Read(IOBuffer* buf, 8187 int buf_length, 8188 const CompletionCallback& callback) OVERRIDE { 8189 return ERR_FAILED; 8190 } 8191 8192 private: 8193 CompletionCallback callback_; 8194 }; 8195 8196 FakeUploadElementReader* fake_reader = new FakeUploadElementReader; 8197 ScopedVector<UploadElementReader> element_readers; 8198 element_readers.push_back(fake_reader); 8199 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 8200 8201 HttpRequestInfo request; 8202 request.method = "POST"; 8203 request.url = GURL("http://www.google.com/upload"); 8204 request.upload_data_stream = &upload_data_stream; 8205 request.load_flags = 0; 8206 8207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8208 scoped_ptr<HttpTransaction> trans( 8209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 8210 8211 StaticSocketDataProvider data; 8212 session_deps_.socket_factory->AddSocketDataProvider(&data); 8213 8214 TestCompletionCallback callback; 8215 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8216 EXPECT_EQ(ERR_IO_PENDING, rv); 8217 base::MessageLoop::current()->RunUntilIdle(); 8218 8219 // Transaction is pending on request body initialization. 8220 ASSERT_FALSE(fake_reader->callback().is_null()); 8221 8222 // Return Init()'s result after the transaction gets destroyed. 8223 trans.reset(); 8224 fake_reader->callback().Run(OK); // Should not crash. 8225 } 8226 8227 // Tests that changes to Auth realms are treated like auth rejections. 8228 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) { 8229 8230 HttpRequestInfo request; 8231 request.method = "GET"; 8232 request.url = GURL("http://www.google.com/"); 8233 request.load_flags = 0; 8234 8235 // First transaction will request a resource and receive a Basic challenge 8236 // with realm="first_realm". 8237 MockWrite data_writes1[] = { 8238 MockWrite("GET / HTTP/1.1\r\n" 8239 "Host: www.google.com\r\n" 8240 "Connection: keep-alive\r\n" 8241 "\r\n"), 8242 }; 8243 MockRead data_reads1[] = { 8244 MockRead("HTTP/1.1 401 Unauthorized\r\n" 8245 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 8246 "\r\n"), 8247 }; 8248 8249 // After calling trans->RestartWithAuth(), provide an Authentication header 8250 // for first_realm. The server will reject and provide a challenge with 8251 // second_realm. 8252 MockWrite data_writes2[] = { 8253 MockWrite("GET / HTTP/1.1\r\n" 8254 "Host: www.google.com\r\n" 8255 "Connection: keep-alive\r\n" 8256 "Authorization: Basic Zmlyc3Q6YmF6\r\n" 8257 "\r\n"), 8258 }; 8259 MockRead data_reads2[] = { 8260 MockRead("HTTP/1.1 401 Unauthorized\r\n" 8261 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n" 8262 "\r\n"), 8263 }; 8264 8265 // This again fails, and goes back to first_realm. Make sure that the 8266 // entry is removed from cache. 8267 MockWrite data_writes3[] = { 8268 MockWrite("GET / HTTP/1.1\r\n" 8269 "Host: www.google.com\r\n" 8270 "Connection: keep-alive\r\n" 8271 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n" 8272 "\r\n"), 8273 }; 8274 MockRead data_reads3[] = { 8275 MockRead("HTTP/1.1 401 Unauthorized\r\n" 8276 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 8277 "\r\n"), 8278 }; 8279 8280 // Try one last time (with the correct password) and get the resource. 8281 MockWrite data_writes4[] = { 8282 MockWrite("GET / HTTP/1.1\r\n" 8283 "Host: www.google.com\r\n" 8284 "Connection: keep-alive\r\n" 8285 "Authorization: Basic Zmlyc3Q6YmFy\r\n" 8286 "\r\n"), 8287 }; 8288 MockRead data_reads4[] = { 8289 MockRead("HTTP/1.1 200 OK\r\n" 8290 "Content-Type: text/html; charset=iso-8859-1\r\n" 8291 "Content-Length: 5\r\n" 8292 "\r\n" 8293 "hello"), 8294 }; 8295 8296 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 8297 data_writes1, arraysize(data_writes1)); 8298 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 8299 data_writes2, arraysize(data_writes2)); 8300 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 8301 data_writes3, arraysize(data_writes3)); 8302 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4), 8303 data_writes4, arraysize(data_writes4)); 8304 session_deps_.socket_factory->AddSocketDataProvider(&data1); 8305 session_deps_.socket_factory->AddSocketDataProvider(&data2); 8306 session_deps_.socket_factory->AddSocketDataProvider(&data3); 8307 session_deps_.socket_factory->AddSocketDataProvider(&data4); 8308 8309 TestCompletionCallback callback1; 8310 8311 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8312 scoped_ptr<HttpTransaction> trans( 8313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 8314 8315 // Issue the first request with Authorize headers. There should be a 8316 // password prompt for first_realm waiting to be filled in after the 8317 // transaction completes. 8318 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); 8319 EXPECT_EQ(ERR_IO_PENDING, rv); 8320 rv = callback1.WaitForResult(); 8321 EXPECT_EQ(OK, rv); 8322 const HttpResponseInfo* response = trans->GetResponseInfo(); 8323 ASSERT_TRUE(response != NULL); 8324 const AuthChallengeInfo* challenge = response->auth_challenge.get(); 8325 ASSERT_FALSE(challenge == NULL); 8326 EXPECT_FALSE(challenge->is_proxy); 8327 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 8328 EXPECT_EQ("first_realm", challenge->realm); 8329 EXPECT_EQ("basic", challenge->scheme); 8330 8331 // Issue the second request with an incorrect password. There should be a 8332 // password prompt for second_realm waiting to be filled in after the 8333 // transaction completes. 8334 TestCompletionCallback callback2; 8335 rv = trans->RestartWithAuth( 8336 AuthCredentials(kFirst, kBaz), callback2.callback()); 8337 EXPECT_EQ(ERR_IO_PENDING, rv); 8338 rv = callback2.WaitForResult(); 8339 EXPECT_EQ(OK, rv); 8340 response = trans->GetResponseInfo(); 8341 ASSERT_TRUE(response != NULL); 8342 challenge = response->auth_challenge.get(); 8343 ASSERT_FALSE(challenge == NULL); 8344 EXPECT_FALSE(challenge->is_proxy); 8345 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 8346 EXPECT_EQ("second_realm", challenge->realm); 8347 EXPECT_EQ("basic", challenge->scheme); 8348 8349 // Issue the third request with another incorrect password. There should be 8350 // a password prompt for first_realm waiting to be filled in. If the password 8351 // prompt is not present, it indicates that the HttpAuthCacheEntry for 8352 // first_realm was not correctly removed. 8353 TestCompletionCallback callback3; 8354 rv = trans->RestartWithAuth( 8355 AuthCredentials(kSecond, kFou), callback3.callback()); 8356 EXPECT_EQ(ERR_IO_PENDING, rv); 8357 rv = callback3.WaitForResult(); 8358 EXPECT_EQ(OK, rv); 8359 response = trans->GetResponseInfo(); 8360 ASSERT_TRUE(response != NULL); 8361 challenge = response->auth_challenge.get(); 8362 ASSERT_FALSE(challenge == NULL); 8363 EXPECT_FALSE(challenge->is_proxy); 8364 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString()); 8365 EXPECT_EQ("first_realm", challenge->realm); 8366 EXPECT_EQ("basic", challenge->scheme); 8367 8368 // Issue the fourth request with the correct password and username. 8369 TestCompletionCallback callback4; 8370 rv = trans->RestartWithAuth( 8371 AuthCredentials(kFirst, kBar), callback4.callback()); 8372 EXPECT_EQ(ERR_IO_PENDING, rv); 8373 rv = callback4.WaitForResult(); 8374 EXPECT_EQ(OK, rv); 8375 response = trans->GetResponseInfo(); 8376 ASSERT_TRUE(response != NULL); 8377 EXPECT_TRUE(response->auth_challenge.get() == NULL); 8378 } 8379 8380 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { 8381 session_deps_.next_protos = SpdyNextProtos(); 8382 session_deps_.use_alternate_protocols = true; 8383 8384 std::string alternate_protocol_http_header = 8385 GetAlternateProtocolHttpHeader(); 8386 8387 MockRead data_reads[] = { 8388 MockRead("HTTP/1.1 200 OK\r\n"), 8389 MockRead(alternate_protocol_http_header.c_str()), 8390 MockRead("hello world"), 8391 MockRead(SYNCHRONOUS, OK), 8392 }; 8393 8394 HttpRequestInfo request; 8395 request.method = "GET"; 8396 request.url = GURL("http://www.google.com/"); 8397 request.load_flags = 0; 8398 8399 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 8400 8401 session_deps_.socket_factory->AddSocketDataProvider(&data); 8402 8403 TestCompletionCallback callback; 8404 8405 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8406 scoped_ptr<HttpTransaction> trans( 8407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8408 8409 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8410 EXPECT_EQ(ERR_IO_PENDING, rv); 8411 8412 HostPortPair http_host_port_pair("www.google.com", 80); 8413 HttpServerProperties& http_server_properties = 8414 *session->http_server_properties(); 8415 EXPECT_FALSE( 8416 http_server_properties.HasAlternateProtocol(http_host_port_pair)); 8417 8418 EXPECT_EQ(OK, callback.WaitForResult()); 8419 8420 const HttpResponseInfo* response = trans->GetResponseInfo(); 8421 ASSERT_TRUE(response != NULL); 8422 ASSERT_TRUE(response->headers.get() != NULL); 8423 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8424 EXPECT_FALSE(response->was_fetched_via_spdy); 8425 EXPECT_FALSE(response->was_npn_negotiated); 8426 8427 std::string response_data; 8428 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8429 EXPECT_EQ("hello world", response_data); 8430 8431 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair)); 8432 const PortAlternateProtocolPair alternate = 8433 http_server_properties.GetAlternateProtocol(http_host_port_pair); 8434 PortAlternateProtocolPair expected_alternate; 8435 expected_alternate.port = 443; 8436 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam()); 8437 EXPECT_TRUE(expected_alternate.Equals(alternate)); 8438 } 8439 8440 TEST_P(HttpNetworkTransactionTest, 8441 MarkBrokenAlternateProtocolAndFallback) { 8442 session_deps_.use_alternate_protocols = true; 8443 8444 HttpRequestInfo request; 8445 request.method = "GET"; 8446 request.url = GURL("http://www.google.com/"); 8447 request.load_flags = 0; 8448 8449 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8450 StaticSocketDataProvider first_data; 8451 first_data.set_connect_data(mock_connect); 8452 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8453 8454 MockRead data_reads[] = { 8455 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8456 MockRead("hello world"), 8457 MockRead(ASYNC, OK), 8458 }; 8459 StaticSocketDataProvider second_data( 8460 data_reads, arraysize(data_reads), NULL, 0); 8461 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8462 8463 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8464 8465 base::WeakPtr<HttpServerProperties> http_server_properties = 8466 session->http_server_properties(); 8467 // Port must be < 1024, or the header will be ignored (since initial port was 8468 // port 80 (another restricted port). 8469 http_server_properties->SetAlternateProtocol( 8470 HostPortPair::FromURL(request.url), 8471 666 /* port is ignored by MockConnect anyway */, 8472 AlternateProtocolFromNextProto(GetParam())); 8473 8474 scoped_ptr<HttpTransaction> trans( 8475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8476 TestCompletionCallback callback; 8477 8478 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8479 EXPECT_EQ(ERR_IO_PENDING, rv); 8480 EXPECT_EQ(OK, callback.WaitForResult()); 8481 8482 const HttpResponseInfo* response = trans->GetResponseInfo(); 8483 ASSERT_TRUE(response != NULL); 8484 ASSERT_TRUE(response->headers.get() != NULL); 8485 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8486 8487 std::string response_data; 8488 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8489 EXPECT_EQ("hello world", response_data); 8490 8491 ASSERT_TRUE(http_server_properties->HasAlternateProtocol( 8492 HostPortPair::FromURL(request.url))); 8493 const PortAlternateProtocolPair alternate = 8494 http_server_properties->GetAlternateProtocol( 8495 HostPortPair::FromURL(request.url)); 8496 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); 8497 } 8498 8499 TEST_P(HttpNetworkTransactionTest, 8500 AlternateProtocolPortRestrictedBlocked) { 8501 // Ensure that we're not allowed to redirect traffic via an alternate 8502 // protocol to an unrestricted (port >= 1024) when the original traffic was 8503 // on a restricted port (port < 1024). Ensure that we can redirect in all 8504 // other cases. 8505 session_deps_.use_alternate_protocols = true; 8506 8507 HttpRequestInfo restricted_port_request; 8508 restricted_port_request.method = "GET"; 8509 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8510 restricted_port_request.load_flags = 0; 8511 8512 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8513 StaticSocketDataProvider first_data; 8514 first_data.set_connect_data(mock_connect); 8515 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8516 8517 MockRead data_reads[] = { 8518 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8519 MockRead("hello world"), 8520 MockRead(ASYNC, OK), 8521 }; 8522 StaticSocketDataProvider second_data( 8523 data_reads, arraysize(data_reads), NULL, 0); 8524 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8525 8526 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8527 8528 base::WeakPtr<HttpServerProperties> http_server_properties = 8529 session->http_server_properties(); 8530 const int kUnrestrictedAlternatePort = 1024; 8531 http_server_properties->SetAlternateProtocol( 8532 HostPortPair::FromURL(restricted_port_request.url), 8533 kUnrestrictedAlternatePort, 8534 AlternateProtocolFromNextProto(GetParam())); 8535 8536 scoped_ptr<HttpTransaction> trans( 8537 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8538 TestCompletionCallback callback; 8539 8540 int rv = trans->Start( 8541 &restricted_port_request, 8542 callback.callback(), BoundNetLog()); 8543 EXPECT_EQ(ERR_IO_PENDING, rv); 8544 // Invalid change to unrestricted port should fail. 8545 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult()); 8546 } 8547 8548 TEST_P(HttpNetworkTransactionTest, 8549 AlternateProtocolPortRestrictedPermitted) { 8550 // Ensure that we're allowed to redirect traffic via an alternate 8551 // protocol to an unrestricted (port >= 1024) when the original traffic was 8552 // on a restricted port (port < 1024) if we set 8553 // enable_user_alternate_protocol_ports. 8554 8555 session_deps_.use_alternate_protocols = true; 8556 session_deps_.enable_user_alternate_protocol_ports = true; 8557 8558 HttpRequestInfo restricted_port_request; 8559 restricted_port_request.method = "GET"; 8560 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8561 restricted_port_request.load_flags = 0; 8562 8563 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8564 StaticSocketDataProvider first_data; 8565 first_data.set_connect_data(mock_connect); 8566 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8567 8568 MockRead data_reads[] = { 8569 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8570 MockRead("hello world"), 8571 MockRead(ASYNC, OK), 8572 }; 8573 StaticSocketDataProvider second_data( 8574 data_reads, arraysize(data_reads), NULL, 0); 8575 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8576 8577 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8578 8579 base::WeakPtr<HttpServerProperties> http_server_properties = 8580 session->http_server_properties(); 8581 const int kUnrestrictedAlternatePort = 1024; 8582 http_server_properties->SetAlternateProtocol( 8583 HostPortPair::FromURL(restricted_port_request.url), 8584 kUnrestrictedAlternatePort, 8585 AlternateProtocolFromNextProto(GetParam())); 8586 8587 scoped_ptr<HttpTransaction> trans( 8588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8589 TestCompletionCallback callback; 8590 8591 EXPECT_EQ(ERR_IO_PENDING, trans->Start( 8592 &restricted_port_request, 8593 callback.callback(), BoundNetLog())); 8594 // Change to unrestricted port should succeed. 8595 EXPECT_EQ(OK, callback.WaitForResult()); 8596 } 8597 8598 TEST_P(HttpNetworkTransactionTest, 8599 AlternateProtocolPortRestrictedAllowed) { 8600 // Ensure that we're not allowed to redirect traffic via an alternate 8601 // protocol to an unrestricted (port >= 1024) when the original traffic was 8602 // on a restricted port (port < 1024). Ensure that we can redirect in all 8603 // other cases. 8604 session_deps_.use_alternate_protocols = true; 8605 8606 HttpRequestInfo restricted_port_request; 8607 restricted_port_request.method = "GET"; 8608 restricted_port_request.url = GURL("http://www.google.com:1023/"); 8609 restricted_port_request.load_flags = 0; 8610 8611 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8612 StaticSocketDataProvider first_data; 8613 first_data.set_connect_data(mock_connect); 8614 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8615 8616 MockRead data_reads[] = { 8617 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8618 MockRead("hello world"), 8619 MockRead(ASYNC, OK), 8620 }; 8621 StaticSocketDataProvider second_data( 8622 data_reads, arraysize(data_reads), NULL, 0); 8623 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8624 8625 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8626 8627 base::WeakPtr<HttpServerProperties> http_server_properties = 8628 session->http_server_properties(); 8629 const int kRestrictedAlternatePort = 80; 8630 http_server_properties->SetAlternateProtocol( 8631 HostPortPair::FromURL(restricted_port_request.url), 8632 kRestrictedAlternatePort, 8633 AlternateProtocolFromNextProto(GetParam())); 8634 8635 scoped_ptr<HttpTransaction> trans( 8636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8637 TestCompletionCallback callback; 8638 8639 int rv = trans->Start( 8640 &restricted_port_request, 8641 callback.callback(), BoundNetLog()); 8642 EXPECT_EQ(ERR_IO_PENDING, rv); 8643 // Valid change to restricted port should pass. 8644 EXPECT_EQ(OK, callback.WaitForResult()); 8645 } 8646 8647 TEST_P(HttpNetworkTransactionTest, 8648 AlternateProtocolPortUnrestrictedAllowed1) { 8649 // Ensure that we're not allowed to redirect traffic via an alternate 8650 // protocol to an unrestricted (port >= 1024) when the original traffic was 8651 // on a restricted port (port < 1024). Ensure that we can redirect in all 8652 // other cases. 8653 session_deps_.use_alternate_protocols = true; 8654 8655 HttpRequestInfo unrestricted_port_request; 8656 unrestricted_port_request.method = "GET"; 8657 unrestricted_port_request.url = GURL("http://www.google.com:1024/"); 8658 unrestricted_port_request.load_flags = 0; 8659 8660 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8661 StaticSocketDataProvider first_data; 8662 first_data.set_connect_data(mock_connect); 8663 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8664 8665 MockRead data_reads[] = { 8666 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8667 MockRead("hello world"), 8668 MockRead(ASYNC, OK), 8669 }; 8670 StaticSocketDataProvider second_data( 8671 data_reads, arraysize(data_reads), NULL, 0); 8672 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8673 8674 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8675 8676 base::WeakPtr<HttpServerProperties> http_server_properties = 8677 session->http_server_properties(); 8678 const int kRestrictedAlternatePort = 80; 8679 http_server_properties->SetAlternateProtocol( 8680 HostPortPair::FromURL(unrestricted_port_request.url), 8681 kRestrictedAlternatePort, 8682 AlternateProtocolFromNextProto(GetParam())); 8683 8684 scoped_ptr<HttpTransaction> trans( 8685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8686 TestCompletionCallback callback; 8687 8688 int rv = trans->Start( 8689 &unrestricted_port_request, callback.callback(), BoundNetLog()); 8690 EXPECT_EQ(ERR_IO_PENDING, rv); 8691 // Valid change to restricted port should pass. 8692 EXPECT_EQ(OK, callback.WaitForResult()); 8693 } 8694 8695 TEST_P(HttpNetworkTransactionTest, 8696 AlternateProtocolPortUnrestrictedAllowed2) { 8697 // Ensure that we're not allowed to redirect traffic via an alternate 8698 // protocol to an unrestricted (port >= 1024) when the original traffic was 8699 // on a restricted port (port < 1024). Ensure that we can redirect in all 8700 // other cases. 8701 session_deps_.use_alternate_protocols = true; 8702 8703 HttpRequestInfo unrestricted_port_request; 8704 unrestricted_port_request.method = "GET"; 8705 unrestricted_port_request.url = GURL("http://www.google.com:1024/"); 8706 unrestricted_port_request.load_flags = 0; 8707 8708 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 8709 StaticSocketDataProvider first_data; 8710 first_data.set_connect_data(mock_connect); 8711 session_deps_.socket_factory->AddSocketDataProvider(&first_data); 8712 8713 MockRead data_reads[] = { 8714 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8715 MockRead("hello world"), 8716 MockRead(ASYNC, OK), 8717 }; 8718 StaticSocketDataProvider second_data( 8719 data_reads, arraysize(data_reads), NULL, 0); 8720 session_deps_.socket_factory->AddSocketDataProvider(&second_data); 8721 8722 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8723 8724 base::WeakPtr<HttpServerProperties> http_server_properties = 8725 session->http_server_properties(); 8726 const int kUnrestrictedAlternatePort = 1024; 8727 http_server_properties->SetAlternateProtocol( 8728 HostPortPair::FromURL(unrestricted_port_request.url), 8729 kUnrestrictedAlternatePort, 8730 AlternateProtocolFromNextProto(GetParam())); 8731 8732 scoped_ptr<HttpTransaction> trans( 8733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8734 TestCompletionCallback callback; 8735 8736 int rv = trans->Start( 8737 &unrestricted_port_request, callback.callback(), BoundNetLog()); 8738 EXPECT_EQ(ERR_IO_PENDING, rv); 8739 // Valid change to an unrestricted port should pass. 8740 EXPECT_EQ(OK, callback.WaitForResult()); 8741 } 8742 8743 TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) { 8744 // Ensure that we're not allowed to redirect traffic via an alternate 8745 // protocol to an unsafe port, and that we resume the second 8746 // HttpStreamFactoryImpl::Job once the alternate protocol request fails. 8747 session_deps_.use_alternate_protocols = true; 8748 8749 HttpRequestInfo request; 8750 request.method = "GET"; 8751 request.url = GURL("http://www.google.com/"); 8752 request.load_flags = 0; 8753 8754 // The alternate protocol request will error out before we attempt to connect, 8755 // so only the standard HTTP request will try to connect. 8756 MockRead data_reads[] = { 8757 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 8758 MockRead("hello world"), 8759 MockRead(ASYNC, OK), 8760 }; 8761 StaticSocketDataProvider data( 8762 data_reads, arraysize(data_reads), NULL, 0); 8763 session_deps_.socket_factory->AddSocketDataProvider(&data); 8764 8765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8766 8767 base::WeakPtr<HttpServerProperties> http_server_properties = 8768 session->http_server_properties(); 8769 const int kUnsafePort = 7; 8770 http_server_properties->SetAlternateProtocol( 8771 HostPortPair::FromURL(request.url), 8772 kUnsafePort, 8773 AlternateProtocolFromNextProto(GetParam())); 8774 8775 scoped_ptr<HttpTransaction> trans( 8776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8777 TestCompletionCallback callback; 8778 8779 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8780 EXPECT_EQ(ERR_IO_PENDING, rv); 8781 // The HTTP request should succeed. 8782 EXPECT_EQ(OK, callback.WaitForResult()); 8783 8784 // Disable alternate protocol before the asserts. 8785 // HttpStreamFactory::set_use_alternate_protocols(false); 8786 8787 const HttpResponseInfo* response = trans->GetResponseInfo(); 8788 ASSERT_TRUE(response != NULL); 8789 ASSERT_TRUE(response->headers.get() != NULL); 8790 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8791 8792 std::string response_data; 8793 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8794 EXPECT_EQ("hello world", response_data); 8795 } 8796 8797 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) { 8798 session_deps_.use_alternate_protocols = true; 8799 session_deps_.next_protos = SpdyNextProtos(); 8800 8801 HttpRequestInfo request; 8802 request.method = "GET"; 8803 request.url = GURL("http://www.google.com/"); 8804 request.load_flags = 0; 8805 8806 std::string alternate_protocol_http_header = 8807 GetAlternateProtocolHttpHeader(); 8808 8809 MockRead data_reads[] = { 8810 MockRead("HTTP/1.1 200 OK\r\n"), 8811 MockRead(alternate_protocol_http_header.c_str()), 8812 MockRead("hello world"), 8813 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8814 MockRead(ASYNC, OK) 8815 }; 8816 8817 StaticSocketDataProvider first_transaction( 8818 data_reads, arraysize(data_reads), NULL, 0); 8819 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8820 8821 SSLSocketDataProvider ssl(ASYNC, OK); 8822 ssl.SetNextProto(GetParam()); 8823 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8824 8825 scoped_ptr<SpdyFrame> req( 8826 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8827 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 8828 8829 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8830 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8831 MockRead spdy_reads[] = { 8832 CreateMockRead(*resp), 8833 CreateMockRead(*data), 8834 MockRead(ASYNC, 0, 0), 8835 }; 8836 8837 DelayedSocketData spdy_data( 8838 1, // wait for one write to finish before reading. 8839 spdy_reads, arraysize(spdy_reads), 8840 spdy_writes, arraysize(spdy_writes)); 8841 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8842 8843 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8844 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 8845 NULL, 0, NULL, 0); 8846 hanging_non_alternate_protocol_socket.set_connect_data( 8847 never_finishing_connect); 8848 session_deps_.socket_factory->AddSocketDataProvider( 8849 &hanging_non_alternate_protocol_socket); 8850 8851 TestCompletionCallback callback; 8852 8853 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8854 scoped_ptr<HttpTransaction> trans( 8855 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8856 8857 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8858 EXPECT_EQ(ERR_IO_PENDING, rv); 8859 EXPECT_EQ(OK, callback.WaitForResult()); 8860 8861 const HttpResponseInfo* response = trans->GetResponseInfo(); 8862 ASSERT_TRUE(response != NULL); 8863 ASSERT_TRUE(response->headers.get() != NULL); 8864 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8865 8866 std::string response_data; 8867 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8868 EXPECT_EQ("hello world", response_data); 8869 8870 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 8871 8872 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 8873 EXPECT_EQ(ERR_IO_PENDING, rv); 8874 EXPECT_EQ(OK, callback.WaitForResult()); 8875 8876 response = trans->GetResponseInfo(); 8877 ASSERT_TRUE(response != NULL); 8878 ASSERT_TRUE(response->headers.get() != NULL); 8879 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8880 EXPECT_TRUE(response->was_fetched_via_spdy); 8881 EXPECT_TRUE(response->was_npn_negotiated); 8882 8883 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 8884 EXPECT_EQ("hello!", response_data); 8885 } 8886 8887 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) { 8888 session_deps_.use_alternate_protocols = true; 8889 session_deps_.next_protos = SpdyNextProtos(); 8890 8891 HttpRequestInfo request; 8892 request.method = "GET"; 8893 request.url = GURL("http://www.google.com/"); 8894 request.load_flags = 0; 8895 8896 std::string alternate_protocol_http_header = 8897 GetAlternateProtocolHttpHeader(); 8898 8899 MockRead data_reads[] = { 8900 MockRead("HTTP/1.1 200 OK\r\n"), 8901 MockRead(alternate_protocol_http_header.c_str()), 8902 MockRead("hello world"), 8903 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 8904 MockRead(ASYNC, OK), 8905 }; 8906 8907 StaticSocketDataProvider first_transaction( 8908 data_reads, arraysize(data_reads), NULL, 0); 8909 // Socket 1 is the HTTP transaction with the Alternate-Protocol header. 8910 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 8911 8912 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 8913 StaticSocketDataProvider hanging_socket( 8914 NULL, 0, NULL, 0); 8915 hanging_socket.set_connect_data(never_finishing_connect); 8916 // Socket 2 and 3 are the hanging Alternate-Protocol and 8917 // non-Alternate-Protocol jobs from the 2nd transaction. 8918 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8919 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8920 8921 SSLSocketDataProvider ssl(ASYNC, OK); 8922 ssl.SetNextProto(GetParam()); 8923 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8924 8925 scoped_ptr<SpdyFrame> req1( 8926 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8927 scoped_ptr<SpdyFrame> req2( 8928 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 8929 MockWrite spdy_writes[] = { 8930 CreateMockWrite(*req1), 8931 CreateMockWrite(*req2), 8932 }; 8933 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8934 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8935 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 8936 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 8937 MockRead spdy_reads[] = { 8938 CreateMockRead(*resp1), 8939 CreateMockRead(*data1), 8940 CreateMockRead(*resp2), 8941 CreateMockRead(*data2), 8942 MockRead(ASYNC, 0, 0), 8943 }; 8944 8945 DelayedSocketData spdy_data( 8946 2, // wait for writes to finish before reading. 8947 spdy_reads, arraysize(spdy_reads), 8948 spdy_writes, arraysize(spdy_writes)); 8949 // Socket 4 is the successful Alternate-Protocol for transaction 3. 8950 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 8951 8952 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3. 8953 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket); 8954 8955 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 8956 TestCompletionCallback callback1; 8957 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 8958 8959 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog()); 8960 EXPECT_EQ(ERR_IO_PENDING, rv); 8961 EXPECT_EQ(OK, callback1.WaitForResult()); 8962 8963 const HttpResponseInfo* response = trans1.GetResponseInfo(); 8964 ASSERT_TRUE(response != NULL); 8965 ASSERT_TRUE(response->headers.get() != NULL); 8966 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8967 8968 std::string response_data; 8969 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 8970 EXPECT_EQ("hello world", response_data); 8971 8972 TestCompletionCallback callback2; 8973 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 8974 rv = trans2.Start(&request, callback2.callback(), BoundNetLog()); 8975 EXPECT_EQ(ERR_IO_PENDING, rv); 8976 8977 TestCompletionCallback callback3; 8978 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get()); 8979 rv = trans3.Start(&request, callback3.callback(), BoundNetLog()); 8980 EXPECT_EQ(ERR_IO_PENDING, rv); 8981 8982 EXPECT_EQ(OK, callback2.WaitForResult()); 8983 EXPECT_EQ(OK, callback3.WaitForResult()); 8984 8985 response = trans2.GetResponseInfo(); 8986 ASSERT_TRUE(response != NULL); 8987 ASSERT_TRUE(response->headers.get() != NULL); 8988 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8989 EXPECT_TRUE(response->was_fetched_via_spdy); 8990 EXPECT_TRUE(response->was_npn_negotiated); 8991 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 8992 EXPECT_EQ("hello!", response_data); 8993 8994 response = trans3.GetResponseInfo(); 8995 ASSERT_TRUE(response != NULL); 8996 ASSERT_TRUE(response->headers.get() != NULL); 8997 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 8998 EXPECT_TRUE(response->was_fetched_via_spdy); 8999 EXPECT_TRUE(response->was_npn_negotiated); 9000 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data)); 9001 EXPECT_EQ("hello!", response_data); 9002 } 9003 9004 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) { 9005 session_deps_.use_alternate_protocols = true; 9006 session_deps_.next_protos = SpdyNextProtos(); 9007 9008 HttpRequestInfo request; 9009 request.method = "GET"; 9010 request.url = GURL("http://www.google.com/"); 9011 request.load_flags = 0; 9012 9013 std::string alternate_protocol_http_header = 9014 GetAlternateProtocolHttpHeader(); 9015 9016 MockRead data_reads[] = { 9017 MockRead("HTTP/1.1 200 OK\r\n"), 9018 MockRead(alternate_protocol_http_header.c_str()), 9019 MockRead("hello world"), 9020 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 9021 MockRead(ASYNC, OK), 9022 }; 9023 9024 StaticSocketDataProvider first_transaction( 9025 data_reads, arraysize(data_reads), NULL, 0); 9026 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9027 9028 SSLSocketDataProvider ssl(ASYNC, OK); 9029 ssl.SetNextProto(GetParam()); 9030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9031 9032 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 9033 StaticSocketDataProvider hanging_alternate_protocol_socket( 9034 NULL, 0, NULL, 0); 9035 hanging_alternate_protocol_socket.set_connect_data( 9036 never_finishing_connect); 9037 session_deps_.socket_factory->AddSocketDataProvider( 9038 &hanging_alternate_protocol_socket); 9039 9040 // 2nd request is just a copy of the first one, over HTTP again. 9041 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9042 9043 TestCompletionCallback callback; 9044 9045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9046 scoped_ptr<HttpTransaction> trans( 9047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9048 9049 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9050 EXPECT_EQ(ERR_IO_PENDING, rv); 9051 EXPECT_EQ(OK, callback.WaitForResult()); 9052 9053 const HttpResponseInfo* response = trans->GetResponseInfo(); 9054 ASSERT_TRUE(response != NULL); 9055 ASSERT_TRUE(response->headers.get() != NULL); 9056 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9057 9058 std::string response_data; 9059 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9060 EXPECT_EQ("hello world", response_data); 9061 9062 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9063 9064 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9065 EXPECT_EQ(ERR_IO_PENDING, rv); 9066 EXPECT_EQ(OK, callback.WaitForResult()); 9067 9068 response = trans->GetResponseInfo(); 9069 ASSERT_TRUE(response != NULL); 9070 ASSERT_TRUE(response->headers.get() != NULL); 9071 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9072 EXPECT_FALSE(response->was_fetched_via_spdy); 9073 EXPECT_FALSE(response->was_npn_negotiated); 9074 9075 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9076 EXPECT_EQ("hello world", response_data); 9077 } 9078 9079 class CapturingProxyResolver : public ProxyResolver { 9080 public: 9081 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {} 9082 virtual ~CapturingProxyResolver() {} 9083 9084 virtual int GetProxyForURL(const GURL& url, 9085 ProxyInfo* results, 9086 const CompletionCallback& callback, 9087 RequestHandle* request, 9088 const BoundNetLog& net_log) OVERRIDE { 9089 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, 9090 HostPortPair("myproxy", 80)); 9091 results->UseProxyServer(proxy_server); 9092 resolved_.push_back(url); 9093 return OK; 9094 } 9095 9096 virtual void CancelRequest(RequestHandle request) OVERRIDE { 9097 NOTREACHED(); 9098 } 9099 9100 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE { 9101 NOTREACHED(); 9102 return LOAD_STATE_IDLE; 9103 } 9104 9105 virtual void CancelSetPacScript() OVERRIDE { 9106 NOTREACHED(); 9107 } 9108 9109 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&, 9110 const CompletionCallback& /*callback*/) OVERRIDE { 9111 return OK; 9112 } 9113 9114 const std::vector<GURL>& resolved() const { return resolved_; } 9115 9116 private: 9117 std::vector<GURL> resolved_; 9118 9119 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver); 9120 }; 9121 9122 TEST_P(HttpNetworkTransactionTest, 9123 UseAlternateProtocolForTunneledNpnSpdy) { 9124 session_deps_.use_alternate_protocols = true; 9125 session_deps_.next_protos = SpdyNextProtos(); 9126 9127 ProxyConfig proxy_config; 9128 proxy_config.set_auto_detect(true); 9129 proxy_config.set_pac_url(GURL("http://fooproxyurl")); 9130 9131 CapturingProxyResolver* capturing_proxy_resolver = 9132 new CapturingProxyResolver(); 9133 session_deps_.proxy_service.reset(new ProxyService( 9134 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver, 9135 NULL)); 9136 CapturingNetLog net_log; 9137 session_deps_.net_log = &net_log; 9138 9139 HttpRequestInfo request; 9140 request.method = "GET"; 9141 request.url = GURL("http://www.google.com/"); 9142 request.load_flags = 0; 9143 9144 std::string alternate_protocol_http_header = 9145 GetAlternateProtocolHttpHeader(); 9146 9147 MockRead data_reads[] = { 9148 MockRead("HTTP/1.1 200 OK\r\n"), 9149 MockRead(alternate_protocol_http_header.c_str()), 9150 MockRead("hello world"), 9151 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 9152 MockRead(ASYNC, OK), 9153 }; 9154 9155 StaticSocketDataProvider first_transaction( 9156 data_reads, arraysize(data_reads), NULL, 0); 9157 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9158 9159 SSLSocketDataProvider ssl(ASYNC, OK); 9160 ssl.SetNextProto(GetParam()); 9161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9162 9163 scoped_ptr<SpdyFrame> req( 9164 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 9165 MockWrite spdy_writes[] = { 9166 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 9167 "Host: www.google.com\r\n" 9168 "Proxy-Connection: keep-alive\r\n\r\n"), // 0 9169 CreateMockWrite(*req), // 3 9170 }; 9171 9172 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 9173 9174 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 9175 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 9176 MockRead spdy_reads[] = { 9177 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1 9178 CreateMockRead(*resp.get(), 4), // 2, 4 9179 CreateMockRead(*data.get(), 4), // 5 9180 MockRead(ASYNC, 0, 0, 4), // 6 9181 }; 9182 9183 OrderedSocketData spdy_data( 9184 spdy_reads, arraysize(spdy_reads), 9185 spdy_writes, arraysize(spdy_writes)); 9186 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 9187 9188 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 9189 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 9190 NULL, 0, NULL, 0); 9191 hanging_non_alternate_protocol_socket.set_connect_data( 9192 never_finishing_connect); 9193 session_deps_.socket_factory->AddSocketDataProvider( 9194 &hanging_non_alternate_protocol_socket); 9195 9196 TestCompletionCallback callback; 9197 9198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9199 scoped_ptr<HttpTransaction> trans( 9200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9201 9202 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9203 EXPECT_EQ(ERR_IO_PENDING, rv); 9204 EXPECT_EQ(OK, callback.WaitForResult()); 9205 9206 const HttpResponseInfo* response = trans->GetResponseInfo(); 9207 ASSERT_TRUE(response != NULL); 9208 ASSERT_TRUE(response->headers.get() != NULL); 9209 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9210 EXPECT_FALSE(response->was_fetched_via_spdy); 9211 EXPECT_FALSE(response->was_npn_negotiated); 9212 9213 std::string response_data; 9214 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9215 EXPECT_EQ("hello world", response_data); 9216 9217 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9218 9219 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9220 EXPECT_EQ(ERR_IO_PENDING, rv); 9221 EXPECT_EQ(OK, callback.WaitForResult()); 9222 9223 response = trans->GetResponseInfo(); 9224 ASSERT_TRUE(response != NULL); 9225 ASSERT_TRUE(response->headers.get() != NULL); 9226 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9227 EXPECT_TRUE(response->was_fetched_via_spdy); 9228 EXPECT_TRUE(response->was_npn_negotiated); 9229 9230 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9231 EXPECT_EQ("hello!", response_data); 9232 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size()); 9233 EXPECT_EQ("http://www.google.com/", 9234 capturing_proxy_resolver->resolved()[0].spec()); 9235 EXPECT_EQ("https://www.google.com/", 9236 capturing_proxy_resolver->resolved()[1].spec()); 9237 9238 LoadTimingInfo load_timing_info; 9239 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 9240 TestLoadTimingNotReusedWithPac(load_timing_info, 9241 CONNECT_TIMING_HAS_SSL_TIMES); 9242 } 9243 9244 TEST_P(HttpNetworkTransactionTest, 9245 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) { 9246 session_deps_.use_alternate_protocols = true; 9247 session_deps_.next_protos = SpdyNextProtos(); 9248 9249 HttpRequestInfo request; 9250 request.method = "GET"; 9251 request.url = GURL("http://www.google.com/"); 9252 request.load_flags = 0; 9253 9254 std::string alternate_protocol_http_header = 9255 GetAlternateProtocolHttpHeader(); 9256 9257 MockRead data_reads[] = { 9258 MockRead("HTTP/1.1 200 OK\r\n"), 9259 MockRead(alternate_protocol_http_header.c_str()), 9260 MockRead("hello world"), 9261 MockRead(ASYNC, OK), 9262 }; 9263 9264 StaticSocketDataProvider first_transaction( 9265 data_reads, arraysize(data_reads), NULL, 0); 9266 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); 9267 9268 SSLSocketDataProvider ssl(ASYNC, OK); 9269 ssl.SetNextProto(GetParam()); 9270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9271 9272 scoped_ptr<SpdyFrame> req( 9273 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 9274 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 9275 9276 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 9277 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 9278 MockRead spdy_reads[] = { 9279 CreateMockRead(*resp), 9280 CreateMockRead(*data), 9281 MockRead(ASYNC, 0, 0), 9282 }; 9283 9284 DelayedSocketData spdy_data( 9285 1, // wait for one write to finish before reading. 9286 spdy_reads, arraysize(spdy_reads), 9287 spdy_writes, arraysize(spdy_writes)); 9288 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 9289 9290 TestCompletionCallback callback; 9291 9292 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9293 9294 scoped_ptr<HttpTransaction> trans( 9295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9296 9297 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9298 EXPECT_EQ(ERR_IO_PENDING, rv); 9299 EXPECT_EQ(OK, callback.WaitForResult()); 9300 9301 const HttpResponseInfo* response = trans->GetResponseInfo(); 9302 ASSERT_TRUE(response != NULL); 9303 ASSERT_TRUE(response->headers.get() != NULL); 9304 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9305 9306 std::string response_data; 9307 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9308 EXPECT_EQ("hello world", response_data); 9309 9310 // Set up an initial SpdySession in the pool to reuse. 9311 HostPortPair host_port_pair("www.google.com", 443); 9312 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 9313 PRIVACY_MODE_DISABLED); 9314 base::WeakPtr<SpdySession> spdy_session = 9315 CreateSecureSpdySession(session, key, BoundNetLog()); 9316 9317 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9318 9319 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9320 EXPECT_EQ(ERR_IO_PENDING, rv); 9321 EXPECT_EQ(OK, callback.WaitForResult()); 9322 9323 response = trans->GetResponseInfo(); 9324 ASSERT_TRUE(response != NULL); 9325 ASSERT_TRUE(response->headers.get() != NULL); 9326 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9327 EXPECT_TRUE(response->was_fetched_via_spdy); 9328 EXPECT_TRUE(response->was_npn_negotiated); 9329 9330 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9331 EXPECT_EQ("hello!", response_data); 9332 } 9333 9334 // GenerateAuthToken is a mighty big test. 9335 // It tests all permutation of GenerateAuthToken behavior: 9336 // - Synchronous and Asynchronous completion. 9337 // - OK or error on completion. 9338 // - Direct connection, non-authenticating proxy, and authenticating proxy. 9339 // - HTTP or HTTPS backend (to include proxy tunneling). 9340 // - Non-authenticating and authenticating backend. 9341 // 9342 // In all, there are 44 reasonable permuations (for example, if there are 9343 // problems generating an auth token for an authenticating proxy, we don't 9344 // need to test all permutations of the backend server). 9345 // 9346 // The test proceeds by going over each of the configuration cases, and 9347 // potentially running up to three rounds in each of the tests. The TestConfig 9348 // specifies both the configuration for the test as well as the expectations 9349 // for the results. 9350 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) { 9351 static const char kServer[] = "http://www.example.com"; 9352 static const char kSecureServer[] = "https://www.example.com"; 9353 static const char kProxy[] = "myproxy:70"; 9354 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS; 9355 9356 enum AuthTiming { 9357 AUTH_NONE, 9358 AUTH_SYNC, 9359 AUTH_ASYNC, 9360 }; 9361 9362 const MockWrite kGet( 9363 "GET / HTTP/1.1\r\n" 9364 "Host: www.example.com\r\n" 9365 "Connection: keep-alive\r\n\r\n"); 9366 const MockWrite kGetProxy( 9367 "GET http://www.example.com/ HTTP/1.1\r\n" 9368 "Host: www.example.com\r\n" 9369 "Proxy-Connection: keep-alive\r\n\r\n"); 9370 const MockWrite kGetAuth( 9371 "GET / HTTP/1.1\r\n" 9372 "Host: www.example.com\r\n" 9373 "Connection: keep-alive\r\n" 9374 "Authorization: auth_token\r\n\r\n"); 9375 const MockWrite kGetProxyAuth( 9376 "GET http://www.example.com/ HTTP/1.1\r\n" 9377 "Host: www.example.com\r\n" 9378 "Proxy-Connection: keep-alive\r\n" 9379 "Proxy-Authorization: auth_token\r\n\r\n"); 9380 const MockWrite kGetAuthThroughProxy( 9381 "GET http://www.example.com/ HTTP/1.1\r\n" 9382 "Host: www.example.com\r\n" 9383 "Proxy-Connection: keep-alive\r\n" 9384 "Authorization: auth_token\r\n\r\n"); 9385 const MockWrite kGetAuthWithProxyAuth( 9386 "GET http://www.example.com/ HTTP/1.1\r\n" 9387 "Host: www.example.com\r\n" 9388 "Proxy-Connection: keep-alive\r\n" 9389 "Proxy-Authorization: auth_token\r\n" 9390 "Authorization: auth_token\r\n\r\n"); 9391 const MockWrite kConnect( 9392 "CONNECT www.example.com:443 HTTP/1.1\r\n" 9393 "Host: www.example.com\r\n" 9394 "Proxy-Connection: keep-alive\r\n\r\n"); 9395 const MockWrite kConnectProxyAuth( 9396 "CONNECT www.example.com:443 HTTP/1.1\r\n" 9397 "Host: www.example.com\r\n" 9398 "Proxy-Connection: keep-alive\r\n" 9399 "Proxy-Authorization: auth_token\r\n\r\n"); 9400 9401 const MockRead kSuccess( 9402 "HTTP/1.1 200 OK\r\n" 9403 "Content-Type: text/html; charset=iso-8859-1\r\n" 9404 "Content-Length: 3\r\n\r\n" 9405 "Yes"); 9406 const MockRead kFailure( 9407 "Should not be called."); 9408 const MockRead kServerChallenge( 9409 "HTTP/1.1 401 Unauthorized\r\n" 9410 "WWW-Authenticate: Mock realm=server\r\n" 9411 "Content-Type: text/html; charset=iso-8859-1\r\n" 9412 "Content-Length: 14\r\n\r\n" 9413 "Unauthorized\r\n"); 9414 const MockRead kProxyChallenge( 9415 "HTTP/1.1 407 Unauthorized\r\n" 9416 "Proxy-Authenticate: Mock realm=proxy\r\n" 9417 "Proxy-Connection: close\r\n" 9418 "Content-Type: text/html; charset=iso-8859-1\r\n" 9419 "Content-Length: 14\r\n\r\n" 9420 "Unauthorized\r\n"); 9421 const MockRead kProxyConnected( 9422 "HTTP/1.1 200 Connection Established\r\n\r\n"); 9423 9424 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with 9425 // no constructors, but the C++ compiler on Windows warns about 9426 // unspecified data in compound literals. So, moved to using constructors, 9427 // and TestRound's created with the default constructor should not be used. 9428 struct TestRound { 9429 TestRound() 9430 : expected_rv(ERR_UNEXPECTED), 9431 extra_write(NULL), 9432 extra_read(NULL) { 9433 } 9434 TestRound(const MockWrite& write_arg, const MockRead& read_arg, 9435 int expected_rv_arg) 9436 : write(write_arg), 9437 read(read_arg), 9438 expected_rv(expected_rv_arg), 9439 extra_write(NULL), 9440 extra_read(NULL) { 9441 } 9442 TestRound(const MockWrite& write_arg, const MockRead& read_arg, 9443 int expected_rv_arg, const MockWrite* extra_write_arg, 9444 const MockRead* extra_read_arg) 9445 : write(write_arg), 9446 read(read_arg), 9447 expected_rv(expected_rv_arg), 9448 extra_write(extra_write_arg), 9449 extra_read(extra_read_arg) { 9450 } 9451 MockWrite write; 9452 MockRead read; 9453 int expected_rv; 9454 const MockWrite* extra_write; 9455 const MockRead* extra_read; 9456 }; 9457 9458 static const int kNoSSL = 500; 9459 9460 struct TestConfig { 9461 const char* proxy_url; 9462 AuthTiming proxy_auth_timing; 9463 int proxy_auth_rv; 9464 const char* server_url; 9465 AuthTiming server_auth_timing; 9466 int server_auth_rv; 9467 int num_auth_rounds; 9468 int first_ssl_round; 9469 TestRound rounds[3]; 9470 } test_configs[] = { 9471 // Non-authenticating HTTP server with a direct connection. 9472 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 9473 { TestRound(kGet, kSuccess, OK)}}, 9474 // Authenticating HTTP server with a direct connection. 9475 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 9476 { TestRound(kGet, kServerChallenge, OK), 9477 TestRound(kGetAuth, kSuccess, OK)}}, 9478 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 9479 { TestRound(kGet, kServerChallenge, OK), 9480 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9481 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 9482 { TestRound(kGet, kServerChallenge, OK), 9483 TestRound(kGetAuth, kSuccess, OK)}}, 9484 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 9485 { TestRound(kGet, kServerChallenge, OK), 9486 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9487 // Non-authenticating HTTP server through a non-authenticating proxy. 9488 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 9489 { TestRound(kGetProxy, kSuccess, OK)}}, 9490 // Authenticating HTTP server through a non-authenticating proxy. 9491 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 9492 { TestRound(kGetProxy, kServerChallenge, OK), 9493 TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 9494 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 9495 { TestRound(kGetProxy, kServerChallenge, OK), 9496 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 9497 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 9498 { TestRound(kGetProxy, kServerChallenge, OK), 9499 TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 9500 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 9501 { TestRound(kGetProxy, kServerChallenge, OK), 9502 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 9503 // Non-authenticating HTTP server through an authenticating proxy. 9504 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 9505 { TestRound(kGetProxy, kProxyChallenge, OK), 9506 TestRound(kGetProxyAuth, kSuccess, OK)}}, 9507 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 9508 { TestRound(kGetProxy, kProxyChallenge, OK), 9509 TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 9510 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 9511 { TestRound(kGetProxy, kProxyChallenge, OK), 9512 TestRound(kGetProxyAuth, kSuccess, OK)}}, 9513 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 9514 { TestRound(kGetProxy, kProxyChallenge, OK), 9515 TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 9516 // Authenticating HTTP server through an authenticating proxy. 9517 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 9518 { TestRound(kGetProxy, kProxyChallenge, OK), 9519 TestRound(kGetProxyAuth, kServerChallenge, OK), 9520 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9521 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 9522 { TestRound(kGetProxy, kProxyChallenge, OK), 9523 TestRound(kGetProxyAuth, kServerChallenge, OK), 9524 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9525 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 9526 { TestRound(kGetProxy, kProxyChallenge, OK), 9527 TestRound(kGetProxyAuth, kServerChallenge, OK), 9528 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9529 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 9530 { TestRound(kGetProxy, kProxyChallenge, OK), 9531 TestRound(kGetProxyAuth, kServerChallenge, OK), 9532 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9533 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 9534 { TestRound(kGetProxy, kProxyChallenge, OK), 9535 TestRound(kGetProxyAuth, kServerChallenge, OK), 9536 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9537 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 9538 { TestRound(kGetProxy, kProxyChallenge, OK), 9539 TestRound(kGetProxyAuth, kServerChallenge, OK), 9540 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9541 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 9542 { TestRound(kGetProxy, kProxyChallenge, OK), 9543 TestRound(kGetProxyAuth, kServerChallenge, OK), 9544 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 9545 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 9546 { TestRound(kGetProxy, kProxyChallenge, OK), 9547 TestRound(kGetProxyAuth, kServerChallenge, OK), 9548 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 9549 // Non-authenticating HTTPS server with a direct connection. 9550 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 9551 { TestRound(kGet, kSuccess, OK)}}, 9552 // Authenticating HTTPS server with a direct connection. 9553 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 9554 { TestRound(kGet, kServerChallenge, OK), 9555 TestRound(kGetAuth, kSuccess, OK)}}, 9556 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 9557 { TestRound(kGet, kServerChallenge, OK), 9558 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9559 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 9560 { TestRound(kGet, kServerChallenge, OK), 9561 TestRound(kGetAuth, kSuccess, OK)}}, 9562 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 9563 { TestRound(kGet, kServerChallenge, OK), 9564 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9565 // Non-authenticating HTTPS server with a non-authenticating proxy. 9566 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 9567 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}}, 9568 // Authenticating HTTPS server through a non-authenticating proxy. 9569 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 9570 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9571 TestRound(kGetAuth, kSuccess, OK)}}, 9572 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 9573 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9574 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9575 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 9576 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9577 TestRound(kGetAuth, kSuccess, OK)}}, 9578 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 9579 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 9580 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9581 // Non-Authenticating HTTPS server through an authenticating proxy. 9582 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 9583 { TestRound(kConnect, kProxyChallenge, OK), 9584 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 9585 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 9586 { TestRound(kConnect, kProxyChallenge, OK), 9587 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 9588 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 9589 { TestRound(kConnect, kProxyChallenge, OK), 9590 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 9591 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 9592 { TestRound(kConnect, kProxyChallenge, OK), 9593 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 9594 // Authenticating HTTPS server through an authenticating proxy. 9595 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 9596 { TestRound(kConnect, kProxyChallenge, OK), 9597 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9598 &kGet, &kServerChallenge), 9599 TestRound(kGetAuth, kSuccess, OK)}}, 9600 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 9601 { TestRound(kConnect, kProxyChallenge, OK), 9602 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9603 &kGet, &kServerChallenge), 9604 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9605 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 9606 { TestRound(kConnect, kProxyChallenge, OK), 9607 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9608 &kGet, &kServerChallenge), 9609 TestRound(kGetAuth, kSuccess, OK)}}, 9610 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 9611 { TestRound(kConnect, kProxyChallenge, OK), 9612 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9613 &kGet, &kServerChallenge), 9614 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9615 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 9616 { TestRound(kConnect, kProxyChallenge, OK), 9617 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9618 &kGet, &kServerChallenge), 9619 TestRound(kGetAuth, kSuccess, OK)}}, 9620 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 9621 { TestRound(kConnect, kProxyChallenge, OK), 9622 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9623 &kGet, &kServerChallenge), 9624 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9625 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 9626 { TestRound(kConnect, kProxyChallenge, OK), 9627 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9628 &kGet, &kServerChallenge), 9629 TestRound(kGetAuth, kSuccess, OK)}}, 9630 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 9631 { TestRound(kConnect, kProxyChallenge, OK), 9632 TestRound(kConnectProxyAuth, kProxyConnected, OK, 9633 &kGet, &kServerChallenge), 9634 TestRound(kGetAuth, kFailure, kAuthErr)}}, 9635 }; 9636 9637 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) { 9638 HttpAuthHandlerMock::Factory* auth_factory( 9639 new HttpAuthHandlerMock::Factory()); 9640 session_deps_.http_auth_handler_factory.reset(auth_factory); 9641 const TestConfig& test_config = test_configs[i]; 9642 9643 // Set up authentication handlers as necessary. 9644 if (test_config.proxy_auth_timing != AUTH_NONE) { 9645 for (int n = 0; n < 2; n++) { 9646 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9647 std::string auth_challenge = "Mock realm=proxy"; 9648 GURL origin(test_config.proxy_url); 9649 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), 9650 auth_challenge.end()); 9651 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY, 9652 origin, BoundNetLog()); 9653 auth_handler->SetGenerateExpectation( 9654 test_config.proxy_auth_timing == AUTH_ASYNC, 9655 test_config.proxy_auth_rv); 9656 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); 9657 } 9658 } 9659 if (test_config.server_auth_timing != AUTH_NONE) { 9660 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9661 std::string auth_challenge = "Mock realm=server"; 9662 GURL origin(test_config.server_url); 9663 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), 9664 auth_challenge.end()); 9665 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 9666 origin, BoundNetLog()); 9667 auth_handler->SetGenerateExpectation( 9668 test_config.server_auth_timing == AUTH_ASYNC, 9669 test_config.server_auth_rv); 9670 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); 9671 } 9672 if (test_config.proxy_url) { 9673 session_deps_.proxy_service.reset( 9674 ProxyService::CreateFixed(test_config.proxy_url)); 9675 } else { 9676 session_deps_.proxy_service.reset(ProxyService::CreateDirect()); 9677 } 9678 9679 HttpRequestInfo request; 9680 request.method = "GET"; 9681 request.url = GURL(test_config.server_url); 9682 request.load_flags = 0; 9683 9684 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session); 9686 9687 for (int round = 0; round < test_config.num_auth_rounds; ++round) { 9688 const TestRound& read_write_round = test_config.rounds[round]; 9689 9690 // Set up expected reads and writes. 9691 MockRead reads[2]; 9692 reads[0] = read_write_round.read; 9693 size_t length_reads = 1; 9694 if (read_write_round.extra_read) { 9695 reads[1] = *read_write_round.extra_read; 9696 length_reads = 2; 9697 } 9698 9699 MockWrite writes[2]; 9700 writes[0] = read_write_round.write; 9701 size_t length_writes = 1; 9702 if (read_write_round.extra_write) { 9703 writes[1] = *read_write_round.extra_write; 9704 length_writes = 2; 9705 } 9706 StaticSocketDataProvider data_provider( 9707 reads, length_reads, writes, length_writes); 9708 session_deps_.socket_factory->AddSocketDataProvider(&data_provider); 9709 9710 // Add an SSL sequence if necessary. 9711 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK); 9712 if (round >= test_config.first_ssl_round) 9713 session_deps_.socket_factory->AddSSLSocketDataProvider( 9714 &ssl_socket_data_provider); 9715 9716 // Start or restart the transaction. 9717 TestCompletionCallback callback; 9718 int rv; 9719 if (round == 0) { 9720 rv = trans.Start(&request, callback.callback(), BoundNetLog()); 9721 } else { 9722 rv = trans.RestartWithAuth( 9723 AuthCredentials(kFoo, kBar), callback.callback()); 9724 } 9725 if (rv == ERR_IO_PENDING) 9726 rv = callback.WaitForResult(); 9727 9728 // Compare results with expected data. 9729 EXPECT_EQ(read_write_round.expected_rv, rv); 9730 const HttpResponseInfo* response = trans.GetResponseInfo(); 9731 if (read_write_round.expected_rv == OK) { 9732 ASSERT_TRUE(response != NULL); 9733 } else { 9734 EXPECT_TRUE(response == NULL); 9735 EXPECT_EQ(round + 1, test_config.num_auth_rounds); 9736 continue; 9737 } 9738 if (round + 1 < test_config.num_auth_rounds) { 9739 EXPECT_FALSE(response->auth_challenge.get() == NULL); 9740 } else { 9741 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9742 } 9743 } 9744 } 9745 } 9746 9747 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) { 9748 // Do multi-round authentication and make sure it works correctly. 9749 HttpAuthHandlerMock::Factory* auth_factory( 9750 new HttpAuthHandlerMock::Factory()); 9751 session_deps_.http_auth_handler_factory.reset(auth_factory); 9752 session_deps_.proxy_service.reset(ProxyService::CreateDirect()); 9753 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1"); 9754 session_deps_.host_resolver->set_synchronous_mode(true); 9755 9756 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 9757 auth_handler->set_connection_based(true); 9758 std::string auth_challenge = "Mock realm=server"; 9759 GURL origin("http://www.example.com"); 9760 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), 9761 auth_challenge.end()); 9762 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 9763 origin, BoundNetLog()); 9764 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); 9765 9766 int rv = OK; 9767 const HttpResponseInfo* response = NULL; 9768 HttpRequestInfo request; 9769 request.method = "GET"; 9770 request.url = origin; 9771 request.load_flags = 0; 9772 9773 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9774 9775 // Use a TCP Socket Pool with only one connection per group. This is used 9776 // to validate that the TCP socket is not released to the pool between 9777 // each round of multi-round authentication. 9778 HttpNetworkSessionPeer session_peer(session); 9779 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP"); 9780 TransportClientSocketPool* transport_pool = new TransportClientSocketPool( 9781 50, // Max sockets for pool 9782 1, // Max sockets per group 9783 &transport_pool_histograms, 9784 session_deps_.host_resolver.get(), 9785 session_deps_.socket_factory.get(), 9786 session_deps_.net_log); 9787 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 9788 new MockClientSocketPoolManager); 9789 mock_pool_manager->SetTransportSocketPool(transport_pool); 9790 session_peer.SetClientSocketPoolManager( 9791 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 9792 9793 scoped_ptr<HttpTransaction> trans( 9794 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9795 TestCompletionCallback callback; 9796 9797 const MockWrite kGet( 9798 "GET / HTTP/1.1\r\n" 9799 "Host: www.example.com\r\n" 9800 "Connection: keep-alive\r\n\r\n"); 9801 const MockWrite kGetAuth( 9802 "GET / HTTP/1.1\r\n" 9803 "Host: www.example.com\r\n" 9804 "Connection: keep-alive\r\n" 9805 "Authorization: auth_token\r\n\r\n"); 9806 9807 const MockRead kServerChallenge( 9808 "HTTP/1.1 401 Unauthorized\r\n" 9809 "WWW-Authenticate: Mock realm=server\r\n" 9810 "Content-Type: text/html; charset=iso-8859-1\r\n" 9811 "Content-Length: 14\r\n\r\n" 9812 "Unauthorized\r\n"); 9813 const MockRead kSuccess( 9814 "HTTP/1.1 200 OK\r\n" 9815 "Content-Type: text/html; charset=iso-8859-1\r\n" 9816 "Content-Length: 3\r\n\r\n" 9817 "Yes"); 9818 9819 MockWrite writes[] = { 9820 // First round 9821 kGet, 9822 // Second round 9823 kGetAuth, 9824 // Third round 9825 kGetAuth, 9826 // Fourth round 9827 kGetAuth, 9828 // Competing request 9829 kGet, 9830 }; 9831 MockRead reads[] = { 9832 // First round 9833 kServerChallenge, 9834 // Second round 9835 kServerChallenge, 9836 // Third round 9837 kServerChallenge, 9838 // Fourth round 9839 kSuccess, 9840 // Competing response 9841 kSuccess, 9842 }; 9843 StaticSocketDataProvider data_provider(reads, arraysize(reads), 9844 writes, arraysize(writes)); 9845 session_deps_.socket_factory->AddSocketDataProvider(&data_provider); 9846 9847 const char* const kSocketGroup = "www.example.com:80"; 9848 9849 // First round of authentication. 9850 auth_handler->SetGenerateExpectation(false, OK); 9851 rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9852 if (rv == ERR_IO_PENDING) 9853 rv = callback.WaitForResult(); 9854 EXPECT_EQ(OK, rv); 9855 response = trans->GetResponseInfo(); 9856 ASSERT_TRUE(response != NULL); 9857 EXPECT_FALSE(response->auth_challenge.get() == NULL); 9858 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9859 9860 // In between rounds, another request comes in for the same domain. 9861 // It should not be able to grab the TCP socket that trans has already 9862 // claimed. 9863 scoped_ptr<HttpTransaction> trans_compete( 9864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9865 TestCompletionCallback callback_compete; 9866 rv = trans_compete->Start( 9867 &request, callback_compete.callback(), BoundNetLog()); 9868 EXPECT_EQ(ERR_IO_PENDING, rv); 9869 // callback_compete.WaitForResult at this point would stall forever, 9870 // since the HttpNetworkTransaction does not release the request back to 9871 // the pool until after authentication completes. 9872 9873 // Second round of authentication. 9874 auth_handler->SetGenerateExpectation(false, OK); 9875 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); 9876 if (rv == ERR_IO_PENDING) 9877 rv = callback.WaitForResult(); 9878 EXPECT_EQ(OK, rv); 9879 response = trans->GetResponseInfo(); 9880 ASSERT_TRUE(response != NULL); 9881 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9882 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9883 9884 // Third round of authentication. 9885 auth_handler->SetGenerateExpectation(false, OK); 9886 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); 9887 if (rv == ERR_IO_PENDING) 9888 rv = callback.WaitForResult(); 9889 EXPECT_EQ(OK, rv); 9890 response = trans->GetResponseInfo(); 9891 ASSERT_TRUE(response != NULL); 9892 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9893 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9894 9895 // Fourth round of authentication, which completes successfully. 9896 auth_handler->SetGenerateExpectation(false, OK); 9897 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); 9898 if (rv == ERR_IO_PENDING) 9899 rv = callback.WaitForResult(); 9900 EXPECT_EQ(OK, rv); 9901 response = trans->GetResponseInfo(); 9902 ASSERT_TRUE(response != NULL); 9903 EXPECT_TRUE(response->auth_challenge.get() == NULL); 9904 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9905 9906 // Read the body since the fourth round was successful. This will also 9907 // release the socket back to the pool. 9908 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50)); 9909 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 9910 if (rv == ERR_IO_PENDING) 9911 rv = callback.WaitForResult(); 9912 EXPECT_EQ(3, rv); 9913 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); 9914 EXPECT_EQ(0, rv); 9915 // There are still 0 idle sockets, since the trans_compete transaction 9916 // will be handed it immediately after trans releases it to the group. 9917 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9918 9919 // The competing request can now finish. Wait for the headers and then 9920 // read the body. 9921 rv = callback_compete.WaitForResult(); 9922 EXPECT_EQ(OK, rv); 9923 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); 9924 if (rv == ERR_IO_PENDING) 9925 rv = callback.WaitForResult(); 9926 EXPECT_EQ(3, rv); 9927 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); 9928 EXPECT_EQ(0, rv); 9929 9930 // Finally, the socket is released to the group. 9931 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 9932 } 9933 9934 // This tests the case that a request is issued via http instead of spdy after 9935 // npn is negotiated. 9936 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) { 9937 session_deps_.use_alternate_protocols = true; 9938 NextProtoVector next_protos; 9939 next_protos.push_back(kProtoHTTP11); 9940 session_deps_.next_protos = next_protos; 9941 9942 HttpRequestInfo request; 9943 request.method = "GET"; 9944 request.url = GURL("https://www.google.com/"); 9945 request.load_flags = 0; 9946 9947 MockWrite data_writes[] = { 9948 MockWrite("GET / HTTP/1.1\r\n" 9949 "Host: www.google.com\r\n" 9950 "Connection: keep-alive\r\n\r\n"), 9951 }; 9952 9953 std::string alternate_protocol_http_header = 9954 GetAlternateProtocolHttpHeader(); 9955 9956 MockRead data_reads[] = { 9957 MockRead("HTTP/1.1 200 OK\r\n"), 9958 MockRead(alternate_protocol_http_header.c_str()), 9959 MockRead("hello world"), 9960 MockRead(SYNCHRONOUS, OK), 9961 }; 9962 9963 SSLSocketDataProvider ssl(ASYNC, OK); 9964 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 9965 ssl.next_proto = "http/1.1"; 9966 ssl.protocol_negotiated = kProtoHTTP11; 9967 9968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 9969 9970 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 9971 data_writes, arraysize(data_writes)); 9972 session_deps_.socket_factory->AddSocketDataProvider(&data); 9973 9974 TestCompletionCallback callback; 9975 9976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 9977 scoped_ptr<HttpTransaction> trans( 9978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 9979 9980 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 9981 9982 EXPECT_EQ(ERR_IO_PENDING, rv); 9983 EXPECT_EQ(OK, callback.WaitForResult()); 9984 9985 const HttpResponseInfo* response = trans->GetResponseInfo(); 9986 ASSERT_TRUE(response != NULL); 9987 ASSERT_TRUE(response->headers.get() != NULL); 9988 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 9989 9990 std::string response_data; 9991 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 9992 EXPECT_EQ("hello world", response_data); 9993 9994 EXPECT_FALSE(response->was_fetched_via_spdy); 9995 EXPECT_TRUE(response->was_npn_negotiated); 9996 } 9997 9998 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) { 9999 // Simulate the SSL handshake completing with an NPN negotiation 10000 // followed by an immediate server closing of the socket. 10001 // Fix crash: http://crbug.com/46369 10002 session_deps_.use_alternate_protocols = true; 10003 session_deps_.next_protos = SpdyNextProtos(); 10004 10005 HttpRequestInfo request; 10006 request.method = "GET"; 10007 request.url = GURL("https://www.google.com/"); 10008 request.load_flags = 0; 10009 10010 SSLSocketDataProvider ssl(ASYNC, OK); 10011 ssl.SetNextProto(GetParam()); 10012 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10013 10014 scoped_ptr<SpdyFrame> req( 10015 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 10016 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 10017 10018 MockRead spdy_reads[] = { 10019 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately. 10020 }; 10021 10022 DelayedSocketData spdy_data( 10023 0, // don't wait in this case, immediate hangup. 10024 spdy_reads, arraysize(spdy_reads), 10025 spdy_writes, arraysize(spdy_writes)); 10026 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10027 10028 TestCompletionCallback callback; 10029 10030 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10031 scoped_ptr<HttpTransaction> trans( 10032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10033 10034 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 10035 EXPECT_EQ(ERR_IO_PENDING, rv); 10036 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); 10037 } 10038 10039 // A subclass of HttpAuthHandlerMock that records the request URL when 10040 // it gets it. This is needed since the auth handler may get destroyed 10041 // before we get a chance to query it. 10042 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock { 10043 public: 10044 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {} 10045 10046 virtual ~UrlRecordingHttpAuthHandlerMock() {} 10047 10048 protected: 10049 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials, 10050 const HttpRequestInfo* request, 10051 const CompletionCallback& callback, 10052 std::string* auth_token) OVERRIDE { 10053 *url_ = request->url; 10054 return HttpAuthHandlerMock::GenerateAuthTokenImpl( 10055 credentials, request, callback, auth_token); 10056 } 10057 10058 private: 10059 GURL* url_; 10060 }; 10061 10062 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { 10063 // This test ensures that the URL passed into the proxy is upgraded 10064 // to https when doing an Alternate Protocol upgrade. 10065 session_deps_.use_alternate_protocols = true; 10066 session_deps_.next_protos = SpdyNextProtos(); 10067 10068 session_deps_.proxy_service.reset( 10069 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 10070 CapturingNetLog net_log; 10071 session_deps_.net_log = &net_log; 10072 GURL request_url; 10073 { 10074 HttpAuthHandlerMock::Factory* auth_factory = 10075 new HttpAuthHandlerMock::Factory(); 10076 UrlRecordingHttpAuthHandlerMock* auth_handler = 10077 new UrlRecordingHttpAuthHandlerMock(&request_url); 10078 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); 10079 auth_factory->set_do_init_from_challenge(true); 10080 session_deps_.http_auth_handler_factory.reset(auth_factory); 10081 } 10082 10083 HttpRequestInfo request; 10084 request.method = "GET"; 10085 request.url = GURL("http://www.google.com"); 10086 request.load_flags = 0; 10087 10088 // First round goes unauthenticated through the proxy. 10089 MockWrite data_writes_1[] = { 10090 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 10091 "Host: www.google.com\r\n" 10092 "Proxy-Connection: keep-alive\r\n" 10093 "\r\n"), 10094 }; 10095 MockRead data_reads_1[] = { 10096 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 10097 MockRead("HTTP/1.1 200 OK\r\n" 10098 "Alternate-Protocol: 443:npn-spdy/2\r\n" 10099 "Proxy-Connection: close\r\n" 10100 "\r\n"), 10101 }; 10102 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1), 10103 data_writes_1, arraysize(data_writes_1)); 10104 10105 // Second round tries to tunnel to www.google.com due to the 10106 // Alternate-Protocol announcement in the first round. It fails due 10107 // to a proxy authentication challenge. 10108 // After the failure, a tunnel is established to www.google.com using 10109 // Proxy-Authorization headers. There is then a SPDY request round. 10110 // 10111 // NOTE: Despite the "Proxy-Connection: Close", these are done on the 10112 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket 10113 // does a Disconnect and Connect on the same socket, rather than trying 10114 // to obtain a new one. 10115 // 10116 // NOTE: Originally, the proxy response to the second CONNECT request 10117 // simply returned another 407 so the unit test could skip the SSL connection 10118 // establishment and SPDY framing issues. Alas, the 10119 // retry-http-when-alternate-protocol fails logic kicks in, which was more 10120 // complicated to set up expectations for than the SPDY session. 10121 10122 scoped_ptr<SpdyFrame> req( 10123 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 10124 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10125 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10126 10127 MockWrite data_writes_2[] = { 10128 // First connection attempt without Proxy-Authorization. 10129 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10130 "Host: www.google.com\r\n" 10131 "Proxy-Connection: keep-alive\r\n" 10132 "\r\n"), 10133 10134 // Second connection attempt with Proxy-Authorization. 10135 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10136 "Host: www.google.com\r\n" 10137 "Proxy-Connection: keep-alive\r\n" 10138 "Proxy-Authorization: auth_token\r\n" 10139 "\r\n"), 10140 10141 // SPDY request 10142 CreateMockWrite(*req), 10143 }; 10144 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n" 10145 "Proxy-Authenticate: Mock\r\n" 10146 "Proxy-Connection: close\r\n" 10147 "\r\n"); 10148 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 10149 MockRead data_reads_2[] = { 10150 // First connection attempt fails 10151 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1), 10152 MockRead(ASYNC, kRejectConnectResponse, 10153 arraysize(kRejectConnectResponse) - 1, 1), 10154 10155 // Second connection attempt passes 10156 MockRead(ASYNC, kAcceptConnectResponse, 10157 arraysize(kAcceptConnectResponse) -1, 4), 10158 10159 // SPDY response 10160 CreateMockRead(*resp.get(), 6), 10161 CreateMockRead(*data.get(), 6), 10162 MockRead(ASYNC, 0, 0, 6), 10163 }; 10164 OrderedSocketData data_2( 10165 data_reads_2, arraysize(data_reads_2), 10166 data_writes_2, arraysize(data_writes_2)); 10167 10168 SSLSocketDataProvider ssl(ASYNC, OK); 10169 ssl.SetNextProto(GetParam()); 10170 10171 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 10172 StaticSocketDataProvider hanging_non_alternate_protocol_socket( 10173 NULL, 0, NULL, 0); 10174 hanging_non_alternate_protocol_socket.set_connect_data( 10175 never_finishing_connect); 10176 10177 session_deps_.socket_factory->AddSocketDataProvider(&data_1); 10178 session_deps_.socket_factory->AddSocketDataProvider(&data_2); 10179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10180 session_deps_.socket_factory->AddSocketDataProvider( 10181 &hanging_non_alternate_protocol_socket); 10182 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10183 10184 // First round should work and provide the Alternate-Protocol state. 10185 TestCompletionCallback callback_1; 10186 scoped_ptr<HttpTransaction> trans_1( 10187 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10188 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog()); 10189 EXPECT_EQ(ERR_IO_PENDING, rv); 10190 EXPECT_EQ(OK, callback_1.WaitForResult()); 10191 10192 // Second round should attempt a tunnel connect and get an auth challenge. 10193 TestCompletionCallback callback_2; 10194 scoped_ptr<HttpTransaction> trans_2( 10195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10196 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog()); 10197 EXPECT_EQ(ERR_IO_PENDING, rv); 10198 EXPECT_EQ(OK, callback_2.WaitForResult()); 10199 const HttpResponseInfo* response = trans_2->GetResponseInfo(); 10200 ASSERT_TRUE(response != NULL); 10201 ASSERT_FALSE(response->auth_challenge.get() == NULL); 10202 10203 // Restart with auth. Tunnel should work and response received. 10204 TestCompletionCallback callback_3; 10205 rv = trans_2->RestartWithAuth( 10206 AuthCredentials(kFoo, kBar), callback_3.callback()); 10207 EXPECT_EQ(ERR_IO_PENDING, rv); 10208 EXPECT_EQ(OK, callback_3.WaitForResult()); 10209 10210 // After all that work, these two lines (or actually, just the scheme) are 10211 // what this test is all about. Make sure it happens correctly. 10212 EXPECT_EQ("https", request_url.scheme()); 10213 EXPECT_EQ("www.google.com", request_url.host()); 10214 10215 LoadTimingInfo load_timing_info; 10216 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info)); 10217 TestLoadTimingNotReusedWithPac(load_timing_info, 10218 CONNECT_TIMING_HAS_SSL_TIMES); 10219 } 10220 10221 // Test that if we cancel the transaction as the connection is completing, that 10222 // everything tears down correctly. 10223 TEST_P(HttpNetworkTransactionTest, SimpleCancel) { 10224 // Setup everything about the connection to complete synchronously, so that 10225 // after calling HttpNetworkTransaction::Start, the only thing we're waiting 10226 // for is the callback from the HttpStreamRequest. 10227 // Then cancel the transaction. 10228 // Verify that we don't crash. 10229 MockConnect mock_connect(SYNCHRONOUS, OK); 10230 MockRead data_reads[] = { 10231 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"), 10232 MockRead(SYNCHRONOUS, "hello world"), 10233 MockRead(SYNCHRONOUS, OK), 10234 }; 10235 10236 HttpRequestInfo request; 10237 request.method = "GET"; 10238 request.url = GURL("http://www.google.com/"); 10239 request.load_flags = 0; 10240 10241 session_deps_.host_resolver->set_synchronous_mode(true); 10242 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10243 scoped_ptr<HttpTransaction> trans( 10244 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 10245 10246 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 10247 data.set_connect_data(mock_connect); 10248 session_deps_.socket_factory->AddSocketDataProvider(&data); 10249 10250 TestCompletionCallback callback; 10251 10252 CapturingBoundNetLog log; 10253 int rv = trans->Start(&request, callback.callback(), log.bound()); 10254 EXPECT_EQ(ERR_IO_PENDING, rv); 10255 trans.reset(); // Cancel the transaction here. 10256 10257 base::MessageLoop::current()->RunUntilIdle(); 10258 } 10259 10260 // Test that if a transaction is cancelled after receiving the headers, the 10261 // stream is drained properly and added back to the socket pool. The main 10262 // purpose of this test is to make sure that an HttpStreamParser can be read 10263 // from after the HttpNetworkTransaction and the objects it owns have been 10264 // deleted. 10265 // See http://crbug.com/368418 10266 TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) { 10267 MockRead data_reads[] = { 10268 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"), 10269 MockRead(ASYNC, "Content-Length: 2\r\n"), 10270 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"), 10271 MockRead(ASYNC, "1"), 10272 // 2 async reads are necessary to trigger a ReadResponseBody call after the 10273 // HttpNetworkTransaction has been deleted. 10274 MockRead(ASYNC, "2"), 10275 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this. 10276 }; 10277 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 10278 session_deps_.socket_factory->AddSocketDataProvider(&data); 10279 10280 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10281 10282 { 10283 HttpRequestInfo request; 10284 request.method = "GET"; 10285 request.url = GURL("http://www.google.com/"); 10286 request.load_flags = 0; 10287 10288 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session); 10289 TestCompletionCallback callback; 10290 10291 int rv = trans.Start(&request, callback.callback(), BoundNetLog()); 10292 EXPECT_EQ(ERR_IO_PENDING, rv); 10293 callback.WaitForResult(); 10294 10295 const HttpResponseInfo* response = trans.GetResponseInfo(); 10296 ASSERT_TRUE(response != NULL); 10297 EXPECT_TRUE(response->headers.get() != NULL); 10298 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10299 10300 // The transaction and HttpRequestInfo are deleted. 10301 } 10302 10303 // Let the HttpResponseBodyDrainer drain the socket. 10304 base::MessageLoop::current()->RunUntilIdle(); 10305 10306 // Socket should now be idle, waiting to be reused. 10307 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session)); 10308 } 10309 10310 // Test a basic GET request through a proxy. 10311 TEST_P(HttpNetworkTransactionTest, ProxyGet) { 10312 session_deps_.proxy_service.reset( 10313 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 10314 CapturingBoundNetLog log; 10315 session_deps_.net_log = log.bound().net_log(); 10316 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10317 10318 HttpRequestInfo request; 10319 request.method = "GET"; 10320 request.url = GURL("http://www.google.com/"); 10321 10322 MockWrite data_writes1[] = { 10323 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 10324 "Host: www.google.com\r\n" 10325 "Proxy-Connection: keep-alive\r\n\r\n"), 10326 }; 10327 10328 MockRead data_reads1[] = { 10329 MockRead("HTTP/1.1 200 OK\r\n"), 10330 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 10331 MockRead("Content-Length: 100\r\n\r\n"), 10332 MockRead(SYNCHRONOUS, OK), 10333 }; 10334 10335 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 10336 data_writes1, arraysize(data_writes1)); 10337 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10338 10339 TestCompletionCallback callback1; 10340 10341 scoped_ptr<HttpTransaction> trans( 10342 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10343 10344 int rv = trans->Start(&request, callback1.callback(), log.bound()); 10345 EXPECT_EQ(ERR_IO_PENDING, rv); 10346 10347 rv = callback1.WaitForResult(); 10348 EXPECT_EQ(OK, rv); 10349 10350 const HttpResponseInfo* response = trans->GetResponseInfo(); 10351 ASSERT_TRUE(response != NULL); 10352 10353 EXPECT_TRUE(response->headers->IsKeepAlive()); 10354 EXPECT_EQ(200, response->headers->response_code()); 10355 EXPECT_EQ(100, response->headers->GetContentLength()); 10356 EXPECT_TRUE(response->was_fetched_via_proxy); 10357 EXPECT_TRUE( 10358 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70"))); 10359 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 10360 10361 LoadTimingInfo load_timing_info; 10362 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 10363 TestLoadTimingNotReusedWithPac(load_timing_info, 10364 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 10365 } 10366 10367 // Test a basic HTTPS GET request through a proxy. 10368 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) { 10369 session_deps_.proxy_service.reset( 10370 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 10371 CapturingBoundNetLog log; 10372 session_deps_.net_log = log.bound().net_log(); 10373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10374 10375 HttpRequestInfo request; 10376 request.method = "GET"; 10377 request.url = GURL("https://www.google.com/"); 10378 10379 // Since we have proxy, should try to establish tunnel. 10380 MockWrite data_writes1[] = { 10381 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10382 "Host: www.google.com\r\n" 10383 "Proxy-Connection: keep-alive\r\n\r\n"), 10384 10385 MockWrite("GET / HTTP/1.1\r\n" 10386 "Host: www.google.com\r\n" 10387 "Connection: keep-alive\r\n\r\n"), 10388 }; 10389 10390 MockRead data_reads1[] = { 10391 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 10392 10393 MockRead("HTTP/1.1 200 OK\r\n"), 10394 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 10395 MockRead("Content-Length: 100\r\n\r\n"), 10396 MockRead(SYNCHRONOUS, OK), 10397 }; 10398 10399 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 10400 data_writes1, arraysize(data_writes1)); 10401 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10402 SSLSocketDataProvider ssl(ASYNC, OK); 10403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10404 10405 TestCompletionCallback callback1; 10406 10407 scoped_ptr<HttpTransaction> trans( 10408 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10409 10410 int rv = trans->Start(&request, callback1.callback(), log.bound()); 10411 EXPECT_EQ(ERR_IO_PENDING, rv); 10412 10413 rv = callback1.WaitForResult(); 10414 EXPECT_EQ(OK, rv); 10415 net::CapturingNetLog::CapturedEntryList entries; 10416 log.GetEntries(&entries); 10417 size_t pos = ExpectLogContainsSomewhere( 10418 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 10419 NetLog::PHASE_NONE); 10420 ExpectLogContainsSomewhere( 10421 entries, pos, 10422 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 10423 NetLog::PHASE_NONE); 10424 10425 const HttpResponseInfo* response = trans->GetResponseInfo(); 10426 ASSERT_TRUE(response != NULL); 10427 10428 EXPECT_TRUE(response->headers->IsKeepAlive()); 10429 EXPECT_EQ(200, response->headers->response_code()); 10430 EXPECT_EQ(100, response->headers->GetContentLength()); 10431 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 10432 EXPECT_TRUE(response->was_fetched_via_proxy); 10433 EXPECT_TRUE( 10434 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70"))); 10435 10436 LoadTimingInfo load_timing_info; 10437 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); 10438 TestLoadTimingNotReusedWithPac(load_timing_info, 10439 CONNECT_TIMING_HAS_SSL_TIMES); 10440 } 10441 10442 // Test a basic HTTPS GET request through a proxy, but the server hangs up 10443 // while establishing the tunnel. 10444 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { 10445 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70")); 10446 CapturingBoundNetLog log; 10447 session_deps_.net_log = log.bound().net_log(); 10448 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10449 10450 HttpRequestInfo request; 10451 request.method = "GET"; 10452 request.url = GURL("https://www.google.com/"); 10453 10454 // Since we have proxy, should try to establish tunnel. 10455 MockWrite data_writes1[] = { 10456 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 10457 "Host: www.google.com\r\n" 10458 "Proxy-Connection: keep-alive\r\n\r\n"), 10459 10460 MockWrite("GET / HTTP/1.1\r\n" 10461 "Host: www.google.com\r\n" 10462 "Connection: keep-alive\r\n\r\n"), 10463 }; 10464 10465 MockRead data_reads1[] = { 10466 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 10467 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 10468 MockRead(ASYNC, 0, 0), // EOF 10469 }; 10470 10471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 10472 data_writes1, arraysize(data_writes1)); 10473 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10474 SSLSocketDataProvider ssl(ASYNC, OK); 10475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10476 10477 TestCompletionCallback callback1; 10478 10479 scoped_ptr<HttpTransaction> trans( 10480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10481 10482 int rv = trans->Start(&request, callback1.callback(), log.bound()); 10483 EXPECT_EQ(ERR_IO_PENDING, rv); 10484 10485 rv = callback1.WaitForResult(); 10486 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 10487 net::CapturingNetLog::CapturedEntryList entries; 10488 log.GetEntries(&entries); 10489 size_t pos = ExpectLogContainsSomewhere( 10490 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 10491 NetLog::PHASE_NONE); 10492 ExpectLogContainsSomewhere( 10493 entries, pos, 10494 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 10495 NetLog::PHASE_NONE); 10496 } 10497 10498 // Test for crbug.com/55424. 10499 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) { 10500 scoped_ptr<SpdyFrame> req( 10501 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10502 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 10503 10504 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10505 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10506 MockRead spdy_reads[] = { 10507 CreateMockRead(*resp), 10508 CreateMockRead(*data), 10509 MockRead(ASYNC, 0, 0), 10510 }; 10511 10512 DelayedSocketData spdy_data( 10513 1, // wait for one write to finish before reading. 10514 spdy_reads, arraysize(spdy_reads), 10515 spdy_writes, arraysize(spdy_writes)); 10516 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10517 10518 SSLSocketDataProvider ssl(ASYNC, OK); 10519 ssl.SetNextProto(GetParam()); 10520 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10521 10522 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10523 10524 // Set up an initial SpdySession in the pool to reuse. 10525 HostPortPair host_port_pair("www.google.com", 443); 10526 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 10527 PRIVACY_MODE_DISABLED); 10528 base::WeakPtr<SpdySession> spdy_session = 10529 CreateInsecureSpdySession(session, key, BoundNetLog()); 10530 10531 HttpRequestInfo request; 10532 request.method = "GET"; 10533 request.url = GURL("https://www.google.com/"); 10534 request.load_flags = 0; 10535 10536 // This is the important line that marks this as a preconnect. 10537 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED; 10538 10539 scoped_ptr<HttpTransaction> trans( 10540 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10541 10542 TestCompletionCallback callback; 10543 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 10544 EXPECT_EQ(ERR_IO_PENDING, rv); 10545 EXPECT_EQ(OK, callback.WaitForResult()); 10546 } 10547 10548 // Given a net error, cause that error to be returned from the first Write() 10549 // call and verify that the HttpTransaction fails with that error. 10550 void HttpNetworkTransactionTest::CheckErrorIsPassedBack( 10551 int error, IoMode mode) { 10552 net::HttpRequestInfo request_info; 10553 request_info.url = GURL("https://www.example.com/"); 10554 request_info.method = "GET"; 10555 request_info.load_flags = net::LOAD_NORMAL; 10556 10557 SSLSocketDataProvider ssl_data(mode, OK); 10558 net::MockWrite data_writes[] = { 10559 net::MockWrite(mode, error), 10560 }; 10561 net::StaticSocketDataProvider data(NULL, 0, 10562 data_writes, arraysize(data_writes)); 10563 session_deps_.socket_factory->AddSocketDataProvider(&data); 10564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); 10565 10566 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10567 scoped_ptr<HttpTransaction> trans( 10568 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10569 10570 TestCompletionCallback callback; 10571 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10572 if (rv == net::ERR_IO_PENDING) 10573 rv = callback.WaitForResult(); 10574 ASSERT_EQ(error, rv); 10575 } 10576 10577 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) { 10578 // Just check a grab bag of cert errors. 10579 static const int kErrors[] = { 10580 ERR_CERT_COMMON_NAME_INVALID, 10581 ERR_CERT_AUTHORITY_INVALID, 10582 ERR_CERT_DATE_INVALID, 10583 }; 10584 for (size_t i = 0; i < arraysize(kErrors); i++) { 10585 CheckErrorIsPassedBack(kErrors[i], ASYNC); 10586 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS); 10587 } 10588 } 10589 10590 // Ensure that a client certificate is removed from the SSL client auth 10591 // cache when: 10592 // 1) No proxy is involved. 10593 // 2) TLS False Start is disabled. 10594 // 3) The initial TLS handshake requests a client certificate. 10595 // 4) The client supplies an invalid/unacceptable certificate. 10596 TEST_P(HttpNetworkTransactionTest, 10597 ClientAuthCertCache_Direct_NoFalseStart) { 10598 net::HttpRequestInfo request_info; 10599 request_info.url = GURL("https://www.example.com/"); 10600 request_info.method = "GET"; 10601 request_info.load_flags = net::LOAD_NORMAL; 10602 10603 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10604 cert_request->host_and_port = HostPortPair("www.example.com", 443); 10605 10606 // [ssl_]data1 contains the data for the first SSL handshake. When a 10607 // CertificateRequest is received for the first time, the handshake will 10608 // be aborted to allow the caller to provide a certificate. 10609 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10610 ssl_data1.cert_request_info = cert_request.get(); 10611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10612 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10613 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10614 10615 // [ssl_]data2 contains the data for the second SSL handshake. When TLS 10616 // False Start is not being used, the result of the SSL handshake will be 10617 // returned as part of the SSLClientSocket::Connect() call. This test 10618 // matches the result of a server sending a handshake_failure alert, 10619 // rather than a Finished message, because it requires a client 10620 // certificate and none was supplied. 10621 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10622 ssl_data2.cert_request_info = cert_request.get(); 10623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10624 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 10625 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10626 10627 // [ssl_]data3 contains the data for the third SSL handshake. When a 10628 // connection to a server fails during an SSL handshake, 10629 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous 10630 // connection was attempted with TLSv1.1. This is transparent to the caller 10631 // of the HttpNetworkTransaction. Because this test failure is due to 10632 // requiring a client certificate, this fallback handshake should also 10633 // fail. 10634 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10635 ssl_data3.cert_request_info = cert_request.get(); 10636 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10637 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 10638 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10639 10640 // [ssl_]data4 contains the data for the fourth SSL handshake. When a 10641 // connection to a server fails during an SSL handshake, 10642 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous 10643 // connection was attempted with TLSv1. This is transparent to the caller 10644 // of the HttpNetworkTransaction. Because this test failure is due to 10645 // requiring a client certificate, this fallback handshake should also 10646 // fail. 10647 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10648 ssl_data4.cert_request_info = cert_request.get(); 10649 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4); 10650 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0); 10651 session_deps_.socket_factory->AddSocketDataProvider(&data4); 10652 10653 // Need one more if TLSv1.2 is enabled. 10654 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10655 ssl_data5.cert_request_info = cert_request.get(); 10656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5); 10657 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0); 10658 session_deps_.socket_factory->AddSocketDataProvider(&data5); 10659 10660 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10661 scoped_ptr<HttpTransaction> trans( 10662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10663 10664 // Begin the SSL handshake with the peer. This consumes ssl_data1. 10665 TestCompletionCallback callback; 10666 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10667 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10668 10669 // Complete the SSL handshake, which should abort due to requiring a 10670 // client certificate. 10671 rv = callback.WaitForResult(); 10672 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10673 10674 // Indicate that no certificate should be supplied. From the perspective 10675 // of SSLClientCertCache, NULL is just as meaningful as a real 10676 // certificate, so this is the same as supply a 10677 // legitimate-but-unacceptable certificate. 10678 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10679 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10680 10681 // Ensure the certificate was added to the client auth cache before 10682 // allowing the connection to continue restarting. 10683 scoped_refptr<X509Certificate> client_cert; 10684 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( 10685 HostPortPair("www.example.com", 443), &client_cert)); 10686 ASSERT_EQ(NULL, client_cert.get()); 10687 10688 // Restart the handshake. This will consume ssl_data2, which fails, and 10689 // then consume ssl_data3 and ssl_data4, both of which should also fail. 10690 // The result code is checked against what ssl_data4 should return. 10691 rv = callback.WaitForResult(); 10692 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 10693 10694 // Ensure that the client certificate is removed from the cache on a 10695 // handshake failure. 10696 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10697 HostPortPair("www.example.com", 443), &client_cert)); 10698 } 10699 10700 // Ensure that a client certificate is removed from the SSL client auth 10701 // cache when: 10702 // 1) No proxy is involved. 10703 // 2) TLS False Start is enabled. 10704 // 3) The initial TLS handshake requests a client certificate. 10705 // 4) The client supplies an invalid/unacceptable certificate. 10706 TEST_P(HttpNetworkTransactionTest, 10707 ClientAuthCertCache_Direct_FalseStart) { 10708 net::HttpRequestInfo request_info; 10709 request_info.url = GURL("https://www.example.com/"); 10710 request_info.method = "GET"; 10711 request_info.load_flags = net::LOAD_NORMAL; 10712 10713 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10714 cert_request->host_and_port = HostPortPair("www.example.com", 443); 10715 10716 // When TLS False Start is used, SSLClientSocket::Connect() calls will 10717 // return successfully after reading up to the peer's Certificate message. 10718 // This is to allow the caller to call SSLClientSocket::Write(), which can 10719 // enqueue application data to be sent in the same packet as the 10720 // ChangeCipherSpec and Finished messages. 10721 // The actual handshake will be finished when SSLClientSocket::Read() is 10722 // called, which expects to process the peer's ChangeCipherSpec and 10723 // Finished messages. If there was an error negotiating with the peer, 10724 // such as due to the peer requiring a client certificate when none was 10725 // supplied, the alert sent by the peer won't be processed until Read() is 10726 // called. 10727 10728 // Like the non-False Start case, when a client certificate is requested by 10729 // the peer, the handshake is aborted during the Connect() call. 10730 // [ssl_]data1 represents the initial SSL handshake with the peer. 10731 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10732 ssl_data1.cert_request_info = cert_request.get(); 10733 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10734 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10735 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10736 10737 // When a client certificate is supplied, Connect() will not be aborted 10738 // when the peer requests the certificate. Instead, the handshake will 10739 // artificially succeed, allowing the caller to write the HTTP request to 10740 // the socket. The handshake messages are not processed until Read() is 10741 // called, which then detects that the handshake was aborted, due to the 10742 // peer sending a handshake_failure because it requires a client 10743 // certificate. 10744 SSLSocketDataProvider ssl_data2(ASYNC, net::OK); 10745 ssl_data2.cert_request_info = cert_request.get(); 10746 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10747 net::MockRead data2_reads[] = { 10748 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR), 10749 }; 10750 net::StaticSocketDataProvider data2( 10751 data2_reads, arraysize(data2_reads), NULL, 0); 10752 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10753 10754 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is 10755 // the data for the SSL handshake once the TLSv1.1 connection falls back to 10756 // TLSv1. It has the same behaviour as [ssl_]data2. 10757 SSLSocketDataProvider ssl_data3(ASYNC, net::OK); 10758 ssl_data3.cert_request_info = cert_request.get(); 10759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10760 net::StaticSocketDataProvider data3( 10761 data2_reads, arraysize(data2_reads), NULL, 0); 10762 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10763 10764 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection 10765 // falls back to SSLv3. It has the same behaviour as [ssl_]data2. 10766 SSLSocketDataProvider ssl_data4(ASYNC, net::OK); 10767 ssl_data4.cert_request_info = cert_request.get(); 10768 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4); 10769 net::StaticSocketDataProvider data4( 10770 data2_reads, arraysize(data2_reads), NULL, 0); 10771 session_deps_.socket_factory->AddSocketDataProvider(&data4); 10772 10773 // Need one more if TLSv1.2 is enabled. 10774 SSLSocketDataProvider ssl_data5(ASYNC, net::OK); 10775 ssl_data5.cert_request_info = cert_request.get(); 10776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5); 10777 net::StaticSocketDataProvider data5( 10778 data2_reads, arraysize(data2_reads), NULL, 0); 10779 session_deps_.socket_factory->AddSocketDataProvider(&data5); 10780 10781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10782 scoped_ptr<HttpTransaction> trans( 10783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10784 10785 // Begin the initial SSL handshake. 10786 TestCompletionCallback callback; 10787 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog()); 10788 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10789 10790 // Complete the SSL handshake, which should abort due to requiring a 10791 // client certificate. 10792 rv = callback.WaitForResult(); 10793 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10794 10795 // Indicate that no certificate should be supplied. From the perspective 10796 // of SSLClientCertCache, NULL is just as meaningful as a real 10797 // certificate, so this is the same as supply a 10798 // legitimate-but-unacceptable certificate. 10799 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10800 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10801 10802 // Ensure the certificate was added to the client auth cache before 10803 // allowing the connection to continue restarting. 10804 scoped_refptr<X509Certificate> client_cert; 10805 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( 10806 HostPortPair("www.example.com", 443), &client_cert)); 10807 ASSERT_EQ(NULL, client_cert.get()); 10808 10809 // Restart the handshake. This will consume ssl_data2, which fails, and 10810 // then consume ssl_data3 and ssl_data4, both of which should also fail. 10811 // The result code is checked against what ssl_data4 should return. 10812 rv = callback.WaitForResult(); 10813 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 10814 10815 // Ensure that the client certificate is removed from the cache on a 10816 // handshake failure. 10817 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10818 HostPortPair("www.example.com", 443), &client_cert)); 10819 } 10820 10821 // Ensure that a client certificate is removed from the SSL client auth 10822 // cache when: 10823 // 1) An HTTPS proxy is involved. 10824 // 3) The HTTPS proxy requests a client certificate. 10825 // 4) The client supplies an invalid/unacceptable certificate for the 10826 // proxy. 10827 // The test is repeated twice, first for connecting to an HTTPS endpoint, 10828 // then for connecting to an HTTP endpoint. 10829 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) { 10830 session_deps_.proxy_service.reset( 10831 ProxyService::CreateFixed("https://proxy:70")); 10832 CapturingBoundNetLog log; 10833 session_deps_.net_log = log.bound().net_log(); 10834 10835 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 10836 cert_request->host_and_port = HostPortPair("proxy", 70); 10837 10838 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of 10839 // [ssl_]data[1-3]. Rather than represending the endpoint 10840 // (www.example.com:443), they represent failures with the HTTPS proxy 10841 // (proxy:70). 10842 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 10843 ssl_data1.cert_request_info = cert_request.get(); 10844 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1); 10845 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 10846 session_deps_.socket_factory->AddSocketDataProvider(&data1); 10847 10848 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10849 ssl_data2.cert_request_info = cert_request.get(); 10850 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2); 10851 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 10852 session_deps_.socket_factory->AddSocketDataProvider(&data2); 10853 10854 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3. 10855 #if 0 10856 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR); 10857 ssl_data3.cert_request_info = cert_request.get(); 10858 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3); 10859 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 10860 session_deps_.socket_factory->AddSocketDataProvider(&data3); 10861 #endif 10862 10863 net::HttpRequestInfo requests[2]; 10864 requests[0].url = GURL("https://www.example.com/"); 10865 requests[0].method = "GET"; 10866 requests[0].load_flags = net::LOAD_NORMAL; 10867 10868 requests[1].url = GURL("http://www.example.com/"); 10869 requests[1].method = "GET"; 10870 requests[1].load_flags = net::LOAD_NORMAL; 10871 10872 for (size_t i = 0; i < arraysize(requests); ++i) { 10873 session_deps_.socket_factory->ResetNextMockIndexes(); 10874 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10875 scoped_ptr<HttpNetworkTransaction> trans( 10876 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 10877 10878 // Begin the SSL handshake with the proxy. 10879 TestCompletionCallback callback; 10880 int rv = trans->Start( 10881 &requests[i], callback.callback(), net::BoundNetLog()); 10882 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10883 10884 // Complete the SSL handshake, which should abort due to requiring a 10885 // client certificate. 10886 rv = callback.WaitForResult(); 10887 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 10888 10889 // Indicate that no certificate should be supplied. From the perspective 10890 // of SSLClientCertCache, NULL is just as meaningful as a real 10891 // certificate, so this is the same as supply a 10892 // legitimate-but-unacceptable certificate. 10893 rv = trans->RestartWithCertificate(NULL, callback.callback()); 10894 ASSERT_EQ(net::ERR_IO_PENDING, rv); 10895 10896 // Ensure the certificate was added to the client auth cache before 10897 // allowing the connection to continue restarting. 10898 scoped_refptr<X509Certificate> client_cert; 10899 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( 10900 HostPortPair("proxy", 70), &client_cert)); 10901 ASSERT_EQ(NULL, client_cert.get()); 10902 // Ensure the certificate was NOT cached for the endpoint. This only 10903 // applies to HTTPS requests, but is fine to check for HTTP requests. 10904 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10905 HostPortPair("www.example.com", 443), &client_cert)); 10906 10907 // Restart the handshake. This will consume ssl_data2, which fails, and 10908 // then consume ssl_data3, which should also fail. The result code is 10909 // checked against what ssl_data3 should return. 10910 rv = callback.WaitForResult(); 10911 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv); 10912 10913 // Now that the new handshake has failed, ensure that the client 10914 // certificate was removed from the client auth cache. 10915 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10916 HostPortPair("proxy", 70), &client_cert)); 10917 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( 10918 HostPortPair("www.example.com", 443), &client_cert)); 10919 } 10920 } 10921 10922 // Unlike TEST/TEST_F, which are macros that expand to further macros, 10923 // TEST_P is a macro that expands directly to code that stringizes the 10924 // arguments. As a result, macros passed as parameters (such as prefix 10925 // or test_case_name) will not be expanded by the preprocessor. To 10926 // work around this, indirect the macro for TEST_P, so that the 10927 // pre-processor will expand macros such as MAYBE_test_name before 10928 // instantiating the test. 10929 #define WRAPPED_TEST_P(test_case_name, test_name) \ 10930 TEST_P(test_case_name, test_name) 10931 10932 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 10933 #if defined(OS_WIN) 10934 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling 10935 #else 10936 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling 10937 #endif 10938 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) { 10939 session_deps_.use_alternate_protocols = true; 10940 session_deps_.next_protos = SpdyNextProtos(); 10941 10942 // Set up a special HttpNetworkSession with a MockCachingHostResolver. 10943 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 10944 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 10945 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 10946 pool_peer.DisableDomainAuthenticationVerification(); 10947 10948 SSLSocketDataProvider ssl(ASYNC, OK); 10949 ssl.SetNextProto(GetParam()); 10950 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10951 10952 scoped_ptr<SpdyFrame> host1_req( 10953 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 10954 scoped_ptr<SpdyFrame> host2_req( 10955 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 10956 MockWrite spdy_writes[] = { 10957 CreateMockWrite(*host1_req, 1), 10958 CreateMockWrite(*host2_req, 4), 10959 }; 10960 scoped_ptr<SpdyFrame> host1_resp( 10961 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10962 scoped_ptr<SpdyFrame> host1_resp_body( 10963 spdy_util_.ConstructSpdyBodyFrame(1, true)); 10964 scoped_ptr<SpdyFrame> host2_resp( 10965 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 10966 scoped_ptr<SpdyFrame> host2_resp_body( 10967 spdy_util_.ConstructSpdyBodyFrame(3, true)); 10968 MockRead spdy_reads[] = { 10969 CreateMockRead(*host1_resp, 2), 10970 CreateMockRead(*host1_resp_body, 3), 10971 CreateMockRead(*host2_resp, 5), 10972 CreateMockRead(*host2_resp_body, 6), 10973 MockRead(ASYNC, 0, 7), 10974 }; 10975 10976 IPAddressNumber ip; 10977 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 10978 IPEndPoint peer_addr = IPEndPoint(ip, 443); 10979 MockConnect connect(ASYNC, OK, peer_addr); 10980 OrderedSocketData spdy_data( 10981 connect, 10982 spdy_reads, arraysize(spdy_reads), 10983 spdy_writes, arraysize(spdy_writes)); 10984 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 10985 10986 TestCompletionCallback callback; 10987 HttpRequestInfo request1; 10988 request1.method = "GET"; 10989 request1.url = GURL("https://www.google.com/"); 10990 request1.load_flags = 0; 10991 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 10992 10993 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 10994 EXPECT_EQ(ERR_IO_PENDING, rv); 10995 EXPECT_EQ(OK, callback.WaitForResult()); 10996 10997 const HttpResponseInfo* response = trans1.GetResponseInfo(); 10998 ASSERT_TRUE(response != NULL); 10999 ASSERT_TRUE(response->headers.get() != NULL); 11000 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11001 11002 std::string response_data; 11003 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 11004 EXPECT_EQ("hello!", response_data); 11005 11006 // Preload www.gmail.com into HostCache. 11007 HostPortPair host_port("www.gmail.com", 443); 11008 HostResolver::RequestInfo resolve_info(host_port); 11009 AddressList ignored; 11010 rv = session_deps_.host_resolver->Resolve(resolve_info, 11011 DEFAULT_PRIORITY, 11012 &ignored, 11013 callback.callback(), 11014 NULL, 11015 BoundNetLog()); 11016 EXPECT_EQ(ERR_IO_PENDING, rv); 11017 rv = callback.WaitForResult(); 11018 EXPECT_EQ(OK, rv); 11019 11020 HttpRequestInfo request2; 11021 request2.method = "GET"; 11022 request2.url = GURL("https://www.gmail.com/"); 11023 request2.load_flags = 0; 11024 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 11025 11026 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 11027 EXPECT_EQ(ERR_IO_PENDING, rv); 11028 EXPECT_EQ(OK, callback.WaitForResult()); 11029 11030 response = trans2.GetResponseInfo(); 11031 ASSERT_TRUE(response != NULL); 11032 ASSERT_TRUE(response->headers.get() != NULL); 11033 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11034 EXPECT_TRUE(response->was_fetched_via_spdy); 11035 EXPECT_TRUE(response->was_npn_negotiated); 11036 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 11037 EXPECT_EQ("hello!", response_data); 11038 } 11039 #undef MAYBE_UseIPConnectionPooling 11040 11041 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) { 11042 session_deps_.use_alternate_protocols = true; 11043 session_deps_.next_protos = SpdyNextProtos(); 11044 11045 // Set up a special HttpNetworkSession with a MockCachingHostResolver. 11046 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 11047 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11048 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 11049 pool_peer.DisableDomainAuthenticationVerification(); 11050 11051 SSLSocketDataProvider ssl(ASYNC, OK); 11052 ssl.SetNextProto(GetParam()); 11053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11054 11055 scoped_ptr<SpdyFrame> host1_req( 11056 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 11057 scoped_ptr<SpdyFrame> host2_req( 11058 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 11059 MockWrite spdy_writes[] = { 11060 CreateMockWrite(*host1_req, 1), 11061 CreateMockWrite(*host2_req, 4), 11062 }; 11063 scoped_ptr<SpdyFrame> host1_resp( 11064 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11065 scoped_ptr<SpdyFrame> host1_resp_body( 11066 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11067 scoped_ptr<SpdyFrame> host2_resp( 11068 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11069 scoped_ptr<SpdyFrame> host2_resp_body( 11070 spdy_util_.ConstructSpdyBodyFrame(3, true)); 11071 MockRead spdy_reads[] = { 11072 CreateMockRead(*host1_resp, 2), 11073 CreateMockRead(*host1_resp_body, 3), 11074 CreateMockRead(*host2_resp, 5), 11075 CreateMockRead(*host2_resp_body, 6), 11076 MockRead(ASYNC, 0, 7), 11077 }; 11078 11079 IPAddressNumber ip; 11080 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 11081 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11082 MockConnect connect(ASYNC, OK, peer_addr); 11083 OrderedSocketData spdy_data( 11084 connect, 11085 spdy_reads, arraysize(spdy_reads), 11086 spdy_writes, arraysize(spdy_writes)); 11087 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 11088 11089 TestCompletionCallback callback; 11090 HttpRequestInfo request1; 11091 request1.method = "GET"; 11092 request1.url = GURL("https://www.google.com/"); 11093 request1.load_flags = 0; 11094 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 11095 11096 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 11097 EXPECT_EQ(ERR_IO_PENDING, rv); 11098 EXPECT_EQ(OK, callback.WaitForResult()); 11099 11100 const HttpResponseInfo* response = trans1.GetResponseInfo(); 11101 ASSERT_TRUE(response != NULL); 11102 ASSERT_TRUE(response->headers.get() != NULL); 11103 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11104 11105 std::string response_data; 11106 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 11107 EXPECT_EQ("hello!", response_data); 11108 11109 HttpRequestInfo request2; 11110 request2.method = "GET"; 11111 request2.url = GURL("https://www.gmail.com/"); 11112 request2.load_flags = 0; 11113 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 11114 11115 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 11116 EXPECT_EQ(ERR_IO_PENDING, rv); 11117 EXPECT_EQ(OK, callback.WaitForResult()); 11118 11119 response = trans2.GetResponseInfo(); 11120 ASSERT_TRUE(response != NULL); 11121 ASSERT_TRUE(response->headers.get() != NULL); 11122 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11123 EXPECT_TRUE(response->was_fetched_via_spdy); 11124 EXPECT_TRUE(response->was_npn_negotiated); 11125 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 11126 EXPECT_EQ("hello!", response_data); 11127 } 11128 11129 class OneTimeCachingHostResolver : public net::HostResolver { 11130 public: 11131 explicit OneTimeCachingHostResolver(const HostPortPair& host_port) 11132 : host_port_(host_port) {} 11133 virtual ~OneTimeCachingHostResolver() {} 11134 11135 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); } 11136 11137 // HostResolver methods: 11138 virtual int Resolve(const RequestInfo& info, 11139 RequestPriority priority, 11140 AddressList* addresses, 11141 const CompletionCallback& callback, 11142 RequestHandle* out_req, 11143 const BoundNetLog& net_log) OVERRIDE { 11144 return host_resolver_.Resolve( 11145 info, priority, addresses, callback, out_req, net_log); 11146 } 11147 11148 virtual int ResolveFromCache(const RequestInfo& info, 11149 AddressList* addresses, 11150 const BoundNetLog& net_log) OVERRIDE { 11151 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log); 11152 if (rv == OK && info.host_port_pair().Equals(host_port_)) 11153 host_resolver_.GetHostCache()->clear(); 11154 return rv; 11155 } 11156 11157 virtual void CancelRequest(RequestHandle req) OVERRIDE { 11158 host_resolver_.CancelRequest(req); 11159 } 11160 11161 MockCachingHostResolver* GetMockHostResolver() { 11162 return &host_resolver_; 11163 } 11164 11165 private: 11166 MockCachingHostResolver host_resolver_; 11167 const HostPortPair host_port_; 11168 }; 11169 11170 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 11171 #if defined(OS_WIN) 11172 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \ 11173 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration 11174 #else 11175 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \ 11176 UseIPConnectionPoolingWithHostCacheExpiration 11177 #endif 11178 WRAPPED_TEST_P(HttpNetworkTransactionTest, 11179 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) { 11180 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_ 11181 // prefix doesn't work with parametrized tests). 11182 #if defined(OS_WIN) 11183 return; 11184 #else 11185 session_deps_.use_alternate_protocols = true; 11186 session_deps_.next_protos = SpdyNextProtos(); 11187 11188 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver. 11189 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443)); 11190 HttpNetworkSession::Params params = 11191 SpdySessionDependencies::CreateSessionParams(&session_deps_); 11192 params.host_resolver = &host_resolver; 11193 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11194 SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); 11195 pool_peer.DisableDomainAuthenticationVerification(); 11196 11197 SSLSocketDataProvider ssl(ASYNC, OK); 11198 ssl.SetNextProto(GetParam()); 11199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11200 11201 scoped_ptr<SpdyFrame> host1_req( 11202 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST)); 11203 scoped_ptr<SpdyFrame> host2_req( 11204 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST)); 11205 MockWrite spdy_writes[] = { 11206 CreateMockWrite(*host1_req, 1), 11207 CreateMockWrite(*host2_req, 4), 11208 }; 11209 scoped_ptr<SpdyFrame> host1_resp( 11210 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11211 scoped_ptr<SpdyFrame> host1_resp_body( 11212 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11213 scoped_ptr<SpdyFrame> host2_resp( 11214 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11215 scoped_ptr<SpdyFrame> host2_resp_body( 11216 spdy_util_.ConstructSpdyBodyFrame(3, true)); 11217 MockRead spdy_reads[] = { 11218 CreateMockRead(*host1_resp, 2), 11219 CreateMockRead(*host1_resp_body, 3), 11220 CreateMockRead(*host2_resp, 5), 11221 CreateMockRead(*host2_resp_body, 6), 11222 MockRead(ASYNC, 0, 7), 11223 }; 11224 11225 IPAddressNumber ip; 11226 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip)); 11227 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11228 MockConnect connect(ASYNC, OK, peer_addr); 11229 OrderedSocketData spdy_data( 11230 connect, 11231 spdy_reads, arraysize(spdy_reads), 11232 spdy_writes, arraysize(spdy_writes)); 11233 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); 11234 11235 TestCompletionCallback callback; 11236 HttpRequestInfo request1; 11237 request1.method = "GET"; 11238 request1.url = GURL("https://www.google.com/"); 11239 request1.load_flags = 0; 11240 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); 11241 11242 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog()); 11243 EXPECT_EQ(ERR_IO_PENDING, rv); 11244 EXPECT_EQ(OK, callback.WaitForResult()); 11245 11246 const HttpResponseInfo* response = trans1.GetResponseInfo(); 11247 ASSERT_TRUE(response != NULL); 11248 ASSERT_TRUE(response->headers.get() != NULL); 11249 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11250 11251 std::string response_data; 11252 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 11253 EXPECT_EQ("hello!", response_data); 11254 11255 // Preload cache entries into HostCache. 11256 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443)); 11257 AddressList ignored; 11258 rv = host_resolver.Resolve(resolve_info, 11259 DEFAULT_PRIORITY, 11260 &ignored, 11261 callback.callback(), 11262 NULL, 11263 BoundNetLog()); 11264 EXPECT_EQ(ERR_IO_PENDING, rv); 11265 rv = callback.WaitForResult(); 11266 EXPECT_EQ(OK, rv); 11267 11268 HttpRequestInfo request2; 11269 request2.method = "GET"; 11270 request2.url = GURL("https://www.gmail.com/"); 11271 request2.load_flags = 0; 11272 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); 11273 11274 rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); 11275 EXPECT_EQ(ERR_IO_PENDING, rv); 11276 EXPECT_EQ(OK, callback.WaitForResult()); 11277 11278 response = trans2.GetResponseInfo(); 11279 ASSERT_TRUE(response != NULL); 11280 ASSERT_TRUE(response->headers.get() != NULL); 11281 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11282 EXPECT_TRUE(response->was_fetched_via_spdy); 11283 EXPECT_TRUE(response->was_npn_negotiated); 11284 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 11285 EXPECT_EQ("hello!", response_data); 11286 #endif 11287 } 11288 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration 11289 11290 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) { 11291 const std::string https_url = "https://www.google.com/"; 11292 const std::string http_url = "http://www.google.com:443/"; 11293 11294 // SPDY GET for HTTPS URL 11295 scoped_ptr<SpdyFrame> req1( 11296 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 11297 11298 MockWrite writes1[] = { 11299 CreateMockWrite(*req1, 0), 11300 }; 11301 11302 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11303 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11304 MockRead reads1[] = { 11305 CreateMockRead(*resp1, 1), 11306 CreateMockRead(*body1, 2), 11307 MockRead(ASYNC, ERR_IO_PENDING, 3) 11308 }; 11309 11310 DelayedSocketData data1( 11311 1, reads1, arraysize(reads1), 11312 writes1, arraysize(writes1)); 11313 MockConnect connect_data1(ASYNC, OK); 11314 data1.set_connect_data(connect_data1); 11315 11316 // HTTP GET for the HTTP URL 11317 MockWrite writes2[] = { 11318 MockWrite(ASYNC, 4, 11319 "GET / HTTP/1.1\r\n" 11320 "Host: www.google.com:443\r\n" 11321 "Connection: keep-alive\r\n\r\n"), 11322 }; 11323 11324 MockRead reads2[] = { 11325 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 11326 MockRead(ASYNC, 6, "hello"), 11327 MockRead(ASYNC, 7, OK), 11328 }; 11329 11330 DelayedSocketData data2( 11331 1, reads2, arraysize(reads2), 11332 writes2, arraysize(writes2)); 11333 11334 SSLSocketDataProvider ssl(ASYNC, OK); 11335 ssl.SetNextProto(GetParam()); 11336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11337 session_deps_.socket_factory->AddSocketDataProvider(&data1); 11338 session_deps_.socket_factory->AddSocketDataProvider(&data2); 11339 11340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11341 11342 // Start the first transaction to set up the SpdySession 11343 HttpRequestInfo request1; 11344 request1.method = "GET"; 11345 request1.url = GURL(https_url); 11346 request1.load_flags = 0; 11347 HttpNetworkTransaction trans1(LOWEST, session.get()); 11348 TestCompletionCallback callback1; 11349 EXPECT_EQ(ERR_IO_PENDING, 11350 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11351 base::MessageLoop::current()->RunUntilIdle(); 11352 11353 EXPECT_EQ(OK, callback1.WaitForResult()); 11354 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11355 11356 // Now, start the HTTP request 11357 HttpRequestInfo request2; 11358 request2.method = "GET"; 11359 request2.url = GURL(http_url); 11360 request2.load_flags = 0; 11361 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11362 TestCompletionCallback callback2; 11363 EXPECT_EQ(ERR_IO_PENDING, 11364 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11365 base::MessageLoop::current()->RunUntilIdle(); 11366 11367 EXPECT_EQ(OK, callback2.WaitForResult()); 11368 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11369 } 11370 11371 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { 11372 const std::string https_url = "https://www.google.com/"; 11373 const std::string http_url = "http://www.google.com:443/"; 11374 11375 // SPDY GET for HTTPS URL (through CONNECT tunnel) 11376 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1, 11377 LOWEST)); 11378 scoped_ptr<SpdyFrame> req1( 11379 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 11380 scoped_ptr<SpdyFrame> wrapped_req1( 11381 spdy_util_.ConstructWrappedSpdyFrame(req1, 1)); 11382 11383 // SPDY GET for HTTP URL (through the proxy, but not the tunnel). 11384 SpdySynStreamIR req2_ir(3); 11385 spdy_util_.SetPriority(MEDIUM, &req2_ir); 11386 req2_ir.set_fin(true); 11387 req2_ir.SetHeader(spdy_util_.GetMethodKey(), "GET"); 11388 req2_ir.SetHeader(spdy_util_.GetPathKey(), 11389 spdy_util_.is_spdy2() ? http_url.c_str() : "/"); 11390 req2_ir.SetHeader(spdy_util_.GetHostKey(), "www.google.com:443"); 11391 req2_ir.SetHeader(spdy_util_.GetSchemeKey(), "http"); 11392 spdy_util_.MaybeAddVersionHeader(&req2_ir); 11393 scoped_ptr<SpdyFrame> req2( 11394 spdy_util_.CreateFramer(false)->SerializeFrame(req2_ir)); 11395 11396 MockWrite writes1[] = { 11397 CreateMockWrite(*connect, 0), 11398 CreateMockWrite(*wrapped_req1, 2), 11399 CreateMockWrite(*req2, 5), 11400 }; 11401 11402 scoped_ptr<SpdyFrame> conn_resp( 11403 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11404 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11405 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11406 scoped_ptr<SpdyFrame> wrapped_resp1( 11407 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1)); 11408 scoped_ptr<SpdyFrame> wrapped_body1( 11409 spdy_util_.ConstructWrappedSpdyFrame(body1, 1)); 11410 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11411 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 11412 MockRead reads1[] = { 11413 CreateMockRead(*conn_resp, 1), 11414 CreateMockRead(*wrapped_resp1, 3), 11415 CreateMockRead(*wrapped_body1, 4), 11416 CreateMockRead(*resp2, 6), 11417 CreateMockRead(*body2, 7), 11418 MockRead(ASYNC, ERR_IO_PENDING, 8) 11419 }; 11420 11421 DeterministicSocketData data1(reads1, arraysize(reads1), 11422 writes1, arraysize(writes1)); 11423 MockConnect connect_data1(ASYNC, OK); 11424 data1.set_connect_data(connect_data1); 11425 11426 session_deps_.proxy_service.reset( 11427 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70")); 11428 CapturingNetLog log; 11429 session_deps_.net_log = &log; 11430 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy 11431 ssl1.SetNextProto(GetParam()); 11432 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11433 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server 11434 ssl2.SetNextProto(GetParam()); 11435 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11436 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1); 11437 11438 scoped_refptr<HttpNetworkSession> session( 11439 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11440 11441 // Start the first transaction to set up the SpdySession 11442 HttpRequestInfo request1; 11443 request1.method = "GET"; 11444 request1.url = GURL(https_url); 11445 request1.load_flags = 0; 11446 HttpNetworkTransaction trans1(LOWEST, session.get()); 11447 TestCompletionCallback callback1; 11448 EXPECT_EQ(ERR_IO_PENDING, 11449 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11450 base::MessageLoop::current()->RunUntilIdle(); 11451 data1.RunFor(4); 11452 11453 EXPECT_EQ(OK, callback1.WaitForResult()); 11454 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11455 11456 LoadTimingInfo load_timing_info1; 11457 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1)); 11458 TestLoadTimingNotReusedWithPac(load_timing_info1, 11459 CONNECT_TIMING_HAS_SSL_TIMES); 11460 11461 // Now, start the HTTP request 11462 HttpRequestInfo request2; 11463 request2.method = "GET"; 11464 request2.url = GURL(http_url); 11465 request2.load_flags = 0; 11466 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11467 TestCompletionCallback callback2; 11468 EXPECT_EQ(ERR_IO_PENDING, 11469 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11470 base::MessageLoop::current()->RunUntilIdle(); 11471 data1.RunFor(3); 11472 11473 EXPECT_EQ(OK, callback2.WaitForResult()); 11474 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11475 11476 LoadTimingInfo load_timing_info2; 11477 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2)); 11478 // The established SPDY sessions is considered reused by the HTTP request. 11479 TestLoadTimingReusedWithPac(load_timing_info2); 11480 // HTTP requests over a SPDY session should have a different connection 11481 // socket_log_id than requests over a tunnel. 11482 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); 11483 } 11484 11485 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) { 11486 session_deps_.force_spdy_always = true; 11487 const std::string https_url = "https://www.google.com/"; 11488 const std::string http_url = "http://www.google.com:443/"; 11489 11490 // SPDY GET for HTTPS URL 11491 scoped_ptr<SpdyFrame> req1( 11492 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 11493 // SPDY GET for the HTTP URL 11494 scoped_ptr<SpdyFrame> req2( 11495 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM)); 11496 11497 MockWrite writes[] = { 11498 CreateMockWrite(*req1, 1), 11499 CreateMockWrite(*req2, 4), 11500 }; 11501 11502 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11503 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11504 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 11505 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 11506 MockRead reads[] = { 11507 CreateMockRead(*resp1, 2), 11508 CreateMockRead(*body1, 3), 11509 CreateMockRead(*resp2, 5), 11510 CreateMockRead(*body2, 6), 11511 MockRead(ASYNC, ERR_IO_PENDING, 7) 11512 }; 11513 11514 OrderedSocketData data(reads, arraysize(reads), 11515 writes, arraysize(writes)); 11516 11517 SSLSocketDataProvider ssl(ASYNC, OK); 11518 ssl.SetNextProto(GetParam()); 11519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11520 session_deps_.socket_factory->AddSocketDataProvider(&data); 11521 11522 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11523 11524 // Start the first transaction to set up the SpdySession 11525 HttpRequestInfo request1; 11526 request1.method = "GET"; 11527 request1.url = GURL(https_url); 11528 request1.load_flags = 0; 11529 HttpNetworkTransaction trans1(LOWEST, session.get()); 11530 TestCompletionCallback callback1; 11531 EXPECT_EQ(ERR_IO_PENDING, 11532 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11533 base::MessageLoop::current()->RunUntilIdle(); 11534 11535 EXPECT_EQ(OK, callback1.WaitForResult()); 11536 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11537 11538 // Now, start the HTTP request 11539 HttpRequestInfo request2; 11540 request2.method = "GET"; 11541 request2.url = GURL(http_url); 11542 request2.load_flags = 0; 11543 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11544 TestCompletionCallback callback2; 11545 EXPECT_EQ(ERR_IO_PENDING, 11546 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11547 base::MessageLoop::current()->RunUntilIdle(); 11548 11549 EXPECT_EQ(OK, callback2.WaitForResult()); 11550 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11551 } 11552 11553 // Test that in the case where we have a SPDY session to a SPDY proxy 11554 // that we do not pool other origins that resolve to the same IP when 11555 // the certificate does not match the new origin. 11556 // http://crbug.com/134690 11557 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) { 11558 const std::string url1 = "http://www.google.com/"; 11559 const std::string url2 = "https://mail.google.com/"; 11560 const std::string ip_addr = "1.2.3.4"; 11561 11562 // SPDY GET for HTTP URL (through SPDY proxy) 11563 scoped_ptr<SpdyHeaderBlock> headers( 11564 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/")); 11565 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame( 11566 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0)); 11567 11568 MockWrite writes1[] = { 11569 CreateMockWrite(*req1, 0), 11570 }; 11571 11572 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11573 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11574 MockRead reads1[] = { 11575 CreateMockRead(*resp1, 1), 11576 CreateMockRead(*body1, 2), 11577 MockRead(ASYNC, OK, 3) // EOF 11578 }; 11579 11580 scoped_ptr<DeterministicSocketData> data1( 11581 new DeterministicSocketData(reads1, arraysize(reads1), 11582 writes1, arraysize(writes1))); 11583 IPAddressNumber ip; 11584 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip)); 11585 IPEndPoint peer_addr = IPEndPoint(ip, 443); 11586 MockConnect connect_data1(ASYNC, OK, peer_addr); 11587 data1->set_connect_data(connect_data1); 11588 11589 // SPDY GET for HTTPS URL (direct) 11590 scoped_ptr<SpdyFrame> req2( 11591 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM)); 11592 11593 MockWrite writes2[] = { 11594 CreateMockWrite(*req2, 0), 11595 }; 11596 11597 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11598 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11599 MockRead reads2[] = { 11600 CreateMockRead(*resp2, 1), 11601 CreateMockRead(*body2, 2), 11602 MockRead(ASYNC, OK, 3) // EOF 11603 }; 11604 11605 scoped_ptr<DeterministicSocketData> data2( 11606 new DeterministicSocketData(reads2, arraysize(reads2), 11607 writes2, arraysize(writes2))); 11608 MockConnect connect_data2(ASYNC, OK); 11609 data2->set_connect_data(connect_data2); 11610 11611 // Set up a proxy config that sends HTTP requests to a proxy, and 11612 // all others direct. 11613 ProxyConfig proxy_config; 11614 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443"); 11615 CapturingProxyResolver* capturing_proxy_resolver = 11616 new CapturingProxyResolver(); 11617 session_deps_.proxy_service.reset(new ProxyService( 11618 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver, 11619 NULL)); 11620 11621 // Load a valid cert. Note, that this does not need to 11622 // be valid for proxy because the MockSSLClientSocket does 11623 // not actually verify it. But SpdySession will use this 11624 // to see if it is valid for the new origin 11625 base::FilePath certs_dir = GetTestCertsDirectory(); 11626 scoped_refptr<X509Certificate> server_cert( 11627 ImportCertFromFile(certs_dir, "ok_cert.pem")); 11628 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); 11629 11630 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy 11631 ssl1.SetNextProto(GetParam()); 11632 ssl1.cert = server_cert; 11633 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11634 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11635 data1.get()); 11636 11637 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server 11638 ssl2.SetNextProto(GetParam()); 11639 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11640 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11641 data2.get()); 11642 11643 session_deps_.host_resolver.reset(new MockCachingHostResolver()); 11644 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr); 11645 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr); 11646 11647 scoped_refptr<HttpNetworkSession> session( 11648 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11649 11650 // Start the first transaction to set up the SpdySession 11651 HttpRequestInfo request1; 11652 request1.method = "GET"; 11653 request1.url = GURL(url1); 11654 request1.load_flags = 0; 11655 HttpNetworkTransaction trans1(LOWEST, session.get()); 11656 TestCompletionCallback callback1; 11657 ASSERT_EQ(ERR_IO_PENDING, 11658 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11659 data1->RunFor(3); 11660 11661 ASSERT_TRUE(callback1.have_result()); 11662 EXPECT_EQ(OK, callback1.WaitForResult()); 11663 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy); 11664 11665 // Now, start the HTTP request 11666 HttpRequestInfo request2; 11667 request2.method = "GET"; 11668 request2.url = GURL(url2); 11669 request2.load_flags = 0; 11670 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11671 TestCompletionCallback callback2; 11672 EXPECT_EQ(ERR_IO_PENDING, 11673 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11674 base::MessageLoop::current()->RunUntilIdle(); 11675 data2->RunFor(3); 11676 11677 ASSERT_TRUE(callback2.have_result()); 11678 EXPECT_EQ(OK, callback2.WaitForResult()); 11679 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11680 } 11681 11682 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED 11683 // error) in SPDY session, removes the socket from pool and closes the SPDY 11684 // session. Verify that new url's from the same HttpNetworkSession (and a new 11685 // SpdySession) do work. http://crbug.com/224701 11686 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) { 11687 const std::string https_url = "https://www.google.com/"; 11688 11689 MockRead reads1[] = { 11690 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0) 11691 }; 11692 11693 scoped_ptr<DeterministicSocketData> data1( 11694 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0)); 11695 data1->SetStop(1); 11696 11697 scoped_ptr<SpdyFrame> req2( 11698 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM)); 11699 MockWrite writes2[] = { 11700 CreateMockWrite(*req2, 0), 11701 }; 11702 11703 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11704 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 11705 MockRead reads2[] = { 11706 CreateMockRead(*resp2, 1), 11707 CreateMockRead(*body2, 2), 11708 MockRead(ASYNC, OK, 3) // EOF 11709 }; 11710 11711 scoped_ptr<DeterministicSocketData> data2( 11712 new DeterministicSocketData(reads2, arraysize(reads2), 11713 writes2, arraysize(writes2))); 11714 11715 SSLSocketDataProvider ssl1(ASYNC, OK); 11716 ssl1.SetNextProto(GetParam()); 11717 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1); 11718 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11719 data1.get()); 11720 11721 SSLSocketDataProvider ssl2(ASYNC, OK); 11722 ssl2.SetNextProto(GetParam()); 11723 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2); 11724 session_deps_.deterministic_socket_factory->AddSocketDataProvider( 11725 data2.get()); 11726 11727 scoped_refptr<HttpNetworkSession> session( 11728 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_)); 11729 11730 // Start the first transaction to set up the SpdySession and verify that 11731 // connection was closed. 11732 HttpRequestInfo request1; 11733 request1.method = "GET"; 11734 request1.url = GURL(https_url); 11735 request1.load_flags = 0; 11736 HttpNetworkTransaction trans1(MEDIUM, session.get()); 11737 TestCompletionCallback callback1; 11738 EXPECT_EQ(ERR_IO_PENDING, 11739 trans1.Start(&request1, callback1.callback(), BoundNetLog())); 11740 base::MessageLoop::current()->RunUntilIdle(); 11741 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult()); 11742 11743 // Now, start the second request and make sure it succeeds. 11744 HttpRequestInfo request2; 11745 request2.method = "GET"; 11746 request2.url = GURL(https_url); 11747 request2.load_flags = 0; 11748 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11749 TestCompletionCallback callback2; 11750 EXPECT_EQ(ERR_IO_PENDING, 11751 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11752 base::MessageLoop::current()->RunUntilIdle(); 11753 data2->RunFor(3); 11754 11755 ASSERT_TRUE(callback2.have_result()); 11756 EXPECT_EQ(OK, callback2.WaitForResult()); 11757 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11758 } 11759 11760 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) { 11761 session_deps_.next_protos = SpdyNextProtos(); 11762 ClientSocketPoolManager::set_max_sockets_per_group( 11763 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 11764 ClientSocketPoolManager::set_max_sockets_per_pool( 11765 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 11766 11767 // Use two different hosts with different IPs so they don't get pooled. 11768 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1"); 11769 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2"); 11770 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11771 11772 SSLSocketDataProvider ssl1(ASYNC, OK); 11773 ssl1.SetNextProto(GetParam()); 11774 SSLSocketDataProvider ssl2(ASYNC, OK); 11775 ssl2.SetNextProto(GetParam()); 11776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); 11777 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); 11778 11779 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet( 11780 "https://www.a.com", false, 1, DEFAULT_PRIORITY)); 11781 MockWrite spdy1_writes[] = { 11782 CreateMockWrite(*host1_req, 1), 11783 }; 11784 scoped_ptr<SpdyFrame> host1_resp( 11785 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11786 scoped_ptr<SpdyFrame> host1_resp_body( 11787 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11788 MockRead spdy1_reads[] = { 11789 CreateMockRead(*host1_resp, 2), 11790 CreateMockRead(*host1_resp_body, 3), 11791 MockRead(ASYNC, ERR_IO_PENDING, 4), 11792 }; 11793 11794 scoped_ptr<OrderedSocketData> spdy1_data( 11795 new OrderedSocketData( 11796 spdy1_reads, arraysize(spdy1_reads), 11797 spdy1_writes, arraysize(spdy1_writes))); 11798 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get()); 11799 11800 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet( 11801 "https://www.b.com", false, 1, DEFAULT_PRIORITY)); 11802 MockWrite spdy2_writes[] = { 11803 CreateMockWrite(*host2_req, 1), 11804 }; 11805 scoped_ptr<SpdyFrame> host2_resp( 11806 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 11807 scoped_ptr<SpdyFrame> host2_resp_body( 11808 spdy_util_.ConstructSpdyBodyFrame(1, true)); 11809 MockRead spdy2_reads[] = { 11810 CreateMockRead(*host2_resp, 2), 11811 CreateMockRead(*host2_resp_body, 3), 11812 MockRead(ASYNC, ERR_IO_PENDING, 4), 11813 }; 11814 11815 scoped_ptr<OrderedSocketData> spdy2_data( 11816 new OrderedSocketData( 11817 spdy2_reads, arraysize(spdy2_reads), 11818 spdy2_writes, arraysize(spdy2_writes))); 11819 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get()); 11820 11821 MockWrite http_write[] = { 11822 MockWrite("GET / HTTP/1.1\r\n" 11823 "Host: www.a.com\r\n" 11824 "Connection: keep-alive\r\n\r\n"), 11825 }; 11826 11827 MockRead http_read[] = { 11828 MockRead("HTTP/1.1 200 OK\r\n"), 11829 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 11830 MockRead("Content-Length: 6\r\n\r\n"), 11831 MockRead("hello!"), 11832 }; 11833 StaticSocketDataProvider http_data(http_read, arraysize(http_read), 11834 http_write, arraysize(http_write)); 11835 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 11836 11837 HostPortPair host_port_pair_a("www.a.com", 443); 11838 SpdySessionKey spdy_session_key_a( 11839 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 11840 EXPECT_FALSE( 11841 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11842 11843 TestCompletionCallback callback; 11844 HttpRequestInfo request1; 11845 request1.method = "GET"; 11846 request1.url = GURL("https://www.a.com/"); 11847 request1.load_flags = 0; 11848 scoped_ptr<HttpNetworkTransaction> trans( 11849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11850 11851 int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); 11852 EXPECT_EQ(ERR_IO_PENDING, rv); 11853 EXPECT_EQ(OK, callback.WaitForResult()); 11854 11855 const HttpResponseInfo* response = trans->GetResponseInfo(); 11856 ASSERT_TRUE(response != NULL); 11857 ASSERT_TRUE(response->headers.get() != NULL); 11858 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11859 EXPECT_TRUE(response->was_fetched_via_spdy); 11860 EXPECT_TRUE(response->was_npn_negotiated); 11861 11862 std::string response_data; 11863 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11864 EXPECT_EQ("hello!", response_data); 11865 trans.reset(); 11866 EXPECT_TRUE( 11867 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11868 11869 HostPortPair host_port_pair_b("www.b.com", 443); 11870 SpdySessionKey spdy_session_key_b( 11871 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 11872 EXPECT_FALSE( 11873 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11874 HttpRequestInfo request2; 11875 request2.method = "GET"; 11876 request2.url = GURL("https://www.b.com/"); 11877 request2.load_flags = 0; 11878 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11879 11880 rv = trans->Start(&request2, callback.callback(), BoundNetLog()); 11881 EXPECT_EQ(ERR_IO_PENDING, rv); 11882 EXPECT_EQ(OK, callback.WaitForResult()); 11883 11884 response = trans->GetResponseInfo(); 11885 ASSERT_TRUE(response != NULL); 11886 ASSERT_TRUE(response->headers.get() != NULL); 11887 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11888 EXPECT_TRUE(response->was_fetched_via_spdy); 11889 EXPECT_TRUE(response->was_npn_negotiated); 11890 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11891 EXPECT_EQ("hello!", response_data); 11892 EXPECT_FALSE( 11893 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11894 EXPECT_TRUE( 11895 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11896 11897 HostPortPair host_port_pair_a1("www.a.com", 80); 11898 SpdySessionKey spdy_session_key_a1( 11899 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 11900 EXPECT_FALSE( 11901 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1)); 11902 HttpRequestInfo request3; 11903 request3.method = "GET"; 11904 request3.url = GURL("http://www.a.com/"); 11905 request3.load_flags = 0; 11906 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 11907 11908 rv = trans->Start(&request3, callback.callback(), BoundNetLog()); 11909 EXPECT_EQ(ERR_IO_PENDING, rv); 11910 EXPECT_EQ(OK, callback.WaitForResult()); 11911 11912 response = trans->GetResponseInfo(); 11913 ASSERT_TRUE(response != NULL); 11914 ASSERT_TRUE(response->headers.get() != NULL); 11915 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 11916 EXPECT_FALSE(response->was_fetched_via_spdy); 11917 EXPECT_FALSE(response->was_npn_negotiated); 11918 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 11919 EXPECT_EQ("hello!", response_data); 11920 EXPECT_FALSE( 11921 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a)); 11922 EXPECT_FALSE( 11923 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b)); 11924 } 11925 11926 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) { 11927 HttpRequestInfo request; 11928 request.method = "GET"; 11929 request.url = GURL("http://www.google.com/"); 11930 request.load_flags = 0; 11931 11932 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11933 scoped_ptr<HttpTransaction> trans( 11934 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11935 11936 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED); 11937 StaticSocketDataProvider data; 11938 data.set_connect_data(mock_connect); 11939 session_deps_.socket_factory->AddSocketDataProvider(&data); 11940 11941 TestCompletionCallback callback; 11942 11943 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11944 EXPECT_EQ(ERR_IO_PENDING, rv); 11945 11946 rv = callback.WaitForResult(); 11947 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); 11948 11949 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11950 11951 // We don't care whether this succeeds or fails, but it shouldn't crash. 11952 HttpRequestHeaders request_headers; 11953 trans->GetFullRequestHeaders(&request_headers); 11954 } 11955 11956 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) { 11957 HttpRequestInfo request; 11958 request.method = "GET"; 11959 request.url = GURL("http://www.google.com/"); 11960 request.load_flags = 0; 11961 11962 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11963 scoped_ptr<HttpTransaction> trans( 11964 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11965 11966 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 11967 StaticSocketDataProvider data; 11968 data.set_connect_data(mock_connect); 11969 session_deps_.socket_factory->AddSocketDataProvider(&data); 11970 11971 TestCompletionCallback callback; 11972 11973 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 11974 EXPECT_EQ(ERR_IO_PENDING, rv); 11975 11976 rv = callback.WaitForResult(); 11977 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); 11978 11979 EXPECT_EQ(NULL, trans->GetResponseInfo()); 11980 11981 // We don't care whether this succeeds or fails, but it shouldn't crash. 11982 HttpRequestHeaders request_headers; 11983 trans->GetFullRequestHeaders(&request_headers); 11984 } 11985 11986 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) { 11987 HttpRequestInfo request; 11988 request.method = "GET"; 11989 request.url = GURL("http://www.google.com/"); 11990 request.load_flags = 0; 11991 11992 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 11993 scoped_ptr<HttpTransaction> trans( 11994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 11995 11996 MockWrite data_writes[] = { 11997 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 11998 }; 11999 MockRead data_reads[] = { 12000 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 12001 }; 12002 12003 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12004 data_writes, arraysize(data_writes)); 12005 session_deps_.socket_factory->AddSocketDataProvider(&data); 12006 12007 TestCompletionCallback callback; 12008 12009 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12010 EXPECT_EQ(ERR_IO_PENDING, rv); 12011 12012 rv = callback.WaitForResult(); 12013 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12014 12015 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12016 12017 HttpRequestHeaders request_headers; 12018 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12019 EXPECT_TRUE(request_headers.HasHeader("Host")); 12020 } 12021 12022 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) { 12023 HttpRequestInfo request; 12024 request.method = "GET"; 12025 request.url = GURL("http://www.google.com/"); 12026 request.load_flags = 0; 12027 12028 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12029 scoped_ptr<HttpTransaction> trans( 12030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12031 12032 MockWrite data_writes[] = { 12033 MockWrite(ASYNC, ERR_CONNECTION_RESET), 12034 }; 12035 MockRead data_reads[] = { 12036 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached. 12037 }; 12038 12039 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12040 data_writes, arraysize(data_writes)); 12041 session_deps_.socket_factory->AddSocketDataProvider(&data); 12042 12043 TestCompletionCallback callback; 12044 12045 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12046 EXPECT_EQ(ERR_IO_PENDING, rv); 12047 12048 rv = callback.WaitForResult(); 12049 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12050 12051 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12052 12053 HttpRequestHeaders request_headers; 12054 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12055 EXPECT_TRUE(request_headers.HasHeader("Host")); 12056 } 12057 12058 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) { 12059 HttpRequestInfo request; 12060 request.method = "GET"; 12061 request.url = GURL("http://www.google.com/"); 12062 request.load_flags = 0; 12063 12064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12065 scoped_ptr<HttpTransaction> trans( 12066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12067 12068 MockWrite data_writes[] = { 12069 MockWrite("GET / HTTP/1.1\r\n" 12070 "Host: www.google.com\r\n" 12071 "Connection: keep-alive\r\n\r\n"), 12072 }; 12073 MockRead data_reads[] = { 12074 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET), 12075 }; 12076 12077 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12078 data_writes, arraysize(data_writes)); 12079 session_deps_.socket_factory->AddSocketDataProvider(&data); 12080 12081 TestCompletionCallback callback; 12082 12083 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12084 EXPECT_EQ(ERR_IO_PENDING, rv); 12085 12086 rv = callback.WaitForResult(); 12087 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12088 12089 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12090 12091 HttpRequestHeaders request_headers; 12092 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12093 EXPECT_TRUE(request_headers.HasHeader("Host")); 12094 } 12095 12096 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) { 12097 HttpRequestInfo request; 12098 request.method = "GET"; 12099 request.url = GURL("http://www.google.com/"); 12100 request.load_flags = 0; 12101 12102 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12103 scoped_ptr<HttpTransaction> trans( 12104 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12105 12106 MockWrite data_writes[] = { 12107 MockWrite("GET / HTTP/1.1\r\n" 12108 "Host: www.google.com\r\n" 12109 "Connection: keep-alive\r\n\r\n"), 12110 }; 12111 MockRead data_reads[] = { 12112 MockRead(ASYNC, ERR_CONNECTION_RESET), 12113 }; 12114 12115 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12116 data_writes, arraysize(data_writes)); 12117 session_deps_.socket_factory->AddSocketDataProvider(&data); 12118 12119 TestCompletionCallback callback; 12120 12121 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12122 EXPECT_EQ(ERR_IO_PENDING, rv); 12123 12124 rv = callback.WaitForResult(); 12125 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 12126 12127 EXPECT_EQ(NULL, trans->GetResponseInfo()); 12128 12129 HttpRequestHeaders request_headers; 12130 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12131 EXPECT_TRUE(request_headers.HasHeader("Host")); 12132 } 12133 12134 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) { 12135 HttpRequestInfo request; 12136 request.method = "GET"; 12137 request.url = GURL("http://www.google.com/"); 12138 request.load_flags = 0; 12139 request.extra_headers.SetHeader("X-Foo", "bar"); 12140 12141 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12142 scoped_ptr<HttpTransaction> trans( 12143 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12144 12145 MockWrite data_writes[] = { 12146 MockWrite("GET / HTTP/1.1\r\n" 12147 "Host: www.google.com\r\n" 12148 "Connection: keep-alive\r\n" 12149 "X-Foo: bar\r\n\r\n"), 12150 }; 12151 MockRead data_reads[] = { 12152 MockRead("HTTP/1.1 200 OK\r\n" 12153 "Content-Length: 5\r\n\r\n" 12154 "hello"), 12155 MockRead(ASYNC, ERR_UNEXPECTED), 12156 }; 12157 12158 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 12159 data_writes, arraysize(data_writes)); 12160 session_deps_.socket_factory->AddSocketDataProvider(&data); 12161 12162 TestCompletionCallback callback; 12163 12164 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12165 EXPECT_EQ(ERR_IO_PENDING, rv); 12166 12167 rv = callback.WaitForResult(); 12168 EXPECT_EQ(OK, rv); 12169 12170 HttpRequestHeaders request_headers; 12171 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); 12172 std::string foo; 12173 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo)); 12174 EXPECT_EQ("bar", foo); 12175 } 12176 12177 namespace { 12178 12179 // Fake HttpStreamBase that simply records calls to SetPriority(). 12180 class FakeStream : public HttpStreamBase, 12181 public base::SupportsWeakPtr<FakeStream> { 12182 public: 12183 explicit FakeStream(RequestPriority priority) : priority_(priority) {} 12184 virtual ~FakeStream() {} 12185 12186 RequestPriority priority() const { return priority_; } 12187 12188 virtual int InitializeStream(const HttpRequestInfo* request_info, 12189 RequestPriority priority, 12190 const BoundNetLog& net_log, 12191 const CompletionCallback& callback) OVERRIDE { 12192 return ERR_IO_PENDING; 12193 } 12194 12195 virtual int SendRequest(const HttpRequestHeaders& request_headers, 12196 HttpResponseInfo* response, 12197 const CompletionCallback& callback) OVERRIDE { 12198 ADD_FAILURE(); 12199 return ERR_UNEXPECTED; 12200 } 12201 12202 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE { 12203 ADD_FAILURE(); 12204 return ERR_UNEXPECTED; 12205 } 12206 12207 virtual int ReadResponseBody(IOBuffer* buf, int buf_len, 12208 const CompletionCallback& callback) OVERRIDE { 12209 ADD_FAILURE(); 12210 return ERR_UNEXPECTED; 12211 } 12212 12213 virtual void Close(bool not_reusable) OVERRIDE {} 12214 12215 virtual bool IsResponseBodyComplete() const OVERRIDE { 12216 ADD_FAILURE(); 12217 return false; 12218 } 12219 12220 virtual bool CanFindEndOfResponse() const OVERRIDE { 12221 return false; 12222 } 12223 12224 virtual bool IsConnectionReused() const OVERRIDE { 12225 ADD_FAILURE(); 12226 return false; 12227 } 12228 12229 virtual void SetConnectionReused() OVERRIDE { 12230 ADD_FAILURE(); 12231 } 12232 12233 virtual bool IsConnectionReusable() const OVERRIDE { 12234 ADD_FAILURE(); 12235 return false; 12236 } 12237 12238 virtual int64 GetTotalReceivedBytes() const OVERRIDE { 12239 ADD_FAILURE(); 12240 return 0; 12241 } 12242 12243 virtual bool GetLoadTimingInfo( 12244 LoadTimingInfo* load_timing_info) const OVERRIDE { 12245 ADD_FAILURE(); 12246 return false; 12247 } 12248 12249 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { 12250 ADD_FAILURE(); 12251 } 12252 12253 virtual void GetSSLCertRequestInfo( 12254 SSLCertRequestInfo* cert_request_info) OVERRIDE { 12255 ADD_FAILURE(); 12256 } 12257 12258 virtual bool IsSpdyHttpStream() const OVERRIDE { 12259 ADD_FAILURE(); 12260 return false; 12261 } 12262 12263 virtual void Drain(HttpNetworkSession* session) OVERRIDE { 12264 ADD_FAILURE(); 12265 } 12266 12267 virtual void SetPriority(RequestPriority priority) OVERRIDE { 12268 priority_ = priority; 12269 } 12270 12271 private: 12272 RequestPriority priority_; 12273 12274 DISALLOW_COPY_AND_ASSIGN(FakeStream); 12275 }; 12276 12277 // Fake HttpStreamRequest that simply records calls to SetPriority() 12278 // and vends FakeStreams with its current priority. 12279 class FakeStreamRequest : public HttpStreamRequest, 12280 public base::SupportsWeakPtr<FakeStreamRequest> { 12281 public: 12282 FakeStreamRequest(RequestPriority priority, 12283 HttpStreamRequest::Delegate* delegate) 12284 : priority_(priority), 12285 delegate_(delegate), 12286 websocket_stream_create_helper_(NULL) {} 12287 12288 FakeStreamRequest(RequestPriority priority, 12289 HttpStreamRequest::Delegate* delegate, 12290 WebSocketHandshakeStreamBase::CreateHelper* create_helper) 12291 : priority_(priority), 12292 delegate_(delegate), 12293 websocket_stream_create_helper_(create_helper) {} 12294 12295 virtual ~FakeStreamRequest() {} 12296 12297 RequestPriority priority() const { return priority_; } 12298 12299 const WebSocketHandshakeStreamBase::CreateHelper* 12300 websocket_stream_create_helper() const { 12301 return websocket_stream_create_helper_; 12302 } 12303 12304 // Create a new FakeStream and pass it to the request's 12305 // delegate. Returns a weak pointer to the FakeStream. 12306 base::WeakPtr<FakeStream> FinishStreamRequest() { 12307 FakeStream* fake_stream = new FakeStream(priority_); 12308 // Do this before calling OnStreamReady() as OnStreamReady() may 12309 // immediately delete |fake_stream|. 12310 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr(); 12311 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream); 12312 return weak_stream; 12313 } 12314 12315 virtual int RestartTunnelWithProxyAuth( 12316 const AuthCredentials& credentials) OVERRIDE { 12317 ADD_FAILURE(); 12318 return ERR_UNEXPECTED; 12319 } 12320 12321 virtual LoadState GetLoadState() const OVERRIDE { 12322 ADD_FAILURE(); 12323 return LoadState(); 12324 } 12325 12326 virtual void SetPriority(RequestPriority priority) OVERRIDE { 12327 priority_ = priority; 12328 } 12329 12330 virtual bool was_npn_negotiated() const OVERRIDE { 12331 return false; 12332 } 12333 12334 virtual NextProto protocol_negotiated() const OVERRIDE { 12335 return kProtoUnknown; 12336 } 12337 12338 virtual bool using_spdy() const OVERRIDE { 12339 return false; 12340 } 12341 12342 private: 12343 RequestPriority priority_; 12344 HttpStreamRequest::Delegate* const delegate_; 12345 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_; 12346 12347 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest); 12348 }; 12349 12350 // Fake HttpStreamFactory that vends FakeStreamRequests. 12351 class FakeStreamFactory : public HttpStreamFactory { 12352 public: 12353 FakeStreamFactory() {} 12354 virtual ~FakeStreamFactory() {} 12355 12356 // Returns a WeakPtr<> to the last HttpStreamRequest returned by 12357 // RequestStream() (which may be NULL if it was destroyed already). 12358 base::WeakPtr<FakeStreamRequest> last_stream_request() { 12359 return last_stream_request_; 12360 } 12361 12362 virtual HttpStreamRequest* RequestStream( 12363 const HttpRequestInfo& info, 12364 RequestPriority priority, 12365 const SSLConfig& server_ssl_config, 12366 const SSLConfig& proxy_ssl_config, 12367 HttpStreamRequest::Delegate* delegate, 12368 const BoundNetLog& net_log) OVERRIDE { 12369 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate); 12370 last_stream_request_ = fake_request->AsWeakPtr(); 12371 return fake_request; 12372 } 12373 12374 virtual HttpStreamRequest* RequestWebSocketHandshakeStream( 12375 const HttpRequestInfo& info, 12376 RequestPriority priority, 12377 const SSLConfig& server_ssl_config, 12378 const SSLConfig& proxy_ssl_config, 12379 HttpStreamRequest::Delegate* delegate, 12380 WebSocketHandshakeStreamBase::CreateHelper* create_helper, 12381 const BoundNetLog& net_log) OVERRIDE { 12382 FakeStreamRequest* fake_request = 12383 new FakeStreamRequest(priority, delegate, create_helper); 12384 last_stream_request_ = fake_request->AsWeakPtr(); 12385 return fake_request; 12386 } 12387 12388 virtual void PreconnectStreams(int num_streams, 12389 const HttpRequestInfo& info, 12390 RequestPriority priority, 12391 const SSLConfig& server_ssl_config, 12392 const SSLConfig& proxy_ssl_config) OVERRIDE { 12393 ADD_FAILURE(); 12394 } 12395 12396 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE { 12397 ADD_FAILURE(); 12398 return NULL; 12399 } 12400 12401 private: 12402 base::WeakPtr<FakeStreamRequest> last_stream_request_; 12403 12404 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory); 12405 }; 12406 12407 // TODO(yhirano): Split this class out into a net/websockets file, if it is 12408 // worth doing. 12409 class FakeWebSocketStreamCreateHelper : 12410 public WebSocketHandshakeStreamBase::CreateHelper { 12411 public: 12412 virtual WebSocketHandshakeStreamBase* CreateBasicStream( 12413 scoped_ptr<ClientSocketHandle> connection, 12414 bool using_proxy) OVERRIDE { 12415 NOTREACHED(); 12416 return NULL; 12417 } 12418 12419 virtual WebSocketHandshakeStreamBase* CreateSpdyStream( 12420 const base::WeakPtr<SpdySession>& session, 12421 bool use_relative_url) OVERRIDE { 12422 NOTREACHED(); 12423 return NULL; 12424 }; 12425 12426 virtual ~FakeWebSocketStreamCreateHelper() {} 12427 12428 virtual scoped_ptr<WebSocketStream> Upgrade() { 12429 NOTREACHED(); 12430 return scoped_ptr<WebSocketStream>(); 12431 } 12432 }; 12433 12434 } // namespace 12435 12436 // Make sure that HttpNetworkTransaction passes on its priority to its 12437 // stream request on start. 12438 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) { 12439 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12440 HttpNetworkSessionPeer peer(session); 12441 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12442 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12443 12444 HttpNetworkTransaction trans(LOW, session); 12445 12446 ASSERT_TRUE(fake_factory->last_stream_request() == NULL); 12447 12448 HttpRequestInfo request; 12449 TestCompletionCallback callback; 12450 EXPECT_EQ(ERR_IO_PENDING, 12451 trans.Start(&request, callback.callback(), BoundNetLog())); 12452 12453 base::WeakPtr<FakeStreamRequest> fake_request = 12454 fake_factory->last_stream_request(); 12455 ASSERT_TRUE(fake_request != NULL); 12456 EXPECT_EQ(LOW, fake_request->priority()); 12457 } 12458 12459 // Make sure that HttpNetworkTransaction passes on its priority 12460 // updates to its stream request. 12461 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) { 12462 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12463 HttpNetworkSessionPeer peer(session); 12464 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12465 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12466 12467 HttpNetworkTransaction trans(LOW, session); 12468 12469 HttpRequestInfo request; 12470 TestCompletionCallback callback; 12471 EXPECT_EQ(ERR_IO_PENDING, 12472 trans.Start(&request, callback.callback(), BoundNetLog())); 12473 12474 base::WeakPtr<FakeStreamRequest> fake_request = 12475 fake_factory->last_stream_request(); 12476 ASSERT_TRUE(fake_request != NULL); 12477 EXPECT_EQ(LOW, fake_request->priority()); 12478 12479 trans.SetPriority(LOWEST); 12480 ASSERT_TRUE(fake_request != NULL); 12481 EXPECT_EQ(LOWEST, fake_request->priority()); 12482 } 12483 12484 // Make sure that HttpNetworkTransaction passes on its priority 12485 // updates to its stream. 12486 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) { 12487 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12488 HttpNetworkSessionPeer peer(session); 12489 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12490 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); 12491 12492 HttpNetworkTransaction trans(LOW, session); 12493 12494 HttpRequestInfo request; 12495 TestCompletionCallback callback; 12496 EXPECT_EQ(ERR_IO_PENDING, 12497 trans.Start(&request, callback.callback(), BoundNetLog())); 12498 12499 base::WeakPtr<FakeStreamRequest> fake_request = 12500 fake_factory->last_stream_request(); 12501 ASSERT_TRUE(fake_request != NULL); 12502 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest(); 12503 ASSERT_TRUE(fake_stream != NULL); 12504 EXPECT_EQ(LOW, fake_stream->priority()); 12505 12506 trans.SetPriority(LOWEST); 12507 EXPECT_EQ(LOWEST, fake_stream->priority()); 12508 } 12509 12510 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) { 12511 // The same logic needs to be tested for both ws: and wss: schemes, but this 12512 // test is already parameterised on NextProto, so it uses a loop to verify 12513 // that the different schemes work. 12514 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"}; 12515 for (size_t i = 0; i < arraysize(test_cases); ++i) { 12516 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12517 HttpNetworkSessionPeer peer(session); 12518 FakeStreamFactory* fake_factory = new FakeStreamFactory(); 12519 FakeWebSocketStreamCreateHelper websocket_stream_create_helper; 12520 peer.SetHttpStreamFactoryForWebSocket( 12521 scoped_ptr<HttpStreamFactory>(fake_factory)); 12522 12523 HttpNetworkTransaction trans(LOW, session); 12524 trans.SetWebSocketHandshakeStreamCreateHelper( 12525 &websocket_stream_create_helper); 12526 12527 HttpRequestInfo request; 12528 TestCompletionCallback callback; 12529 request.method = "GET"; 12530 request.url = GURL(test_cases[i]); 12531 12532 EXPECT_EQ(ERR_IO_PENDING, 12533 trans.Start(&request, callback.callback(), BoundNetLog())); 12534 12535 base::WeakPtr<FakeStreamRequest> fake_request = 12536 fake_factory->last_stream_request(); 12537 ASSERT_TRUE(fake_request != NULL); 12538 EXPECT_EQ(&websocket_stream_create_helper, 12539 fake_request->websocket_stream_create_helper()); 12540 } 12541 } 12542 12543 // Tests that when a used socket is returned to the SSL socket pool, it's closed 12544 // if the transport socket pool is stalled on the global socket limit. 12545 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) { 12546 ClientSocketPoolManager::set_max_sockets_per_group( 12547 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12548 ClientSocketPoolManager::set_max_sockets_per_pool( 12549 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12550 12551 // Set up SSL request. 12552 12553 HttpRequestInfo ssl_request; 12554 ssl_request.method = "GET"; 12555 ssl_request.url = GURL("https://www.google.com/"); 12556 12557 MockWrite ssl_writes[] = { 12558 MockWrite("GET / HTTP/1.1\r\n" 12559 "Host: www.google.com\r\n" 12560 "Connection: keep-alive\r\n\r\n"), 12561 }; 12562 MockRead ssl_reads[] = { 12563 MockRead("HTTP/1.1 200 OK\r\n"), 12564 MockRead("Content-Length: 11\r\n\r\n"), 12565 MockRead("hello world"), 12566 MockRead(SYNCHRONOUS, OK), 12567 }; 12568 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads), 12569 ssl_writes, arraysize(ssl_writes)); 12570 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data); 12571 12572 SSLSocketDataProvider ssl(ASYNC, OK); 12573 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 12574 12575 // Set up HTTP request. 12576 12577 HttpRequestInfo http_request; 12578 http_request.method = "GET"; 12579 http_request.url = GURL("http://www.google.com/"); 12580 12581 MockWrite http_writes[] = { 12582 MockWrite("GET / HTTP/1.1\r\n" 12583 "Host: www.google.com\r\n" 12584 "Connection: keep-alive\r\n\r\n"), 12585 }; 12586 MockRead http_reads[] = { 12587 MockRead("HTTP/1.1 200 OK\r\n"), 12588 MockRead("Content-Length: 7\r\n\r\n"), 12589 MockRead("falafel"), 12590 MockRead(SYNCHRONOUS, OK), 12591 }; 12592 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 12593 http_writes, arraysize(http_writes)); 12594 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 12595 12596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12597 12598 // Start the SSL request. 12599 TestCompletionCallback ssl_callback; 12600 scoped_ptr<HttpTransaction> ssl_trans( 12601 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12602 ASSERT_EQ(ERR_IO_PENDING, 12603 ssl_trans->Start(&ssl_request, ssl_callback.callback(), 12604 BoundNetLog())); 12605 12606 // Start the HTTP request. Pool should stall. 12607 TestCompletionCallback http_callback; 12608 scoped_ptr<HttpTransaction> http_trans( 12609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12610 ASSERT_EQ(ERR_IO_PENDING, 12611 http_trans->Start(&http_request, http_callback.callback(), 12612 BoundNetLog())); 12613 EXPECT_TRUE(IsTransportSocketPoolStalled(session)); 12614 12615 // Wait for response from SSL request. 12616 ASSERT_EQ(OK, ssl_callback.WaitForResult()); 12617 std::string response_data; 12618 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data)); 12619 EXPECT_EQ("hello world", response_data); 12620 12621 // The SSL socket should automatically be closed, so the HTTP request can 12622 // start. 12623 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session)); 12624 ASSERT_FALSE(IsTransportSocketPoolStalled(session)); 12625 12626 // The HTTP request can now complete. 12627 ASSERT_EQ(OK, http_callback.WaitForResult()); 12628 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data)); 12629 EXPECT_EQ("falafel", response_data); 12630 12631 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session)); 12632 } 12633 12634 // Tests that when a SSL connection is established but there's no corresponding 12635 // request that needs it, the new socket is closed if the transport socket pool 12636 // is stalled on the global socket limit. 12637 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) { 12638 ClientSocketPoolManager::set_max_sockets_per_group( 12639 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12640 ClientSocketPoolManager::set_max_sockets_per_pool( 12641 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 12642 12643 // Set up an ssl request. 12644 12645 HttpRequestInfo ssl_request; 12646 ssl_request.method = "GET"; 12647 ssl_request.url = GURL("https://www.foopy.com/"); 12648 12649 // No data will be sent on the SSL socket. 12650 StaticSocketDataProvider ssl_data; 12651 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data); 12652 12653 SSLSocketDataProvider ssl(ASYNC, OK); 12654 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 12655 12656 // Set up HTTP request. 12657 12658 HttpRequestInfo http_request; 12659 http_request.method = "GET"; 12660 http_request.url = GURL("http://www.google.com/"); 12661 12662 MockWrite http_writes[] = { 12663 MockWrite("GET / HTTP/1.1\r\n" 12664 "Host: www.google.com\r\n" 12665 "Connection: keep-alive\r\n\r\n"), 12666 }; 12667 MockRead http_reads[] = { 12668 MockRead("HTTP/1.1 200 OK\r\n"), 12669 MockRead("Content-Length: 7\r\n\r\n"), 12670 MockRead("falafel"), 12671 MockRead(SYNCHRONOUS, OK), 12672 }; 12673 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 12674 http_writes, arraysize(http_writes)); 12675 session_deps_.socket_factory->AddSocketDataProvider(&http_data); 12676 12677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12678 12679 // Preconnect an SSL socket. A preconnect is needed because connect jobs are 12680 // cancelled when a normal transaction is cancelled. 12681 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory(); 12682 net::SSLConfig ssl_config; 12683 session->ssl_config_service()->GetSSLConfig(&ssl_config); 12684 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY, 12685 ssl_config, ssl_config); 12686 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session)); 12687 12688 // Start the HTTP request. Pool should stall. 12689 TestCompletionCallback http_callback; 12690 scoped_ptr<HttpTransaction> http_trans( 12691 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 12692 ASSERT_EQ(ERR_IO_PENDING, 12693 http_trans->Start(&http_request, http_callback.callback(), 12694 BoundNetLog())); 12695 EXPECT_TRUE(IsTransportSocketPoolStalled(session)); 12696 12697 // The SSL connection will automatically be closed once the connection is 12698 // established, to let the HTTP request start. 12699 ASSERT_EQ(OK, http_callback.WaitForResult()); 12700 std::string response_data; 12701 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data)); 12702 EXPECT_EQ("falafel", response_data); 12703 12704 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session)); 12705 } 12706 12707 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) { 12708 ScopedVector<UploadElementReader> element_readers; 12709 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12710 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12711 12712 HttpRequestInfo request; 12713 request.method = "POST"; 12714 request.url = GURL("http://www.foo.com/"); 12715 request.upload_data_stream = &upload_data_stream; 12716 request.load_flags = 0; 12717 12718 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12719 scoped_ptr<HttpTransaction> trans( 12720 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12721 // Send headers successfully, but get an error while sending the body. 12722 MockWrite data_writes[] = { 12723 MockWrite("POST / HTTP/1.1\r\n" 12724 "Host: www.foo.com\r\n" 12725 "Connection: keep-alive\r\n" 12726 "Content-Length: 3\r\n\r\n"), 12727 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12728 }; 12729 12730 MockRead data_reads[] = { 12731 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 12732 MockRead("hello world"), 12733 MockRead(SYNCHRONOUS, OK), 12734 }; 12735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12736 arraysize(data_writes)); 12737 session_deps_.socket_factory->AddSocketDataProvider(&data); 12738 12739 TestCompletionCallback callback; 12740 12741 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12742 EXPECT_EQ(ERR_IO_PENDING, rv); 12743 12744 rv = callback.WaitForResult(); 12745 EXPECT_EQ(OK, rv); 12746 12747 const HttpResponseInfo* response = trans->GetResponseInfo(); 12748 ASSERT_TRUE(response != NULL); 12749 12750 EXPECT_TRUE(response->headers.get() != NULL); 12751 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 12752 12753 std::string response_data; 12754 rv = ReadTransaction(trans.get(), &response_data); 12755 EXPECT_EQ(OK, rv); 12756 EXPECT_EQ("hello world", response_data); 12757 } 12758 12759 // This test makes sure the retry logic doesn't trigger when reading an error 12760 // response from a server that rejected a POST with a CONNECTION_RESET. 12761 TEST_P(HttpNetworkTransactionTest, 12762 PostReadsErrorResponseAfterResetOnReusedSocket) { 12763 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12764 MockWrite data_writes[] = { 12765 MockWrite("GET / HTTP/1.1\r\n" 12766 "Host: www.foo.com\r\n" 12767 "Connection: keep-alive\r\n\r\n"), 12768 MockWrite("POST / HTTP/1.1\r\n" 12769 "Host: www.foo.com\r\n" 12770 "Connection: keep-alive\r\n" 12771 "Content-Length: 3\r\n\r\n"), 12772 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12773 }; 12774 12775 MockRead data_reads[] = { 12776 MockRead("HTTP/1.1 200 Peachy\r\n" 12777 "Content-Length: 14\r\n\r\n"), 12778 MockRead("first response"), 12779 MockRead("HTTP/1.1 400 Not OK\r\n" 12780 "Content-Length: 15\r\n\r\n"), 12781 MockRead("second response"), 12782 MockRead(SYNCHRONOUS, OK), 12783 }; 12784 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12785 arraysize(data_writes)); 12786 session_deps_.socket_factory->AddSocketDataProvider(&data); 12787 12788 TestCompletionCallback callback; 12789 HttpRequestInfo request1; 12790 request1.method = "GET"; 12791 request1.url = GURL("http://www.foo.com/"); 12792 request1.load_flags = 0; 12793 12794 scoped_ptr<HttpTransaction> trans1( 12795 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12796 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); 12797 EXPECT_EQ(ERR_IO_PENDING, rv); 12798 12799 rv = callback.WaitForResult(); 12800 EXPECT_EQ(OK, rv); 12801 12802 const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 12803 ASSERT_TRUE(response1 != NULL); 12804 12805 EXPECT_TRUE(response1->headers.get() != NULL); 12806 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine()); 12807 12808 std::string response_data1; 12809 rv = ReadTransaction(trans1.get(), &response_data1); 12810 EXPECT_EQ(OK, rv); 12811 EXPECT_EQ("first response", response_data1); 12812 // Delete the transaction to release the socket back into the socket pool. 12813 trans1.reset(); 12814 12815 ScopedVector<UploadElementReader> element_readers; 12816 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12817 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12818 12819 HttpRequestInfo request2; 12820 request2.method = "POST"; 12821 request2.url = GURL("http://www.foo.com/"); 12822 request2.upload_data_stream = &upload_data_stream; 12823 request2.load_flags = 0; 12824 12825 scoped_ptr<HttpTransaction> trans2( 12826 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12827 rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); 12828 EXPECT_EQ(ERR_IO_PENDING, rv); 12829 12830 rv = callback.WaitForResult(); 12831 EXPECT_EQ(OK, rv); 12832 12833 const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 12834 ASSERT_TRUE(response2 != NULL); 12835 12836 EXPECT_TRUE(response2->headers.get() != NULL); 12837 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine()); 12838 12839 std::string response_data2; 12840 rv = ReadTransaction(trans2.get(), &response_data2); 12841 EXPECT_EQ(OK, rv); 12842 EXPECT_EQ("second response", response_data2); 12843 } 12844 12845 TEST_P(HttpNetworkTransactionTest, 12846 PostReadsErrorResponseAfterResetPartialBodySent) { 12847 ScopedVector<UploadElementReader> element_readers; 12848 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12849 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12850 12851 HttpRequestInfo request; 12852 request.method = "POST"; 12853 request.url = GURL("http://www.foo.com/"); 12854 request.upload_data_stream = &upload_data_stream; 12855 request.load_flags = 0; 12856 12857 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12858 scoped_ptr<HttpTransaction> trans( 12859 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12860 // Send headers successfully, but get an error while sending the body. 12861 MockWrite data_writes[] = { 12862 MockWrite("POST / HTTP/1.1\r\n" 12863 "Host: www.foo.com\r\n" 12864 "Connection: keep-alive\r\n" 12865 "Content-Length: 3\r\n\r\n" 12866 "fo"), 12867 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12868 }; 12869 12870 MockRead data_reads[] = { 12871 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 12872 MockRead("hello world"), 12873 MockRead(SYNCHRONOUS, OK), 12874 }; 12875 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12876 arraysize(data_writes)); 12877 session_deps_.socket_factory->AddSocketDataProvider(&data); 12878 12879 TestCompletionCallback callback; 12880 12881 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12882 EXPECT_EQ(ERR_IO_PENDING, rv); 12883 12884 rv = callback.WaitForResult(); 12885 EXPECT_EQ(OK, rv); 12886 12887 const HttpResponseInfo* response = trans->GetResponseInfo(); 12888 ASSERT_TRUE(response != NULL); 12889 12890 EXPECT_TRUE(response->headers.get() != NULL); 12891 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 12892 12893 std::string response_data; 12894 rv = ReadTransaction(trans.get(), &response_data); 12895 EXPECT_EQ(OK, rv); 12896 EXPECT_EQ("hello world", response_data); 12897 } 12898 12899 // This tests the more common case than the previous test, where headers and 12900 // body are not merged into a single request. 12901 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) { 12902 ScopedVector<UploadElementReader> element_readers; 12903 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12904 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); 12905 12906 HttpRequestInfo request; 12907 request.method = "POST"; 12908 request.url = GURL("http://www.foo.com/"); 12909 request.upload_data_stream = &upload_data_stream; 12910 request.load_flags = 0; 12911 12912 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12913 scoped_ptr<HttpTransaction> trans( 12914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12915 // Send headers successfully, but get an error while sending the body. 12916 MockWrite data_writes[] = { 12917 MockWrite("POST / HTTP/1.1\r\n" 12918 "Host: www.foo.com\r\n" 12919 "Connection: keep-alive\r\n" 12920 "Transfer-Encoding: chunked\r\n\r\n"), 12921 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12922 }; 12923 12924 MockRead data_reads[] = { 12925 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 12926 MockRead("hello world"), 12927 MockRead(SYNCHRONOUS, OK), 12928 }; 12929 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12930 arraysize(data_writes)); 12931 session_deps_.socket_factory->AddSocketDataProvider(&data); 12932 12933 TestCompletionCallback callback; 12934 12935 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12936 EXPECT_EQ(ERR_IO_PENDING, rv); 12937 // Make sure the headers are sent before adding a chunk. This ensures that 12938 // they can't be merged with the body in a single send. Not currently 12939 // necessary since a chunked body is never merged with headers, but this makes 12940 // the test more future proof. 12941 base::RunLoop().RunUntilIdle(); 12942 12943 upload_data_stream.AppendChunk("last chunk", 10, true); 12944 12945 rv = callback.WaitForResult(); 12946 EXPECT_EQ(OK, rv); 12947 12948 const HttpResponseInfo* response = trans->GetResponseInfo(); 12949 ASSERT_TRUE(response != NULL); 12950 12951 EXPECT_TRUE(response->headers.get() != NULL); 12952 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 12953 12954 std::string response_data; 12955 rv = ReadTransaction(trans.get(), &response_data); 12956 EXPECT_EQ(OK, rv); 12957 EXPECT_EQ("hello world", response_data); 12958 } 12959 12960 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) { 12961 ScopedVector<UploadElementReader> element_readers; 12962 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 12963 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 12964 12965 HttpRequestInfo request; 12966 request.method = "POST"; 12967 request.url = GURL("http://www.foo.com/"); 12968 request.upload_data_stream = &upload_data_stream; 12969 request.load_flags = 0; 12970 12971 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 12972 scoped_ptr<HttpTransaction> trans( 12973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 12974 12975 MockWrite data_writes[] = { 12976 MockWrite("POST / HTTP/1.1\r\n" 12977 "Host: www.foo.com\r\n" 12978 "Connection: keep-alive\r\n" 12979 "Content-Length: 3\r\n\r\n"), 12980 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 12981 }; 12982 12983 MockRead data_reads[] = { 12984 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 12985 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"), 12986 MockRead("hello world"), 12987 MockRead(SYNCHRONOUS, OK), 12988 }; 12989 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 12990 arraysize(data_writes)); 12991 session_deps_.socket_factory->AddSocketDataProvider(&data); 12992 12993 TestCompletionCallback callback; 12994 12995 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 12996 EXPECT_EQ(ERR_IO_PENDING, rv); 12997 12998 rv = callback.WaitForResult(); 12999 EXPECT_EQ(OK, rv); 13000 13001 const HttpResponseInfo* response = trans->GetResponseInfo(); 13002 ASSERT_TRUE(response != NULL); 13003 13004 EXPECT_TRUE(response->headers.get() != NULL); 13005 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); 13006 13007 std::string response_data; 13008 rv = ReadTransaction(trans.get(), &response_data); 13009 EXPECT_EQ(OK, rv); 13010 EXPECT_EQ("hello world", response_data); 13011 } 13012 13013 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) { 13014 ScopedVector<UploadElementReader> element_readers; 13015 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13016 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13017 13018 HttpRequestInfo request; 13019 request.method = "POST"; 13020 request.url = GURL("http://www.foo.com/"); 13021 request.upload_data_stream = &upload_data_stream; 13022 request.load_flags = 0; 13023 13024 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13025 scoped_ptr<HttpTransaction> trans( 13026 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 13027 // Send headers successfully, but get an error while sending the body. 13028 MockWrite data_writes[] = { 13029 MockWrite("POST / HTTP/1.1\r\n" 13030 "Host: www.foo.com\r\n" 13031 "Connection: keep-alive\r\n" 13032 "Content-Length: 3\r\n\r\n"), 13033 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13034 }; 13035 13036 MockRead data_reads[] = { 13037 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"), 13038 MockRead("hello world"), 13039 MockRead(SYNCHRONOUS, OK), 13040 }; 13041 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13042 arraysize(data_writes)); 13043 session_deps_.socket_factory->AddSocketDataProvider(&data); 13044 13045 TestCompletionCallback callback; 13046 13047 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13048 EXPECT_EQ(ERR_IO_PENDING, rv); 13049 13050 rv = callback.WaitForResult(); 13051 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13052 13053 const HttpResponseInfo* response = trans->GetResponseInfo(); 13054 EXPECT_TRUE(response == NULL); 13055 } 13056 13057 TEST_P(HttpNetworkTransactionTest, 13058 PostIgnoresNonErrorResponseAfterResetAnd100) { 13059 ScopedVector<UploadElementReader> element_readers; 13060 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13061 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13062 13063 HttpRequestInfo request; 13064 request.method = "POST"; 13065 request.url = GURL("http://www.foo.com/"); 13066 request.upload_data_stream = &upload_data_stream; 13067 request.load_flags = 0; 13068 13069 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13070 scoped_ptr<HttpTransaction> trans( 13071 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 13072 // Send headers successfully, but get an error while sending the body. 13073 MockWrite data_writes[] = { 13074 MockWrite("POST / HTTP/1.1\r\n" 13075 "Host: www.foo.com\r\n" 13076 "Connection: keep-alive\r\n" 13077 "Content-Length: 3\r\n\r\n"), 13078 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13079 }; 13080 13081 MockRead data_reads[] = { 13082 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 13083 MockRead("HTTP/1.0 302 Redirect\r\n"), 13084 MockRead("Location: http://somewhere-else.com/\r\n"), 13085 MockRead("Content-Length: 0\r\n\r\n"), 13086 MockRead(SYNCHRONOUS, OK), 13087 }; 13088 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13089 arraysize(data_writes)); 13090 session_deps_.socket_factory->AddSocketDataProvider(&data); 13091 13092 TestCompletionCallback callback; 13093 13094 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13095 EXPECT_EQ(ERR_IO_PENDING, rv); 13096 13097 rv = callback.WaitForResult(); 13098 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13099 13100 const HttpResponseInfo* response = trans->GetResponseInfo(); 13101 EXPECT_TRUE(response == NULL); 13102 } 13103 13104 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) { 13105 ScopedVector<UploadElementReader> element_readers; 13106 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13107 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13108 13109 HttpRequestInfo request; 13110 request.method = "POST"; 13111 request.url = GURL("http://www.foo.com/"); 13112 request.upload_data_stream = &upload_data_stream; 13113 request.load_flags = 0; 13114 13115 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13116 scoped_ptr<HttpTransaction> trans( 13117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 13118 // Send headers successfully, but get an error while sending the body. 13119 MockWrite data_writes[] = { 13120 MockWrite("POST / HTTP/1.1\r\n" 13121 "Host: www.foo.com\r\n" 13122 "Connection: keep-alive\r\n" 13123 "Content-Length: 3\r\n\r\n"), 13124 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13125 }; 13126 13127 MockRead data_reads[] = { 13128 MockRead("HTTP 0.9 rocks!"), 13129 MockRead(SYNCHRONOUS, OK), 13130 }; 13131 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13132 arraysize(data_writes)); 13133 session_deps_.socket_factory->AddSocketDataProvider(&data); 13134 13135 TestCompletionCallback callback; 13136 13137 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13138 EXPECT_EQ(ERR_IO_PENDING, rv); 13139 13140 rv = callback.WaitForResult(); 13141 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13142 13143 const HttpResponseInfo* response = trans->GetResponseInfo(); 13144 EXPECT_TRUE(response == NULL); 13145 } 13146 13147 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) { 13148 ScopedVector<UploadElementReader> element_readers; 13149 element_readers.push_back(new UploadBytesElementReader("foo", 3)); 13150 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 13151 13152 HttpRequestInfo request; 13153 request.method = "POST"; 13154 request.url = GURL("http://www.foo.com/"); 13155 request.upload_data_stream = &upload_data_stream; 13156 request.load_flags = 0; 13157 13158 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 13159 scoped_ptr<HttpTransaction> trans( 13160 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 13161 // Send headers successfully, but get an error while sending the body. 13162 MockWrite data_writes[] = { 13163 MockWrite("POST / HTTP/1.1\r\n" 13164 "Host: www.foo.com\r\n" 13165 "Connection: keep-alive\r\n" 13166 "Content-Length: 3\r\n\r\n"), 13167 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), 13168 }; 13169 13170 MockRead data_reads[] = { 13171 MockRead("HTTP/1.0 400 Not a Full Response\r\n"), 13172 MockRead(SYNCHRONOUS, OK), 13173 }; 13174 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 13175 arraysize(data_writes)); 13176 session_deps_.socket_factory->AddSocketDataProvider(&data); 13177 13178 TestCompletionCallback callback; 13179 13180 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 13181 EXPECT_EQ(ERR_IO_PENDING, rv); 13182 13183 rv = callback.WaitForResult(); 13184 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 13185 13186 const HttpResponseInfo* response = trans->GetResponseInfo(); 13187 EXPECT_TRUE(response == NULL); 13188 } 13189 13190 } // namespace net 13191