1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_network_transaction.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <math.h> // ceil 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/compiler_specific.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/auth.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/capturing_net_log.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/completion_callback.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/mock_host_resolver.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/request_priority.h" 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/base/ssl_cert_request_info.h" 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/ssl_config_service_defaults.h" 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/ssl_info.h" 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/test_completion_callback.h" 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/upload_data.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_auth_handler_digest.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_auth_handler_mock.h" 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_auth_handler_ntlm.h" 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_basic_stream.h" 324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "net/http/http_net_log_params.h" 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_network_session.h" 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/http/http_network_session_peer.h" 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_stream.h" 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_stream_factory.h" 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_transaction_unittest.h" 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config_service_fixed.h" 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/proxy/proxy_resolver.h" 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/proxy/proxy_service.h" 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_factory.h" 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/socket_test_util.h" 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/ssl_client_socket.h" 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_framer.h" 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_session.h" 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_session_pool.h" 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_test_util.h" 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/platform_test.h" 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//----------------------------------------------------------------------------- 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace { 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kBar(ASCIIToUTF16("bar")); 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kBar2(ASCIIToUTF16("bar2")); 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kBar3(ASCIIToUTF16("bar3")); 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kBaz(ASCIIToUTF16("baz")); 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kFirst(ASCIIToUTF16("first")); 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kFoo(ASCIIToUTF16("foo")); 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kFoo2(ASCIIToUTF16("foo2")); 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kFoo3(ASCIIToUTF16("foo3")); 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kFou(ASCIIToUTF16("fou")); 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kSecond(ASCIIToUTF16("second")); 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm")); 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst string16 kWrongPassword(ASCIIToUTF16("wrongpassword")); 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} // namespace 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Helper to manage the lifetimes of the dependencies for a 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// HttpNetworkTransaction. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SessionDependencies { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Default set of dependencies -- "null" proxy service. 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies() 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : host_resolver(new MockHostResolver), 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_verifier(new CertVerifier), 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick proxy_service(ProxyService::CreateDirect()), 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ssl_config_service(new SSLConfigServiceDefaults), 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick http_auth_handler_factory( 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HttpAuthHandlerFactory::CreateDefault(host_resolver.get())), 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log(NULL) {} 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Custom proxy service dependency. 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit SessionDependencies(ProxyService* proxy_service) 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : host_resolver(new MockHostResolver), 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_verifier(new CertVerifier), 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott proxy_service(proxy_service), 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ssl_config_service(new SSLConfigServiceDefaults), 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick http_auth_handler_factory( 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HttpAuthHandlerFactory::CreateDefault(host_resolver.get())), 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log(NULL) {} 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<MockHostResolverBase> host_resolver; 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<CertVerifier> cert_verifier; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<ProxyService> proxy_service; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<SSLConfigService> ssl_config_service; 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockClientSocketFactory socket_factory; 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog* net_log; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottHttpNetworkSession* CreateSession(SessionDependencies* session_deps) { 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpNetworkSession::Params params; 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.client_socket_factory = &session_deps->socket_factory; 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.host_resolver = session_deps->host_resolver.get(); 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.cert_verifier = session_deps->cert_verifier.get(); 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.proxy_service = session_deps->proxy_service; 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.ssl_config_service = session_deps->ssl_config_service; 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.http_auth_handler_factory = 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps->http_auth_handler_factory.get(); 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.net_log = session_deps->net_log; 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return new HttpNetworkSession(params); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HttpNetworkTransactionTest : public PlatformTest { 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer::set_enable_compression_default(false); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void TearDown() { 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer::set_enable_compression_default(true); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Empty the current queue. 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->RunAllPending(); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PlatformTest::TearDown(); 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void KeepAliveConnectionResendRequestTest(const MockRead& read_failure); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct SimpleGetHelperResult { 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string status_line; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[], 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t reads_count) { 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SimpleGetHelperResult out; 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, reads_count, NULL, 0); 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 1644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(log.bound().IsLoggingAllEvents()); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, log.bound()); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott out.rv = callback.WaitForResult(); 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (out.rv != OK) 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return out; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott out.status_line = response->headers->GetStatusLine(); 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("192.0.2.33", response->socket_address.host()); 179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(0, response->socket_address.port()); 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &out.response_data); 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t pos = ExpectLogContainsSomewhere( 18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::PHASE_NONE); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExpectLogContainsSomewhere( 19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, pos, 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::PHASE_NONE); 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CapturingNetLog::Entry entry = entries[pos]; 1954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch NetLogHttpRequestParameter* request_params = 1964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch static_cast<NetLogHttpRequestParameter*>(entry.extra_parameters.get()); 1974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ("GET / HTTP/1.1\r\n", request_params->GetLine()); 1984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ("Host: www.google.com\r\n" 1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "Connection: keep-alive\r\n\r\n", 2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch request_params->GetHeaders().ToString()); 2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return out; 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ConnectStatusHelperWithExpectedStatus(const MockRead& status, 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int expected_status); 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ConnectStatusHelper(const MockRead& status); 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Fill |str| with a long header list that consumes >= |size| bytes. 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid FillLargeHeadersString(std::string* str, int size) { 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* row = 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int sizeof_row = strlen(row); 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int num_rows = static_cast<int>( 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ceil(static_cast<float>(size) / sizeof_row)); 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int sizeof_data = num_rows * sizeof_row; 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(sizeof_data >= size); 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott str->reserve(sizeof_data); 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < num_rows; ++i) 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott str->append(row, sizeof_row); 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Alternative functions that eliminate randomness and dependency on the local 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// host name so that the generated NTLM messages are reproducible. 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MockGenerateRandom1(uint8* output, size_t n) { 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const uint8 bytes[] = { 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static size_t current_byte = 0; 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < n; ++i) { 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output[i] = bytes[current_byte++]; 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current_byte %= arraysize(bytes); 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MockGenerateRandom2(uint8* output, size_t n) { 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const uint8 bytes[] = { 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1, 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static size_t current_byte = 0; 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < n; ++i) { 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output[i] = bytes[current_byte++]; 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current_byte %= arraysize(bytes); 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::string MockGetHostName() { 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "WTC-WIN7"; 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<typename ParentPool> 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CaptureGroupNameSocketPool : public ParentPool { 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CaptureGroupNameSocketPool(HostResolver* host_resolver, 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CertVerifier* cert_verifier); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string last_group_name_received() const { 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return last_group_name_; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int RequestSocket(const std::string& group_name, 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const void* socket_params, 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RequestPriority priority, 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ClientSocketHandle* handle, 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback, 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott last_group_name_ = group_name; 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_IO_PENDING; 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void CancelRequest(const std::string& group_name, 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClientSocketHandle* handle) {} 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void ReleaseSocket(const std::string& group_name, 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ClientSocket* socket, 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int id) {} 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void CloseIdleSockets() {} 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int IdleSocketCount() const { 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int IdleSocketCountInGroup(const std::string& group_name) const { 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual LoadState GetLoadState(const std::string& group_name, 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const ClientSocketHandle* handle) const { 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return LOAD_STATE_IDLE; 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual base::TimeDelta ConnectionTimeout() const { 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return base::TimeDelta(); 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string last_group_name_; 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsentypedef CaptureGroupNameSocketPool<TransportClientSocketPool> 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenCaptureGroupNameTransportSocketPool; 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool> 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCaptureGroupNameHttpProxySocketPool; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef CaptureGroupNameSocketPool<SOCKSClientSocketPool> 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCaptureGroupNameSOCKSSocketPool; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef CaptureGroupNameSocketPool<SSLClientSocketPool> 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCaptureGroupNameSSLSocketPool; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<typename ParentPool> 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool( 30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HostResolver* host_resolver, 31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CertVerifier* /* cert_verifier */) 31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {} 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<> 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickCaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool( 31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HostResolver* host_resolver, 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CertVerifier* /* cert_verifier */) 31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {} 3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricktemplate<> 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool( 32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HostResolver* host_resolver, 32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CertVerifier* cert_verifier) 32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : SSLClientSocketPool(0, 0, NULL, host_resolver, cert_verifier, NULL, NULL, 324201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, NULL, NULL, NULL, NULL, NULL, NULL) {} 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//----------------------------------------------------------------------------- 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This is the expected list of advertised protocols from the browser's NPN 3293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// list. 3303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2"; 3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This is the expected return from a current server advertising SPDY. 3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kAlternateProtocolHttpHeader[] = 3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Alternate-Protocol: 443:npn-spdy/2\r\n\r\n"; 3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, Basic) { 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, SimpleGET) { 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n\r\n"), 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello world"), 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("hello world", out.response_data); 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Response with no status line. 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) { 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello world"), 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("hello world", out.response_data); 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Allow up to 4 bytes of junk to precede status line. 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) { 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("DATA", out.response_data); 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Allow up to 4 bytes of junk to precede status line. 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("DATA", out.response_data); 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Beyond 4 bytes of slop and it should fail to find a status line. 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"), 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Same as StatusLineJunk4Bytes, except the read chunks are smaller. 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("\n"), 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("\n"), 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Q"), 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("J"), 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("DATA", out.response_data); 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Close the connection before enough bytes to have a status line. 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, StatusLinePartial) { 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTT"), 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTT", out.response_data); 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Simulate a 204 response, lacking a Content-Length header, sent over a 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// persistent connection. The response should still terminate since a 204 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cannot have a response body. 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, StopsReading204) { 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("junk"), // Should not be read!! 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("", out.response_data); 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A simple request using chunked encoding with some extra data after. 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (Like might be seen in a pipelined response.) 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ChunkedEncoding) { 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"), 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("5\r\nHello\r\n"), 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("1\r\n"), 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(" \r\n"), 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("5\r\nworld\r\n"), 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"), 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, out.rv); 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("Hello world", out.response_data); 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Next tests deal with http://crbug.com/56344. 4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MultipleContentLengthHeadersNoTransferEncoding) { 4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 10\r\n"), 4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 5\r\n\r\n"), 4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SimpleGetHelperResult out = SimpleGetHelper(data_reads, 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(data_reads)); 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, 487513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DuplicateContentLengthHeadersNoTransferEncoding) { 488513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead data_reads[] = { 489513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 490513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n"), 491513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n\r\n"), 492513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Hello"), 493513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 494513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 495513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch arraysize(data_reads)); 496513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(OK, out.rv); 497513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 498513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ("Hello", out.response_data); 499513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 500513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 501513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTEST_F(HttpNetworkTransactionTest, 502513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ComplexContentLengthHeadersNoTransferEncoding) { 503513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // More than 2 dupes. 504513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { 505513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead data_reads[] = { 506513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 507513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n"), 508513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n"), 509513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n\r\n"), 510513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Hello"), 511513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 512513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 513513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch arraysize(data_reads)); 514513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(OK, out.rv); 515513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 516513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ("Hello", out.response_data); 517513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 518513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // HTTP/1.0 519513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { 520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead data_reads[] = { 521513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("HTTP/1.0 200 OK\r\n"), 522513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n"), 523513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n"), 524513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n\r\n"), 525513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Hello"), 526513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 527513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 528513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch arraysize(data_reads)); 529513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(OK, out.rv); 530513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); 531513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ("Hello", out.response_data); 532513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 533513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // 2 dupes and one mismatched. 534513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { 535513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead data_reads[] = { 536513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 537513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 10\r\n"), 538513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 10\r\n"), 539513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Content-Length: 5\r\n\r\n"), 540513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 541513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 542513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch arraysize(data_reads)); 543513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv); 544513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 545513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 546513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 547513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTEST_F(HttpNetworkTransactionTest, 5483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MultipleContentLengthHeadersTransferEncoding) { 5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 5503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 666\r\n"), 5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 1337\r\n"), 5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Transfer-Encoding: chunked\r\n\r\n"), 5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("5\r\nHello\r\n"), 5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("1\r\n"), 5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(" \r\n"), 5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("5\r\nworld\r\n"), 5583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"), 5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SimpleGetHelperResult out = SimpleGetHelper(data_reads, 5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(data_reads)); 5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("Hello world", out.response_data); 5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Do a request using the HEAD method. Verify that we don't try to read the 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// message body (since HEAD has none). 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, Head) { 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "HEAD"; 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 57772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 57872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 57972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("HEAD / HTTP/1.1\r\n" 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Content-Length: 0\r\n\r\n"), 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 404 Not Found\r\n"), 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Server: Blah\r\n"), 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 1234\r\n\r\n"), 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No response body because the test stops reading here. 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_UNEXPECTED), // Should not be reached. 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check that the headers got parsed. 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(1234, response->headers->GetContentLength()); 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine()); 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string server_header; 616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* iter = NULL; 617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool has_server_header = response->headers->EnumerateHeader( 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &iter, "Server", &server_header); 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(has_server_header); 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("Blah", server_header); 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Reading should give EOF right away, since there is no message body 623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (despite non-zero content-length). 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("", response_data); 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ReuseConnection) { 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 632513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello"), 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("world"), 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kExpectedResponseData[] = { 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "hello", "world" 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 2; ++i) { 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kExpectedResponseData[i], response_data); 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, Ignores100) { 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "POST"; 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.foo.com/"); 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.upload_data = new UploadData; 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.upload_data->AppendBytes("foo", 3); 683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 68672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 68772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 68872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 100 Continue\r\n\r\n"), 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n\r\n"), 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello world"), 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("hello world", response_data); 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This test is almost the same as Ignores100 above, but the response contains 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// HTTP/1.1 and the two status headers are read in one read. 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, Ignores1xx) { 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.foo.com/"); 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 72872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 72972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 73072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n" 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "HTTP/1.1 200 OK\r\n\r\n"), 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello world"), 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("hello world", response_data); 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) { 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "POST"; 763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.foo.com/"); 764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 76772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 76872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 76972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, "HTTP/1.0 100 Continue\r\n"), 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, 0), 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("", response_data); 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, EmptyResponse) { 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "POST"; 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.foo.com/"); 795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 79772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 79872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 79972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 80072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, 0), 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// read_failure specifies a read failure that should cause the network 817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// transaction to resend the request. 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest( 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const MockRead& read_failure) { 820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.foo.com/"); 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 82672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 82772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data1_reads[] = { 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello"), 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_failure, // Now, we reuse the connection and fail the first read. 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0); 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data2_reads[] = { 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("world"), 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, OK), 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* kExpectedResponseData[] = { 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "hello", "world" 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 2; ++i) { 849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kExpectedResponseData[i], response_data); 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) { 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead read_failure(true, ERR_CONNECTION_RESET); 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott KeepAliveConnectionResendRequestTest(read_failure); 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead read_failure(false, OK); // EOF 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott KeepAliveConnectionResendRequestTest(read_failure); 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 88972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 89072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 89172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, ERR_CONNECTION_RESET), 894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello world"), 896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_CONNECTION_RESET, rv); 908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response == NULL); 911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// What do various browsers do when the server closes a non-keepalive 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// connection without sending any response header or body? 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// IE7: error page 917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Safari 3.1.2 (Windows): error page 918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Firefox 3.0.1: blank page 919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Opera 9.52: after five attempts, blank page 920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Us with WinHTTP: error page (ERR_INVALID_RESPONSE) 921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Us: error page (EMPTY_RESPONSE) 922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { 923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), // EOF 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello world"), 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SimpleGetHelperResult out = SimpleGetHelper(data_reads, 930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_reads)); 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that we correctly reuse a keep-alive connection after not explicitly 9353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// reading the body. 9363345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) { 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.foo.com/"); 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 94372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 94472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Note that because all these reads happen in the same 9463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // StaticSocketDataProvider, it shows that the same socket is being reused for 9473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // all transactions. 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data1_reads[] = { 9493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 9503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"), 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"), 9523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 302 Found\r\n" 9533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 0\r\n\r\n"), 9543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 302 Found\r\n" 9553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 5\r\n\r\n" 9563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "hello"), 9573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 301 Moved Permanently\r\n" 9583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 0\r\n\r\n"), 9593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 301 Moved Permanently\r\n" 9603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 5\r\n\r\n" 9613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "hello"), 962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello"), 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0); 966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data1); 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data2_reads[] = { 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, ERR_UNEXPECTED), // Should not be reached. 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0); 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data2); 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kNumUnreadBodies = arraysize(data1_reads) - 2; 9753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_lines[kNumUnreadBodies]; 9763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) { 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 9893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 9923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response_lines[i] = response->headers->GetStatusLine(); 9933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We intentionally don't read the response bodies. 995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 9963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStatusLines[] = { 9983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1 204 No Content", 9993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1 205 Reset Content", 10003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1 304 Not Modified", 10013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1 302 Found", 10023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1 302 Found", 10033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1 301 Moved Permanently", 10043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1 301 Moved Permanently", 10053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 10063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines), 10083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick forgot_to_update_kStatusLines); 10093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kNumUnreadBodies; ++i) 10113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(kStatusLines[i], response_lines[i]); 10123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 10143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 10153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 10163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 10173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 10183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 10193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 10203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 10213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 10223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 10233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 10243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = ReadTransaction(trans.get(), &response_data); 10253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 10263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello", response_data); 1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth. 1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (basic auth is the easiest to mock, because it has no randomness). 1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuth) { 1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 103872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 103972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 104072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 1048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Give a couple authenticate options (only the middle one is actually 1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // supported). 1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed. 1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Large content-length -- won't matter, as connection will be reset. 1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 1058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), this is the request we should 1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be issuing -- the final header line contains the credentials. 1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 1066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 1070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 1071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 1072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 1074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 1075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 1081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 1083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 1085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 1087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 1090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 1096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 1099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 1100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 1101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 1103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 1105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 1108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 1111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 1113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 1114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, DoNotSendAuth) { 1117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 1118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 1119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 1120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 1121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 112372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 112472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 112572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 1127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 1130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 1133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 1134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Large content-length -- won't matter, as connection will be reset. 1137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 1138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 1139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 1143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 1144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 1145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 1147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 1150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(0, rv); 1151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_FALSE(response == NULL); 1154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 1155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth, over a keep-alive 1158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// connection. 1159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) { 1160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 1161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 1162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 1163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 1164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 116672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 116772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 1172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), this is the request we should 1174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be issuing -- the final header line contains the credentials. 1175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 1178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 1182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 14\r\n\r\n"), 1186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Unauthorized\r\n"), 1187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 1189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\n"), 1190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 11913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 5\r\n\r\n"), 11923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Hello"), 1193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If there is a regression where we disconnect a Keep-Alive 1196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // connection during an auth roundtrip, we'll end up reading this. 1197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead data_reads2[] = { 1198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(false, ERR_FAILED), 1199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 1203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0); 1205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 1206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data2); 1207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 1209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 1212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 1215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 1221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 1222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 1224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 1226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 1228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 1230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 1233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 1236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(response == NULL); 1237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 12383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(5, response->headers->GetContentLength()); 1239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth, over a keep-alive 1242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// connection and with no response body to drain. 1243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { 1244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 1245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 1246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 1247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 1248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 125072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 125172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 1253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), this is the request we should 1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be issuing -- the final header line contains the credentials. 1259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 1266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 0\r\n\r\n"), // No response body. 1269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\n"), 1272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 12733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 5\r\n\r\n"), 12743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("hello"), 1275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // An incorrect reconnect would cause this to be read. 1278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead data_reads2[] = { 1279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(false, ERR_FAILED), 1280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 1284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0); 1286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 1287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data2); 1288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 1290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 1293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 1296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 1302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 1303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 1305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 1306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 1307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 1309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 1311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 1314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 1317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(response == NULL); 1318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 13193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(5, response->headers->GetContentLength()); 1320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth, over a keep-alive 1323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// connection and with a large response body to drain. 1324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { 1325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 1326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 1327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 1328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 1329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 133072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 133172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 133272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 1334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 1337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), this is the request we should 1339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be issuing -- the final header line contains the credentials. 1340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 1343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Respond with 5 kb of response body. 1347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string large_body_string("Unauthorized"); 1348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott large_body_string.append(5 * 1024, ' '); 1349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott large_body_string.append("\r\n"); 1350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 1352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 5134 = 12 + 5 * 1024 + 2 1356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 5134\r\n\r\n"), 1357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, large_body_string.data(), large_body_string.size()), 1358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 1360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\n"), 1361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 13623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 5\r\n\r\n"), 13633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("hello"), 1364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // An incorrect reconnect would cause this to be read. 1367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead data_reads2[] = { 1368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(false, ERR_FAILED), 1369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 1370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 1373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0); 1375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 1376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data2); 1377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 1379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 1382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 1385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 1391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 1392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 1394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 1395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 1396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 1398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 1400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 1403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 1406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(response == NULL); 1407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 14083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(5, response->headers->GetContentLength()); 1409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth, over a keep-alive 1412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// connection, but the server gets impatient and closes the connection. 1413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { 1414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 1415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 1416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 1417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 1418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 141972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 142072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 142172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 1423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 1426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This simulates the seemingly successful write to a closed connection 1427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // if the bug is not fixed. 1428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 1431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 1435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Unauthorized\r\n"), 1436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 1438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 14\r\n\r\n"), 1439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Tell MockTCPClientSocket to simulate the server closing the connection. 1440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 1441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Unauthorized\r\n"), 1442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), // The server closes the connection. 1443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), this is the request we should 1446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be issuing -- the final header line contains the credentials. 1447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 1448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 1449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 1451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 1452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 1455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 1456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\n"), 1457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 14583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 5\r\n\r\n"), 14593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("hello"), 1460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 1464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 1465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 1466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 1467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 1468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 1470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 1473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 1476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 1482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 1483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 1485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 1486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 1487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 1489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 1491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 1494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 1497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_FALSE(response == NULL); 1498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 14993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(5, response->headers->GetContentLength()); 15003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 15013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test the request-challenge-retry sequence for basic auth, over a connection 15033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// that requires a restart when setting up an SSL tunnel. 15043345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { 15053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 15063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 15073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 15083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // when the no authentication data flag is set. 15093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 15103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 151172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Configure against proxy server "myproxy:70". 151272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 151372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 151472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.net_log = log.bound().net_log(); 151572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 151672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Since we have proxy, should try to establish tunnel. 15183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes1[] = { 15193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 15203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 15213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 15223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // After calling trans->RestartWithAuth(), this is the request we should 15243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // be issuing -- the final header line contains the credentials. 15253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 15263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 15273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n" 15283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 15293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 15313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 15323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 15333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The proxy responds to the connect with a 407, using a persistent 15363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // connection. 15373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads1[] = { 15383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // No credentials. 15393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 15403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 15413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Proxy-Connection: close\r\n\r\n"), 15423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 15443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 15463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 15473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 5\r\n\r\n"), 15483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, "hello"), 15493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 15523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes1, arraysize(data_writes1)); 15533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data1); 15543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 15553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 15563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 15583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 15603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 15623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 15633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback1.WaitForResult(); 15653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 156621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 156721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 15683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t pos = ExpectLogContainsSomewhere( 156921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 15703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::PHASE_NONE); 15713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ExpectLogContainsSomewhere( 157221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, pos, 15733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 15743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::PHASE_NONE); 15753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 15773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 15783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(407, response->headers->response_code()); 15803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 15813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The password prompt info should have been set in response->auth_challenge. 15833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response->auth_challenge.get() == NULL); 15843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port); 15863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 15873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(L"basic", response->auth_challenge->scheme); 15883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 15903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 15923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 15933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback2.WaitForResult(); 15953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 15963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response = trans->GetResponseInfo(); 15983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 15993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers->IsKeepAlive()); 16013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(200, response->headers->response_code()); 16023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(5, response->headers->GetContentLength()); 16033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 16043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The password prompt info should not be set. 16063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->auth_challenge.get() == NULL); 16073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick trans.reset(); 1609dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->CloseAllConnections(); 1610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth, over a keep-alive 1613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// proxy connection, when setting up an SSL tunnel. 1614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { 161572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 161672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 161772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 161872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure that proxy authentication is attempted even 161972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // when the no authentication data flag is set. 162072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 162172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Configure against proxy server "myproxy:70". 1623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 1624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 1625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.net_log = log.bound().net_log(); 1626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 1627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Since we have proxy, should try to establish tunnel. 1631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 1632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 1633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n\r\n"), 1635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), this is the request we should 1637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be issuing -- the final header line contains the credentials. 1638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 1639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n" 1641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 1642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The proxy responds to the connect with a 407, using a persistent 1645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connection. 1646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 1647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No credentials. 1648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 1649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10\r\n\r\n"), 1651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("0123456789"), 1652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Wrong credentials (wrong password). 1654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 1655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10\r\n\r\n"), 1657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No response body because the test stops reading here. 1658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_UNEXPECTED), // Should not be reached. 1659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 1663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 1664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 1666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, log.bound()); 1668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 1671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 167221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 167321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 1674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t pos = ExpectLogContainsSomewhere( 167521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 1676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::PHASE_NONE); 1677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExpectLogContainsSomewhere( 167821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, pos, 1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 1680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::PHASE_NONE); 1681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers->IsKeepAlive()); 1686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(407, response->headers->response_code()); 1687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(10, response->headers->GetContentLength()); 1688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 1689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 1691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 1692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port); 1694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 1695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 1696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 1698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Wrong password (should be "bar"). 17003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBaz, &callback2); 1701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 1704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 1707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers->IsKeepAlive()); 1710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(407, response->headers->response_code()); 1711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(10, response->headers->GetContentLength()); 1712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 1713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 1715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 1716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port); 1718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 1719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the idle socket before the NetLog and HttpNetworkTransaction go 1722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // out of scope. 1723dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->CloseAllConnections(); 1724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that we don't read the response body when we fail to establish a tunnel, 1727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// even if the user cancels the proxy's auth attempt. 1728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { 172972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 173072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 173172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 173272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 173372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Configure against proxy server "myproxy:70". 1735731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 1736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 1738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Since we have proxy, should try to establish tunnel. 1742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 1743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 1744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n\r\n"), 1746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The proxy responds to the connect with a 407. 1749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 1750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 1751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10\r\n\r\n"), 1753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_UNEXPECTED), // Should not be reached. 1754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 1757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 1758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 1759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 1761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 1763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 1764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 1766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 1767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 1769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 1770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers->IsKeepAlive()); 1772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(407, response->headers->response_code()); 1773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(10, response->headers->GetContentLength()); 1774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 1775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 1777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 1778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 1779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the idle socket before the HttpNetworkTransaction goes out of scope. 1781dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->CloseAllConnections(); 1782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test when a server (non-proxy) returns a 407 (proxy-authenticate). 1785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The request should fail with ERR_UNEXPECTED_PROXY_AUTH. 1786c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) { 1787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 1788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 1789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 1790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 1791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We are using a DIRECT connection (i.e. no proxy) for this session. 179372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 179472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 179572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 179672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes1[] = { 1798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET / HTTP/1.1\r\n" 1799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 1800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n\r\n"), 1801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads1[] = { 1804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.0 407 Proxy Auth required\r\n"), 1805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Large content-length -- won't matter, as connection will be reset. 1807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("Content-Length: 10000\r\n\r\n"), 1808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, ERR_FAILED), 1809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 1813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data1); 1814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 1816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 1818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 1819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 1821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 1822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1824513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication) 1825513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// through a non-authenticating proxy. The request should fail with 1826513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// ERR_UNEXPECTED_PROXY_AUTH. 1827513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Note that it is impossible to detect if an HTTP server returns a 407 through 1828513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// a non-authenticating proxy - there is nothing to indicate whether the 1829513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// response came from the proxy or the server, so it is treated as if the proxy 1830513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// issued the challenge. 1831513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) { 183272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 183372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 183472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 183572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1836513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 1837513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 1838513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch session_deps.net_log = log.bound().net_log(); 1839513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 1840513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1841513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Since we have proxy, should try to establish tunnel. 1842513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockWrite data_writes1[] = { 1843513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 1844513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Host: www.google.com\r\n" 1845513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Proxy-Connection: keep-alive\r\n\r\n"), 1846513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1847513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockWrite("GET / HTTP/1.1\r\n" 1848513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Host: www.google.com\r\n" 1849513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Connection: keep-alive\r\n\r\n"), 1850513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 1851513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1852513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead data_reads1[] = { 1853513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 1854513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1855513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("HTTP/1.1 407 Unauthorized\r\n"), 1856513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 1857513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead("\r\n"), 1858513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead(false, OK), 1859513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 1860513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1861513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 1862513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data_writes1, arraysize(data_writes1)); 1863513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch session_deps.socket_factory.AddSocketDataProvider(&data1); 1864513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SSLSocketDataProvider ssl(true, OK); 1865513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 1866513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1867513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TestCompletionCallback callback1; 1868513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1869513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1870513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1871513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int rv = trans->Start(&request, &callback1, log.bound()); 1872513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 1873513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1874513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch rv = callback1.WaitForResult(); 1875513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); 187621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 187721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 1878513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t pos = ExpectLogContainsSomewhere( 187921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 1880513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NetLog::PHASE_NONE); 1881513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ExpectLogContainsSomewhere( 188221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, pos, 1883513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 1884513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NetLog::PHASE_NONE); 1885513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 1886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test a simple get through an HTTPS Proxy. 18883345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { 188972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 189072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 189172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 189272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 18933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Configure against https proxy server "proxy:70". 1894731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 18953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 18963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.net_log = log.bound().net_log(); 1897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 1898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Since we have proxy, should use full url 19003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes1[] = { 19013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 1902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 1903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n\r\n"), 1904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads1[] = { 19073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 19083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 19093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 100\r\n\r\n"), 19103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 1911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 1912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 19143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes1, arraysize(data_writes1)); 19153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data1); 19163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 19173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 1918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 1920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 1922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 19243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 1925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback1.WaitForResult(); 19273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 1928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 19303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 1931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers->IsKeepAlive()); 19333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(200, response->headers->response_code()); 19343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(100, response->headers->GetContentLength()); 19353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 1936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The password prompt info should not be set. 19383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->auth_challenge.get() == NULL); 19393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 19403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test a SPDY get through an HTTPS Proxy. 19423345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) { 194372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 194472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 194572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 194672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 194772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 19483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Configure against https proxy server "proxy:70". 1949731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 19503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 19513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.net_log = log.bound().net_log(); 19523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 19533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // fetch http://www.google.com/ via SPDY 19553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST, 19563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false)); 19573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 19583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 19603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); 19613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead spdy_reads[] = { 19623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 19633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*data), 19643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0), 19653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 19663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> spdy_data( 19683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData( 19693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // wait for one write to finish before reading. 19703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_reads, arraysize(spdy_reads), 19713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_writes, arraysize(spdy_writes))); 19723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(spdy_data); 19733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 19753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 19763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto = "spdy/2"; 19773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.was_npn_negotiated = true; 19783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 19793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 19813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 19833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 19853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 19863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback1.WaitForResult(); 19883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 19893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 19913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 19923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 19933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 19943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 19963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 19973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(net::kUploadData, response_data); 19983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 19993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Test a SPDY get through an HTTPS Proxy. 20014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) { 200272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 200372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 200472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 200572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 200672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Configure against https proxy server "proxy:70". 20084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SessionDependencies session_deps( 20094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ProxyService::CreateFixed("https://proxy:70")); 20104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 20114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch session_deps.net_log = log.bound().net_log(); 20124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 20134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // The first request will be a bare GET, the second request will be a 20154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // GET with a Proxy-Authorization header. 20164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> req_get( 20174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); 20184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const char* const kExtraAuthorizationHeaders[] = { 20194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "proxy-authorization", 20204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "Basic Zm9vOmJhcg==", 20214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 20224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> req_get_authorization( 20234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ConstructSpdyGet( 20244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders)/2, 20254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch false, 3, LOWEST, false)); 20264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch MockWrite spdy_writes[] = { 20274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CreateMockWrite(*req_get, 1), 20284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CreateMockWrite(*req_get_authorization, 4), 20294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 20304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // The first response is a 407 proxy authentication challenge, and the second 20324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // response will be a 200 response since the second request includes a valid 20334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Authorization header. 20344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const char* const kExtraAuthenticationHeaders[] = { 20354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "Proxy-Authenticate", 20364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "Basic realm=\"MyRealm1\"" 20374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 20384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> resp_authentication( 20394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ConstructSpdySynReplyError( 20404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "407 Proxy Authentication Required", 20414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2, 20424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1)); 20434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> body_authentication( 20444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ConstructSpdyBodyFrame(1, true)); 20454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3)); 20464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true)); 20474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch MockRead spdy_reads[] = { 20484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CreateMockRead(*resp_authentication, 2), 20494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CreateMockRead(*body_authentication, 3), 20504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CreateMockRead(*resp_data, 5), 20514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CreateMockRead(*body_data, 6), 20524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch MockRead(true, 0, 7), 20534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 20544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_refptr<OrderedSocketData> data( 20564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new OrderedSocketData(spdy_reads, arraysize(spdy_reads), 20574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy_writes, arraysize(spdy_writes))); 20584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch session_deps.socket_factory.AddSocketDataProvider(data); 20594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SSLSocketDataProvider ssl(true, OK); 20614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 20624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ssl.next_proto = "spdy/2"; 20634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ssl.was_npn_negotiated = true; 20644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 20654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch TestCompletionCallback callback1; 20674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 20694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int rv = trans->Start(&request, &callback1, log.bound()); 20714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 20724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = callback1.WaitForResult(); 20744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(OK, rv); 20754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HttpResponseInfo* const response = trans->GetResponseInfo(); 20774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(response != NULL); 20794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(response->headers != NULL); 20804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(407, response->headers->response_code()); 20814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 20824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // The password prompt info should have been set in response->auth_challenge. 20844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(response->auth_challenge.get() != NULL); 20854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(response->auth_challenge->is_proxy); 20864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(L"proxy:70", response->auth_challenge->host_and_port); 20874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 20884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(L"basic", response->auth_challenge->scheme); 20894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch TestCompletionCallback callback2; 20914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 20934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 20944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = callback2.WaitForResult(); 20964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(OK, rv); 20974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 20984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 20994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 21004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(response_restart != NULL); 21014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(response_restart->headers != NULL); 21024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(200, response_restart->headers->response_code()); 21034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // The password prompt info should not be set. 21044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 21054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 21064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 2107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server. 2108731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) { 210972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 211072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 211172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 211272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 211372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Configure against https proxy server "proxy:70". 2115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 2116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 2117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.net_log = log.bound().net_log(); 2118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 2119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 2121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // CONNECT to www.google.com:443 via SPDY 2123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1)); 2124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // fetch https://www.google.com/ via HTTP 2125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const char get[] = "GET / HTTP/1.1\r\n" 2127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "Host: www.google.com\r\n" 2128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "Connection: keep-alive\r\n\r\n"; 2129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> wrapped_get( 2130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ConstructSpdyBodyFrame(1, get, strlen(get), false)); 2131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockWrite spdy_writes[] = { 2132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockWrite(*connect, 1), 2133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockWrite(*wrapped_get, 3) 2134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 2135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> conn_resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 2137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const char resp[] = "HTTP/1.1 200 OK\r\n" 2138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "Content-Length: 10\r\n\r\n"; 2139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> wrapped_get_resp( 2141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ConstructSpdyBodyFrame(1, resp, strlen(resp), false)); 2142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> wrapped_body( 2143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ConstructSpdyBodyFrame(1, "1234567890", 10, false)); 2144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead spdy_reads[] = { 2145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*conn_resp, 2, true), 2146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*wrapped_get_resp, 4, true), 2147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*wrapped_body, 5, true), 2148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*wrapped_body, 6, true), 2149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 7), 2150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 2151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<OrderedSocketData> spdy_data( 2153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new OrderedSocketData( 2154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_reads, arraysize(spdy_reads), 2155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_writes, arraysize(spdy_writes))); 2156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSocketDataProvider(spdy_data); 2157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SSLSocketDataProvider ssl(true, OK); 2159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.next_proto = "spdy/2"; 2161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.was_npn_negotiated = true; 2162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 2163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SSLSocketDataProvider ssl2(true, OK); 2164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl2.was_npn_negotiated = false; 2165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2); 2166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TestCompletionCallback callback1; 2168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 2170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 2171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick rv = callback1.WaitForResult(); 2173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(OK, rv); 2174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 2176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(response != NULL); 2177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(response->headers != NULL); 2178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 2179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string response_data; 2181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 2182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("1234567890", response_data); 2183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 2184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server. 2186731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) { 218772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 218872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 218972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 219072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 219172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Configure against https proxy server "proxy:70". 2193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 2194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 2195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.net_log = log.bound().net_log(); 2196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 2197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 2199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // CONNECT to www.google.com:443 via SPDY 2201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1)); 2202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // fetch https://www.google.com/ via SPDY 2203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const char* const kMyUrl = "https://www.google.com/"; 2204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> get(ConstructSpdyGet(kMyUrl, false, 1, LOWEST)); 2205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> wrapped_get(ConstructWrappedSpdyFrame(get, 1)); 2206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockWrite spdy_writes[] = { 2207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockWrite(*connect, 1), 2208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockWrite(*wrapped_get, 3) 2209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 2210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> conn_resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 2212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> get_resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 2213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> wrapped_get_resp( 2214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ConstructWrappedSpdyFrame(get_resp, 1)); 2215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 2216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> wrapped_body(ConstructWrappedSpdyFrame(body, 1)); 2217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead spdy_reads[] = { 2218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*conn_resp, 2, true), 2219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*wrapped_get_resp, 4, true), 2220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*wrapped_body, 5, true), 2221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 1), 2222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 2223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<OrderedSocketData> spdy_data( 2225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new OrderedSocketData( 2226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_reads, arraysize(spdy_reads), 2227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_writes, arraysize(spdy_writes))); 2228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSocketDataProvider(spdy_data); 2229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SSLSocketDataProvider ssl(true, OK); 2231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.next_proto = "spdy/2"; 2233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.was_npn_negotiated = true; 2234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 2235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SSLSocketDataProvider ssl2(true, OK); 2236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl2.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl2.next_proto = "spdy/2"; 2238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl2.was_npn_negotiated = true; 2239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2); 2240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TestCompletionCallback callback1; 2242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 2244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 2245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick rv = callback1.WaitForResult(); 2247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(OK, rv); 2248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 2250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(response != NULL); 2251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(response->headers != NULL); 2252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 2253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string response_data; 2255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 2256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(net::kUploadData, response_data); 2257731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 2258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Test a SPDY CONNECT failure through an HTTPS Proxy. 2260731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) { 226172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 226272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 226372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 226472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 226572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Configure against https proxy server "proxy:70". 2267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 2268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 2269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.net_log = log.bound().net_log(); 2270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 2271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 2273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // CONNECT to www.google.com:443 via SPDY 2275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1)); 2276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> get(ConstructSpdyRstStream(1, spdy::CANCEL)); 2277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockWrite spdy_writes[] = { 2279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockWrite(*connect, 1), 2280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockWrite(*get, 3), 2281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 2282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdySynReplyError(1)); 2284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); 2285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead spdy_reads[] = { 2286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*resp, 2, true), 2287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 4), 2288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 2289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<OrderedSocketData> spdy_data( 2291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new OrderedSocketData( 2292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_reads, arraysize(spdy_reads), 2293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_writes, arraysize(spdy_writes))); 2294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSocketDataProvider(spdy_data); 2295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SSLSocketDataProvider ssl(true, OK); 2297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.next_proto = "spdy/2"; 2299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl.was_npn_negotiated = true; 2300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 2301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SSLSocketDataProvider ssl2(true, OK); 2302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl2.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl2.next_proto = "spdy/2"; 2304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl2.was_npn_negotiated = true; 2305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2); 2306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TestCompletionCallback callback1; 2308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 2310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 2311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick rv = callback1.WaitForResult(); 231321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(OK, rv); 2314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 231621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ASSERT_FALSE(response == NULL); 231721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(500, response->headers->response_code()); 2318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 2319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 23203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test the challenge-response-retry sequence through an HTTPS Proxy 23213345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { 23223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 23233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 23243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 23253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // when the no authentication data flag is set. 23263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; 23273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 232872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Configure against https proxy server "proxy:70". 232972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 233072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 233172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.net_log = log.bound().net_log(); 233272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 233372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Since we have proxy, should use full url 23353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes1[] = { 23363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 23373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 23383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 23393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // After calling trans->RestartWithAuth(), this is the request we should 23413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // be issuing -- the final header line contains the credentials. 23423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 23433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 23443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n" 23453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 23463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The proxy responds to the GET with a 407, using a persistent 23493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // connection. 23503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads1[] = { 23513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // No credentials. 23523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 23533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 23543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Proxy-Connection: keep-alive\r\n"), 23553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 0\r\n\r\n"), 23563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 23583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 23593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 100\r\n\r\n"), 23603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 23613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 23643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes1, arraysize(data_writes1)); 23653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data1); 23663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 23673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 23683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 23703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 23723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 23743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 23753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback1.WaitForResult(); 23773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 23783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 23803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 23813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(407, response->headers->response_code()); 23833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 23843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The password prompt info should have been set in response->auth_challenge. 23863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response->auth_challenge.get() == NULL); 23873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(L"proxy:70", response->auth_challenge->host_and_port); 23893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 23903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(L"basic", response->auth_challenge->scheme); 23913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 23933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 23953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 23963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback2.WaitForResult(); 23983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 23993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response = trans->GetResponseInfo(); 24013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 24023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers->IsKeepAlive()); 24043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(200, response->headers->response_code()); 24053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(100, response->headers->GetContentLength()); 24063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 24073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The password prompt info should not be set. 24093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->auth_challenge.get() == NULL); 24103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 24113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( 24133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const MockRead& status, int expected_status) { 24143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 24153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 24163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 24173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 24183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 241972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Configure against proxy server "myproxy:70". 242072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 242172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 242272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 242372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Since we have proxy, should try to establish tunnel. 24253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes[] = { 24263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 24273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 24283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 24293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 24323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick status, 24333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 10\r\n\r\n"), 24343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // No response body because the test stops reading here. 24353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, ERR_UNEXPECTED), // Should not be reached. 24363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), 24393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes, arraysize(data_writes)); 24403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data); 24413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 24433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 24453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 24473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 24483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 24503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(expected_status, rv); 24513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 24523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid HttpNetworkTransactionTest::ConnectStatusHelper(const MockRead& status) { 24543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConnectStatusHelperWithExpectedStatus( 24553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick status, ERR_TUNNEL_CONNECTION_FAILED); 24563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 24573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24583345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, ConnectStatus100) { 24593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n")); 24603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 24613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, ConnectStatus101) { 24633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n")); 24643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 24653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24663345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, ConnectStatus201) { 24673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n")); 2468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus202) { 2471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n")); 2472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus203) { 2475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper( 2476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n")); 2477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus204) { 2480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n")); 2481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus205) { 2484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n")); 2485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus206) { 2488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n")); 2489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus300) { 2492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n")); 2493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus301) { 2496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n")); 2497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus302) { 2500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n")); 2501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus303) { 2504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n")); 2505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus304) { 2508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n")); 2509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus305) { 2512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n")); 2513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus306) { 2516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n")); 2517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus307) { 2520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n")); 2521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus400) { 2524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n")); 2525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus401) { 2528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n")); 2529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus402) { 2532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n")); 2533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus403) { 2536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n")); 2537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus404) { 2540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n")); 2541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus405) { 2544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n")); 2545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus406) { 2548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n")); 2549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus407) { 2552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelperWithExpectedStatus( 2553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 2554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ERR_PROXY_AUTH_UNSUPPORTED); 2555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus408) { 2558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n")); 2559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus409) { 2562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n")); 2563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus410) { 2566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n")); 2567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus411) { 2570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n")); 2571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus412) { 2574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n")); 2575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus413) { 2578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n")); 2579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus414) { 2582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n")); 2583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus415) { 2586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n")); 2587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus416) { 2590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper( 2591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n")); 2592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus417) { 2595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n")); 2596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus500) { 2599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n")); 2600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus501) { 2603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n")); 2604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus502) { 2607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n")); 2608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus503) { 2611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n")); 2612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus504) { 2615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n")); 2616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectStatus505) { 2619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n")); 2620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the flow when both the proxy server AND origin server require 2623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// authentication. Again, this uses basic auth for both since that is 2624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the simplest to mock. 2625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { 262672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 262772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 262872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 262972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 263072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2631731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 2632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Configure against proxy server "myproxy:70". 2634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( 2635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CreateSession(&session_deps))); 2636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 2638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 2639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 2640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n\r\n"), 2641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 2644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 407 Unauthorized\r\n"), 2645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Give a couple authenticate options (only the middle one is actually 2646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // supported). 2647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed. 2648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), 2650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Large content-length -- won't matter, as connection will be reset. 2652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 2653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 2654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth() the first time, this is the 2657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request we should be issuing -- the final header line contains the 2658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // proxy's credentials. 2659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 2660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 2661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 2662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n" 2663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 2664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now the proxy server lets the request pass through to origin server. 2667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The origin server responds with a 401. 2668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 2669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 2670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note: We are using the same realm-name as the proxy server. This is 2671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // completely valid, as realms are unique across hosts. 2672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 2673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 2000\r\n\r\n"), 2675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), // Won't be reached. 2676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth() the second time, we should send 2679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the credentials for both the proxy and origin server. 2680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes3[] = { 2681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 2682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 2683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n" 2684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n" 2685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 2686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly we get the desired content. 2689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads3[] = { 2690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 2691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 2692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 2693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 2694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 2698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 2700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 2701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes3, arraysize(data_writes3)); 2702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 2703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 2704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data3); 2705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 2707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 2709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 2710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 2712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 2713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 2715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 2716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 2718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 2719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port); 2721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 2722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 2723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 2725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 2727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 2728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 2730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 2731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 2733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 2734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 2735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 2737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 2738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 2739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback3; 2741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo2, kBar2, &callback3); 2743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 2744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback3.WaitForResult(); 2746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 2747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 2749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 2750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 2751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// For the NTLM implementation using SSPI, we skip the NTLM tests since we 2754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// can't hook into its internals to cause it to generate predictable NTLM 2755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// authorization headers. 2756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(NTLM_PORTABLE) 2757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The NTLM authentication unit tests were generated by capturing the HTTP 2758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// requests and responses using Fiddler 2 and inspecting the generated random 2759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// bytes in the debugger. 2760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Enter the correct password and authenticate successfully. 2762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, NTLMAuth1) { 2763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 2764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 2765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://172.22.68.17/kids/login.aspx"); 2766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 2767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 276872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, 276972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MockGetHostName); 277072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 277172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 277272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 2774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 2777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 2780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Access Denied\r\n"), 2781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Negotiate and NTLM are often requested together. However, we only want 2782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 2783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the header that requests Negotiate for this test. 2784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: NTLM\r\n"), 2785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Connection: close\r\n"), 2786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 42\r\n"), 2787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html\r\n\r\n"), 2788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Missing content -- won't matter, as connection will be reset. 2789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_UNEXPECTED), 2790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 2793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After restarting with a null identity, this is the 2794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request we should be issuing -- the final header line contains a Type 2795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 1 message. 2796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 2799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: NTLM " 2800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 2801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), we should send a Type 3 message 2803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (the credentials for the origin server). The second request continues 2804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // on the same connection. 2805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 2808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 2809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 2810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW" 2811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX" 2812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "ahlhx5I=\r\n\r\n"), 2813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 2816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The origin server responds with a Type 2 message. 2817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Access Denied\r\n"), 2818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: NTLM " 2819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo" 2820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 2821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 2822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 2823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 2824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 2825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "BtAAAAAAA=\r\n"), 2826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 42\r\n"), 2827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html\r\n\r\n"), 2828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("You are not authorized to view this page\r\n"), 2829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly we get the desired content. 2831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\n"), 2832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=utf-8\r\n"), 2833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 13\r\n\r\n"), 2834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Please Login\r\n"), 2835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 2836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 2839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 2840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 2841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 2842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 2843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 2844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 2846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 28483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 2850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 2851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 2853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 2854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 2856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 285872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_TRUE(response != NULL); 2859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The password prompt info should have been set in 2861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // response->auth_challenge. 286272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_FALSE(response->auth_challenge.get() == NULL); 2863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port); 2865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"", response->auth_challenge->realm); 2866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); 2867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 286872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback2; 286972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 287072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithAuth(kTestingNTLM, kTestingNTLM, &callback2); 287172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 287272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 287372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback2.WaitForResult(); 287472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(OK, rv); 287572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 287672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 287772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 287872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response = trans->GetResponseInfo(); 287972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_TRUE(response != NULL); 288072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 288172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(response->auth_challenge.get() == NULL); 288272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback3; 2884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 288572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithAuth(string16(), string16(), &callback3); 2886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 2887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback3.WaitForResult(); 2889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 2890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 2892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 2893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 2894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(13, response->headers->GetContentLength()); 2895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Enter a wrong password, and then the correct one. 2898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, NTLMAuth2) { 2899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 2900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 2901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://172.22.68.17/kids/login.aspx"); 2902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 2903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 290472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2, 290572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MockGetHostName); 290672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 290772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 290872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 2910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 2913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 2916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Access Denied\r\n"), 2917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Negotiate and NTLM are often requested together. However, we only want 2918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip 2919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the header that requests Negotiate for this test. 2920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: NTLM\r\n"), 2921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Connection: close\r\n"), 2922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 42\r\n"), 2923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html\r\n\r\n"), 2924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Missing content -- won't matter, as connection will be reset. 2925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_UNEXPECTED), 2926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 2929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After restarting with a null identity, this is the 2930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request we should be issuing -- the final header line contains a Type 2931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 1 message. 2932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 2935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: NTLM " 2936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 2937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), we should send a Type 3 message 2939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (the credentials for the origin server). The second request continues 2940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // on the same connection. 2941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 2944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 2945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 2946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY" 2947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj" 2948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "4Ww7b7E=\r\n\r\n"), 2949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 2952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The origin server responds with a Type 2 message. 2953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Access Denied\r\n"), 2954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: NTLM " 2955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo" 2956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 2957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 2958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 2959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 2960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 2961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "BtAAAAAAA=\r\n"), 2962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 42\r\n"), 2963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html\r\n\r\n"), 2964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("You are not authorized to view this page\r\n"), 2965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Wrong password. 2967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Access Denied\r\n"), 2968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: NTLM\r\n"), 2969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Connection: close\r\n"), 2970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 42\r\n"), 2971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html\r\n\r\n"), 2972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Missing content -- won't matter, as connection will be reset. 2973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_UNEXPECTED), 2974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes3[] = { 2977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After restarting with a null identity, this is the 2978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request we should be issuing -- the final header line contains a Type 2979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 1 message. 2980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 2983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: NTLM " 2984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), 2985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), we should send a Type 3 message 2987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (the credentials for the origin server). The second request continues 2988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // on the same connection. 2989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" 2990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: 172.22.68.17\r\n" 2991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 2992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" 2993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" 2994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54" 2995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI" 2996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "+4MUm7c=\r\n\r\n"), 2997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 2998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads3[] = { 3000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The origin server responds with a Type 2 message. 3001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Access Denied\r\n"), 3002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: NTLM " 3003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo" 3004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" 3005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" 3006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" 3007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" 3008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" 3009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "BtAAAAAAA=\r\n"), 3010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 42\r\n"), 3011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html\r\n\r\n"), 3012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("You are not authorized to view this page\r\n"), 3013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly we get the desired content. 3015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\n"), 3016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=utf-8\r\n"), 3017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 13\r\n\r\n"), 3018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Please Login\r\n"), 3019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 3026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 3027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes3, arraysize(data_writes3)); 3028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 3030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data3); 3031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 3033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 30353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 3037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 3040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 3043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 3048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 3049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port); 3051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"", response->auth_challenge->realm); 3052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); 3053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 305472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback2; 3055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Enter the wrong password. 305772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithAuth(kTestingNTLM, kWrongPassword, &callback2); 3058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 306072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback2.WaitForResult(); 3061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 306472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback3; 306572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithAuth(string16(), string16(), &callback3); 3066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 306772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback3.WaitForResult(); 3068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 3070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 307272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_TRUE(response != NULL); 3073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 3075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 3076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port); 3078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"", response->auth_challenge->realm); 3079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); 3080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 308172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback4; 3082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now enter the right password. 308472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithAuth(kTestingNTLM, kTestingNTLM, &callback4); 308572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 308672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 308772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback4.WaitForResult(); 308872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(OK, rv); 308972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 309072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 309172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 309272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback5; 309372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 309472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // One more roundtrip 309572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithAuth(string16(), string16(), &callback5); 3096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback5.WaitForResult(); 3099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 3102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 3103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(13, response->headers->GetContentLength()); 3104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NTLM_PORTABLE 3106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test reading a server response which has only headers, and no body. 3108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// After some maximum number of bytes is consumed, the transaction should 3109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// fail with ERR_RESPONSE_HEADERS_TOO_BIG. 3110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) { 3111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 3114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 3115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 311672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 311772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 311872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 311972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Respond with 300 kb of headers (we should fail after 256 kb). 3121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string large_headers_string; 3122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FillLargeHeadersString(&large_headers_string, 300 * 1024); 3123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 3125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 3126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, large_headers_string.data(), large_headers_string.size()), 3127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("\r\nBODY"), 3128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 3131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 3132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 3134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 3136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 3139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv); 3140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response == NULL); 3143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure that we don't try to reuse a TCPClientSocket when failing to 3146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// establish tunnel. 3147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://code.google.com/p/chromium/issues/detail?id=3772 3148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) { 314972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 315072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 315172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 315272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 315372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Configure against proxy server "myproxy:70". 3155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 3156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 3158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 3160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Since we have proxy, should try to establish tunnel. 3162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 3164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n\r\n"), 3166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The proxy responds to the connect with a 404, using a persistent 3169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connection. Usually a proxy would return 501 (not implemented), 3170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // or 200 (tunnel established). 3171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 404 Not Found\r\n"), 3173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10\r\n\r\n"), 3174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_UNEXPECTED), // Should not be reached. 3175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 3182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 3184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 3187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 3188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response == NULL); 3191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Empty the current queue. This is necessary because idle sockets are 3193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // added to the connection pool asynchronously with a PostTask. 3194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->RunAllPending(); 3195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We now check to make sure the TCPClientSocket was not added back to 3197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the pool. 3198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount()); 3199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott trans.reset(); 3200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->RunAllPending(); 3201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Make sure that the socket didn't get recycled after calling the destructor. 3202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount()); 3203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure that we recycle a socket after reading all of the response body. 3206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, RecycleSocket) { 3207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 3210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 3211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 321272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 321372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 321472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 321572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 321672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 3218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A part of the response body is received with the response headers. 3219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"), 3220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The rest of the response body is received in two parts. 3221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("lo"), 3222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(" world"), 3223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("junk"), // Should not be read!! 3224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 3228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 3229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 3231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 3233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 3236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 3240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 3242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string status_line = response->headers->GetStatusLine(); 3243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 200 OK", status_line); 3244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount()); 3246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 3248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 3249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("hello world", response_data); 3251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Empty the current queue. This is necessary because idle sockets are 3253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // added to the connection pool asynchronously with a PostTask. 3254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->RunAllPending(); 3255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We now check to make sure the socket was added back to the pool. 3257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(1, session->transport_socket_pool()->IdleSocketCount()); 3258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Make sure that we recycle a SSL socket after reading all of the response 32613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// body. 32623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) { 3263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 3264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 32663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 3267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 3268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes[] = { 32703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 32713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 32723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 32733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 32743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 32763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 32773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 11\r\n\r\n"), 32783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("hello world"), 3279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 32833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 32843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 32853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), 32863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes, arraysize(data_writes)); 3287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 3288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 3290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 32923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 32933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 3295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 32973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback.WaitForResult()); 3298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 33003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 33013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 33023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount()); 3305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 3307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 3308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 33093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello world", response_data); 3310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Empty the current queue. This is necessary because idle sockets are 3312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // added to the connection pool asynchronously with a PostTask. 3313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->RunAllPending(); 3314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We now check to make sure the socket was added back to the pool. 33163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount()); 3317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it 33203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// from the pool and make sure that we recover okay. 33213345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) { 33223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SessionDependencies session_deps; 33233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 33243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 33253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 33263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 33273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes[] = { 33293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 33303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 33313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 33323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 33333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 33343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 33353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 33363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 33383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 33393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 11\r\n\r\n"), 33403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 33413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("hello world"), 33423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 33433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 33443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 33463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl2(true, OK); 33473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 33483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2); 33493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), 33513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes, arraysize(data_writes)); 33523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data2(data_reads, arraysize(data_reads), 33533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes, arraysize(data_writes)); 33543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data); 33553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data2); 33563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 33583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 33603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 33613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 33633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 33653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback.WaitForResult()); 33663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 33683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 33693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 33703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 33713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount()); 33733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 33753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = ReadTransaction(trans.get(), &response_data); 33763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 33773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello world", response_data); 33783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Empty the current queue. This is necessary because idle sockets are 33803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // added to the connection pool asynchronously with a PostTask. 33813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 33823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We now check to make sure the socket was added back to the pool. 33843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount()); 33853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Now start the second transaction, which should reuse the previous socket. 33873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick trans.reset(new HttpNetworkTransaction(session)); 33893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->Start(&request, &callback, BoundNetLog()); 33913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 33933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback.WaitForResult()); 33943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 33953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response = trans->GetResponseInfo(); 33963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 33973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 33983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 33993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount()); 34013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = ReadTransaction(trans.get(), &response_data); 34033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 34043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello world", response_data); 34053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Empty the current queue. This is necessary because idle sockets are 34073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // added to the connection pool asynchronously with a PostTask. 34083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 34093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We now check to make sure the socket was added back to the pool. 34113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount()); 34123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 34133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Make sure that we recycle a socket after a zero-length response. 34153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// http://crbug.com/9880 34163345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { 34173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 34183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 34193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&" 34203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "tran=undefined&ei=mAXcSeegAo-SMurloeUN&" 34213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "e=17259,18167,19592,19773,19981,20133,20173,20233&" 34223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "rt=prt.2642,ol.2649,xjs.2951"); 34233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 34243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 342572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 342672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 342772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 342872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 342972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 34313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 204 No Content\r\n" 34323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 0\r\n" 34333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Type: text/html\r\n\r\n"), 34343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("junk"), // Should not be read!! 34353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 34363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 34373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 34393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data); 34403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 34423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 34443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 34453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 34473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 34483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 34503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response != NULL); 34513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers != NULL); 34533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string status_line = response->headers->GetStatusLine(); 34543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 204 No Content", status_line); 34553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount()); 34573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 34593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = ReadTransaction(trans.get(), &response_data); 34603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 34613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("", response_data); 34623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Empty the current queue. This is necessary because idle sockets are 34643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // added to the connection pool asynchronously with a PostTask. 34653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 34663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We now check to make sure the socket was added back to the pool. 3468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(1, session->transport_socket_pool()->IdleSocketCount()); 34693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 34703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 34713345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) { 34723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request[2]; 34733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Transaction 1: a GET request that succeeds. The socket is recycled 34743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // after use. 34753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request[0].method = "GET"; 34763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request[0].url = GURL("http://www.google.com/"); 34773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request[0].load_flags = 0; 34783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Transaction 2: a POST request. Reuses the socket kept alive from 3479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // transaction 1. The first attempts fails when writing the POST data. 3480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This causes the transaction to retry with a new socket. The second 3481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // attempt succeeds. 3482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request[1].method = "POST"; 3483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request[1].url = GURL("http://www.google.com/login.cgi"); 3484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request[1].upload_data = new UploadData; 3485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request[1].upload_data->AppendBytes("foo", 3); 3486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request[1].load_flags = 0; 3487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 3489513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 3490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The first socket is used for transaction 1 and the first attempt of 3492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // transaction 2. 3493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The response of transaction 1. 3495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"), 3497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("hello world"), 3498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The mock write results of transaction 1 and the first attempt of 3501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // transaction 2. 3502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(false, 64), // GET 3504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(false, 93), // POST 3505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(false, ERR_CONNECTION_ABORTED), // POST data 3506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The second socket is used for the second attempt of transaction 2. 3511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The response of transaction 2. 3513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 3514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"), 3515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("welcome"), 3516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The mock write results of the second attempt of transaction 2. 3519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 3520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(false, 93), // POST 3521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(false, 3), // POST data 3522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 3525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 3528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* kExpectedResponseData[] = { 3530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "hello world", "welcome" 3531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 2; ++i) { 3534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 3535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(session)); 3536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 3538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request[i], &callback, BoundNetLog()); 3540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 3543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 3547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 3549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 3552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 3553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kExpectedResponseData[i], response_data); 3555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 3556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth when there is 3559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// an identity in the URL. The request should be sent as normal, but when 3560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// it fails the identity from the URL is used to answer the challenge. 3561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) { 3562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note: the URL has a username:password in it. 3565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://foo:b@r@www.google.com/"); 3566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 356772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 356872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 356972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 357072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password contains an escaped character -- for this test to pass it 3572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // will need to be unescaped by HttpNetworkTransaction. 3573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("b%40r", request.url.password()); 3574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = LOAD_NORMAL; 3576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 3579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 3581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 3585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10\r\n\r\n"), 3587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 3588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After the challenge above, the transaction will be restarted using the 3591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // identity from the url (foo, b@r) to answer the challenge. 3592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 3593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 3594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"), 3597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 3600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 3601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 3602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 3609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 3611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 3613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 3615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 3618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 3621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 36223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(string16(), string16(), &callback2); 3623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 3625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 3627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // There is no challenge info, since the identity in URL worked. 3632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 3633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 3635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Empty the current queue. 3637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->RunAllPending(); 3638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the request-challenge-retry sequence for basic auth when there is 3641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// an incorrect identity in the URL. The identity from the URL should be used 3642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// only once. 3643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) { 3644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note: the URL has a username:password in it. The password "baz" is 3647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // wrong (should be "bar"). 3648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://foo:baz@www.google.com/"); 3649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = LOAD_NORMAL; 3651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 365272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 365372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 365472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 365572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 3658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 3660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 3664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10\r\n\r\n"), 3666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 3667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After the challenge above, the transaction will be restarted using the 3670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // identity from the url (foo, baz) to answer the challenge. 3671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 3672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 3673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJheg==\r\n\r\n"), 3676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 3679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 3680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10\r\n\r\n"), 3682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 3683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After the challenge above, the transaction will be restarted using the 3686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // identity supplied by the user (foo, bar) to answer the challenge. 3687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes3[] = { 3688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 3689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads3[] = { 3695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 3696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 3697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 3704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 3705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes3, arraysize(data_writes3)); 3706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 3708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data3); 3709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 3711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 3713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 3716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 3719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 37203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(string16(), string16(), &callback2); 3721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 3723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 3725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 3729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 3730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 3732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 3733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 3734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback3; 37363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback3); 3737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback3.WaitForResult(); 3739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 3741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 3743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // There is no challenge info, since the identity worked. 3746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 3747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 3749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Empty the current queue. 3751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->RunAllPending(); 3752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 3753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that previously tried username/passwords for a realm get re-used. 3755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { 3756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 3757513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 3758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Transaction 1: authenticate (foo, bar) on MyRealm1 3760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 3761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/x/y/z"); 3764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 3765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 376672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 376772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /x/y/z HTTP/1.1\r\n" 3770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 3772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 3776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 3778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 3779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resend with authorization (username=foo, password=bar) 3782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 3783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /x/y/z HTTP/1.1\r\n" 3784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sever accepts the authorization. 3790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 3791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 3792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 3793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 3800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 3802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 3804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 3806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 3809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in 3815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // response->auth_challenge. 3816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 3817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 3819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 3820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 3821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 3823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 3825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 3828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 3831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 3833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 3834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 3835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ------------------------------------------------------------------------ 3837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Transaction 2: authenticate (foo2, bar2) on MyRealm2 3839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 3840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that Transaction 1 was at /x/y/z, so this is in the same 3843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // protection space as MyRealm1. 3844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/x/y/a/b"); 3845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 3846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 384772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 384872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 3851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Send preemptive authorization for MyRealm1 3854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The server didn't like the preemptive authorization, and 3858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // challenges us for a different realm (MyRealm2). 3859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 3861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"), 3862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 3863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 3864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resend with authorization for MyRealm2 (username=foo2, password=bar2) 3867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 3868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 3869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), 3872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sever accepts the authorization. 3875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 3876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 3877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 3878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 3884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 3885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 3887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 3889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 3891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 3894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in 3900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // response->auth_challenge. 3901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 3902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 3904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm2", response->auth_challenge->realm); 3905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 3906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 3908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 39093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo2, kBar2, &callback2); 3910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 3913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 3916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 3918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 3919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 3920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ------------------------------------------------------------------------ 3922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Transaction 3: Resend a request in MyRealm's protection space -- 3924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // succeed with preemptive authorization. 3925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 3926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/x/y/z2"); 3929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 3930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 393172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 393272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /x/y/z2 HTTP/1.1\r\n" 3935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The authorization for MyRealm1 gets sent preemptively 3938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (since the url is in the same protection space) 3939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sever accepts the preemptive authorization 3943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 3945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 3946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 3947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 3950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 3951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 3952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 3954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 3956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 3957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 3959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 3960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 3962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 3963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 3965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 3966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 3967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ------------------------------------------------------------------------ 3969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Transaction 4: request another URL in MyRealm (however the 3971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // url is not known to belong to the protection space, so no pre-auth). 3972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 3973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 3974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 3975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/x/1"); 3976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 3977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 397872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 397972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 3981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /x/1 HTTP/1.1\r\n" 3982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 3984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 3987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 3988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 3989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 3990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 3991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 3992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resend with authorization from MyRealm's cache. 3994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 3995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /x/1 HTTP/1.1\r\n" 3996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 3997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 3998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 3999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sever accepts the authorization. 4002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 4003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 4004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 4005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 4006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 4010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 4012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 4013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 4014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 4016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 4018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 4021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 40253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(string16(), string16(), &callback2); 4026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 4028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 4032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 4033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 4034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 4035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 4036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ------------------------------------------------------------------------ 4038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Transaction 5: request a URL in MyRealm, but the server rejects the 4040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cached identity. Should invalidate and re-prompt. 4041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 4042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 4043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 4044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/p/q/t"); 4045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 4046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 404772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 404872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 4050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /p/q/t HTTP/1.1\r\n" 4051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 4053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 4056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 4059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 4060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resend with authorization from cache for MyRealm. 4063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 4064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /p/q/t HTTP/1.1\r\n" 4065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 4067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 4068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sever rejects the authorization. 4071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 4072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 4074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 10000\r\n\r\n"), 4075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 4076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // At this point we should prompt for new credentials for MyRealm. 4079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Restart with username=foo3, password=foo4. 4080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes3[] = { 4081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET /p/q/t HTTP/1.1\r\n" 4082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 4084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"), 4085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sever accepts the authorization. 4088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads3[] = { 4089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 4090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 4091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 4092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 4096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 4098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 4099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes3, arraysize(data_writes3)); 4100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 4101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 4102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data3); 4103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 4105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 4107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 4110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(trans->IsReadyToRestartForAuth()); 4113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 41143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(string16(), string16(), &callback2); 4115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 4117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(trans->IsReadyToRestartForAuth()); 4119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 4121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 4122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in 4124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // response->auth_challenge. 4125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 4126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 4128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 4129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 4130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback3; 4132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo3, kBar3, &callback3); 4134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback3.WaitForResult(); 4137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 4140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 4141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 4142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 4143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 4144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 4145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that nonce count increments when multiple auth attempts 4147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// are started with the same nonce. 4148c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) { 4149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 41504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch HttpAuthHandlerDigest::Factory* digest_factory = 41514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new HttpAuthHandlerDigest::Factory(); 41524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator = 41534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef"); 41544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch digest_factory->set_nonce_generator(nonce_generator); 41554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch session_deps.http_auth_handler_factory.reset(digest_factory); 4156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 4157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Transaction 1: authenticate (foo, bar) on MyRealm1 4159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 4161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 4162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/x/y/z"); 4163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 4164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 416572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 416672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes1[] = { 4168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET /x/y/z HTTP/1.1\r\n" 4169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 4170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n\r\n"), 4171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads1[] = { 4174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.0 401 Unauthorized\r\n"), 4175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", " 4176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "algorithm=MD5, qop=\"auth\"\r\n\r\n"), 4177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 4178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Resend with authorization (username=foo, password=bar) 4181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes2[] = { 4182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET /x/y/z HTTP/1.1\r\n" 4183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 4184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 4185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: Digest username=\"foo\", realm=\"digestive\", " 4186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, " 4187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, " 4188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"), 4189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sever accepts the authorization. 4192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads2[] = { 4193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.0 200 OK\r\n"), 4194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 4195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 4199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 4200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 4201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data1); 4202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data2); 4203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback1; 4205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 4207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback1.WaitForResult(); 4210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 4211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 4214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The password prompt info should have been set in 4216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // response->auth_challenge. 4217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response->auth_challenge.get() == NULL); 4218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 4220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"digestive", response->auth_challenge->realm); 4221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"digest", response->auth_challenge->scheme); 4222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback2; 4224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 4226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback2.WaitForResult(); 4229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 4230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 4232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 4233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() == NULL); 4234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ------------------------------------------------------------------------ 4237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Transaction 2: Request another resource in digestive's protection space. 4239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This will preemptively add an Authorization header which should have an 4240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // "nc" value of 2 (as compared to 1 in the first use. 4241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 4243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 4244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that Transaction 1 was at /x/y/z, so this is in the same 4245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // protection space as digest. 4246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/x/y/a/b"); 4247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 4248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 424972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 425072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes1[] = { 4252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET /x/y/a/b HTTP/1.1\r\n" 4253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 4254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 4255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: Digest username=\"foo\", realm=\"digestive\", " 4256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, " 4257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, " 4258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"), 4259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sever accepts the authorization. 4262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads1[] = { 4263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.0 200 OK\r\n"), 4264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("Content-Length: 100\r\n\r\n"), 4265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 4266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 4269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 4270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data1); 4271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback1; 4273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 4275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback1.WaitForResult(); 4278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 4279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 4282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() == NULL); 4283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the ResetStateForRestart() private method. 4287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { 4288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Create a transaction (the dependencies aren't important). 4289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 4290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpNetworkTransaction> trans( 4291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 4292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Setup some state (which we expect ResetStateForRestart() will clear). 4294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott trans->read_buf_ = new IOBuffer(15); 4295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott trans->read_buf_len_ = 15; 4296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch trans->request_headers_.SetHeader("Authorization", "NTLM"); 4297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Setup state in response_ 4299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpResponseInfo* response = &trans->response_; 4300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response->auth_challenge = new AuthChallengeInfo(); 4301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response->ssl_info.cert_status = -15; 4302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response->response_time = base::Time::Now(); 4303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response->was_cached = true; // (Wouldn't ever actually be true...) 4304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { // Setup state for response_.vary_data 4306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 4307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n"); 4308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::replace(temp.begin(), temp.end(), '\n', '\0'); 4309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp)); 4310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader("Foo", "1"); 4311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader("bar", "23"); 4312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->vary_data.Init(request, *headers)); 4313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 4314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Cause the above state to be reset. 4316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott trans->ResetStateForRestart(); 4317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Verify that the state that needed to be reset, has been reset. 4319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(trans->read_buf_.get() == NULL); 4320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(0, trans->read_buf_len_); 4321513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_TRUE(trans->request_headers_.IsEmpty()); 4322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 4323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers.get() == NULL); 4324731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_FALSE(response->was_cached); 4325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(0, response->ssl_info.cert_status); 4326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->vary_data.is_valid()); 4327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 4328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test HTTPS connections to a site with a bad certificate 4330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) { 4331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 4332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 4333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("https://www.google.com/"); 4334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 4335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 433672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 433772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 433872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 433972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 4341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 4342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 4344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 4347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 4348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 4350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 4351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StaticSocketDataProvider ssl_bad_certificate; 4354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 4356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID); 4357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLSocketDataProvider ssl(true, OK); 4358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate); 4360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 4361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad); 4362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 4363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 4365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 4367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 4371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = trans->RestartIgnoringLastError(&callback); 4373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 4379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 4381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 4382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 4383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test HTTPS connections to a site with a bad certificate, going through a 4385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// proxy 4386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { 4387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 4388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 4390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 4391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("https://www.google.com/"); 4392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 4393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite proxy_writes[] = { 4395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 4396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n\r\n"), 4398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead proxy_reads[] = { 4401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 4402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK) 4403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 4406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 4407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Proxy-Connection: keep-alive\r\n\r\n"), 4409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 4410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 4412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 4415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 4416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 4417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 4419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 4420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider ssl_bad_certificate( 4423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch proxy_reads, arraysize(proxy_reads), 4424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch proxy_writes, arraysize(proxy_writes)); 4425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 4427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID); 4428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLSocketDataProvider ssl(true, OK); 4429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate); 4431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 4432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad); 4433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 4434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 4436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 2; i++) { 4438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.ResetNextMockIndexes(); 4439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 4441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 4442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 4444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 4448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = trans->RestartIgnoringLastError(&callback); 4450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 4456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 4458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 4459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 4460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 4461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 44633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test HTTPS connections to a site, going through an HTTPS proxy 44643345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { 4465731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 4466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 4468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 44693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 44703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 4471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 44733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 44743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 44753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 4476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 4477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 44783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 4479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 44823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 44833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 4484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 4486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 4487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 44913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy 44923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider tunnel_ssl(true, OK); // SSL through the tunnel 44933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 44953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl); 44963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&tunnel_ssl); 4497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 4499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans( 45013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(CreateSession(&session_deps))); 45023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 4504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 45083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 45093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 45113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers->IsKeepAlive()); 45133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(200, response->headers->response_code()); 45143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(100, response->headers->GetContentLength()); 45153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 4516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 4517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 451821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Test an HTTPS Proxy's ability to redirect a CONNECT request 451921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { 452021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SessionDependencies session_deps( 452121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProxyService::CreateFixed("https://proxy:70")); 452221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 452321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HttpRequestInfo request; 452421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.method = "GET"; 452521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.url = GURL("https://www.google.com/"); 452621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.load_flags = 0; 452721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 452821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockWrite data_writes[] = { 452921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 453021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "Host: www.google.com\r\n" 453121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "Proxy-Connection: keep-alive\r\n\r\n"), 453221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 453321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 453421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead data_reads[] = { 453521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead("HTTP/1.1 302 Redirect\r\n"), 453621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead("Location: http://login.example.com/\r\n"), 453721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead("Content-Length: 0\r\n\r\n"), 453821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead(false, OK), 453921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 454021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 454121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen StaticSocketDataProvider data(data_reads, arraysize(data_reads), 454221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data_writes, arraysize(data_writes)); 454321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy 454421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 454521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data); 454621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl); 454721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 454821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TestCompletionCallback callback; 454921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 455021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<HttpTransaction> trans( 455121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 455221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 455321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = trans->Start(&request, &callback, BoundNetLog()); 455421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 455521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 455621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = callback.WaitForResult(); 455721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(OK, rv); 455821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const HttpResponseInfo* response = trans->GetResponseInfo(); 455921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 456021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ASSERT_FALSE(response == NULL); 456121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 456221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(302, response->headers->response_code()); 456321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string url; 456421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_TRUE(response->headers->IsRedirect(&url)); 456521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ("http://login.example.com/", url); 456621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 456721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 456821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request 456921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { 457021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SessionDependencies session_deps( 457121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProxyService::CreateFixed("https://proxy:70")); 457221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 457321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HttpRequestInfo request; 457421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.method = "GET"; 457521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.url = GURL("https://www.google.com/"); 457621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.load_flags = 0; 457721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 457821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<spdy::SpdyFrame> conn(ConstructSpdyConnect(NULL, 0, 1)); 457921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyRstStream(1, spdy::CANCEL)); 458021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockWrite data_writes[] = { 458121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateMockWrite(*conn.get(), 0, false), 458221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 458321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 458421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static const char* const kExtraHeaders[] = { 458521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "location", 458621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "http://login.example.com/", 458721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 458821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<spdy::SpdyFrame> resp( 458921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ConstructSpdySynReplyError("302 Redirect", kExtraHeaders, 459021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen arraysize(kExtraHeaders)/2, 1)); 459121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead data_reads[] = { 459221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateMockRead(*resp.get(), 1, false), 459321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead(true, 0, 2), // EOF 459421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 459521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 459621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_refptr<DelayedSocketData> data( 459721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new DelayedSocketData( 459821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1, // wait for one write to finish before reading. 459921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data_reads, arraysize(data_reads), 460021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data_writes, arraysize(data_writes))); 460121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy 460221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen proxy_ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 460321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen proxy_ssl.next_proto = "spdy/2"; 460421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen proxy_ssl.was_npn_negotiated = true; 460521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 460621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSocketDataProvider(data.get()); 460721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl); 460821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 460921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TestCompletionCallback callback; 461021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 461121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<HttpTransaction> trans( 461221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 461321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 461421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = trans->Start(&request, &callback, BoundNetLog()); 461521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 461621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 461721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = callback.WaitForResult(); 461821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(OK, rv); 461921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const HttpResponseInfo* response = trans->GetResponseInfo(); 462021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 462121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ASSERT_FALSE(response == NULL); 462221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 462321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(302, response->headers->response_code()); 462421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string url; 462521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_TRUE(response->headers->IsRedirect(&url)); 462621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ("http://login.example.com/", url); 462721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 462821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 462921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Test an HTTPS Proxy's ability to provide a response to a CONNECT request 463021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(HttpNetworkTransactionTest, ErrorResponseTofHttpsConnectViaHttpsProxy) { 463121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SessionDependencies session_deps( 463221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProxyService::CreateFixed("https://proxy:70")); 463321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 463421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HttpRequestInfo request; 463521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.method = "GET"; 463621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.url = GURL("https://www.google.com/"); 463721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.load_flags = 0; 463821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 463921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockWrite data_writes[] = { 464021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 464121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "Host: www.google.com\r\n" 464221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "Proxy-Connection: keep-alive\r\n\r\n"), 464321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 464421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 464521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead data_reads[] = { 464621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead("HTTP/1.1 404 Not Found\r\n"), 464721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead("Content-Length: 23\r\n\r\n"), 464821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead("The host does not exist"), 464921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead(false, OK), 465021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 465121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 465221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen StaticSocketDataProvider data(data_reads, arraysize(data_reads), 465321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data_writes, arraysize(data_writes)); 465421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy 465521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 465621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data); 465721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl); 465821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 465921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TestCompletionCallback callback; 466021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 466121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<HttpTransaction> trans( 466221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 466321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 466421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = trans->Start(&request, &callback, BoundNetLog()); 466521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 466621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 466721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = callback.WaitForResult(); 466821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(OK, rv); 466921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const HttpResponseInfo* response = trans->GetResponseInfo(); 467021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 467121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ASSERT_FALSE(response == NULL); 467221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 467321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(404, response->headers->response_code()); 467421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(23, response->headers->GetContentLength()); 467521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 467621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_FALSE(response->ssl_info.is_valid()); 467721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 467821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string response_data; 467921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 468021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ("The host does not exist", response_data); 468121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 468221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 468321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Test an HTTPS (SPDY) Proxy's ability to provide a response to a CONNECT 468421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// request 468521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(HttpNetworkTransactionTest, ErrorResponseTofHttpsConnectViaSpdyProxy) { 468621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SessionDependencies session_deps( 468721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProxyService::CreateFixed("https://proxy:70")); 468821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 468921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HttpRequestInfo request; 469021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.method = "GET"; 469121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.url = GURL("https://www.google.com/"); 469221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.load_flags = 0; 469321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 469421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<spdy::SpdyFrame> conn(ConstructSpdyConnect(NULL, 0, 1)); 469521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyRstStream(1, spdy::CANCEL)); 469621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockWrite data_writes[] = { 469721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateMockWrite(*conn.get(), 0, false), 469821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 469921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 470021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static const char* const kExtraHeaders[] = { 470121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "location", 470221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "http://login.example.com/", 470321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 470421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<spdy::SpdyFrame> resp( 470521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ConstructSpdySynReplyError("404 Not Found", kExtraHeaders, 470621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen arraysize(kExtraHeaders)/2, 1)); 470721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<spdy::SpdyFrame> body( 470821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ConstructSpdyBodyFrame(1, "The host does not exist", 23, true)); 470921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead data_reads[] = { 471021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateMockRead(*resp.get(), 1, false), 471121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateMockRead(*body.get(), 2, false), 471221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MockRead(true, 0, 3), // EOF 471321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen }; 471421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 471521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_refptr<DelayedSocketData> data( 471621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new DelayedSocketData( 471721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1, // wait for one write to finish before reading. 471821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data_reads, arraysize(data_reads), 471921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data_writes, arraysize(data_writes))); 472021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy 472121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen proxy_ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 472221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen proxy_ssl.next_proto = "spdy/2"; 472321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen proxy_ssl.was_npn_negotiated = true; 472421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 472521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSocketDataProvider(data.get()); 472621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl); 472721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 472821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TestCompletionCallback callback; 472921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 473021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<HttpTransaction> trans( 473121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 473221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 473321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = trans->Start(&request, &callback, BoundNetLog()); 473421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 473521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 473621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = callback.WaitForResult(); 473721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(OK, rv); 473821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const HttpResponseInfo* response = trans->GetResponseInfo(); 473921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 474021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ASSERT_FALSE(response == NULL); 474121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 474221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ(404, response->headers->response_code()); 474321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_FALSE(response->ssl_info.is_valid()); 474421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 474521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string response_data; 474621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 474721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ("The host does not exist", response_data); 474821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 474921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 47503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test HTTPS connections to a site with a bad certificate, going through an 47513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// HTTPS proxy 47523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) { 4753731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); 4754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 4756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 47573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 4758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 4759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Attempt to fetch the URL from a server with a bad cert 47613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite bad_cert_writes[] = { 47623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 47633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 47643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 47653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead bad_cert_reads[] = { 47683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 47693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK) 47703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Attempt to fetch the URL with a good cert 47733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite good_data_writes[] = { 47743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 47753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 47763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 4777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 4778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 47793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 4780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead good_cert_reads[] = { 47833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.0 200 Connected\r\n\r\n"), 4784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 4785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 4787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 4788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider ssl_bad_certificate( 47913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bad_cert_reads, arraysize(bad_cert_reads), 47923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bad_cert_writes, arraysize(bad_cert_writes)); 47933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads), 47943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick good_data_writes, arraysize(good_data_writes)); 47953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID); 47963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 47973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SSL to the proxy, then CONNECT request, then SSL with bad certificate 47993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 48003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate); 48013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad); 48023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SSL to the proxy, then CONNECT request, then valid SSL certificate 48043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 4805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 48063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 4807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 4809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans( 48113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(CreateSession(&session_deps))); 48123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 4814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 48173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); 48183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartIgnoringLastError(&callback); 48203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 48213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 4823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 48243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 48263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(response == NULL); 48283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(100, response->headers->GetContentLength()); 4829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 4830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48313345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) { 4832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 48333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 4834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 48353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 48363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Chromium Ultra Awesome X Edition"); 4837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 483872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 483972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 484072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 484172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 48433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 4844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 4845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 48463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 4847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 4850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 4851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 4852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 4853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 4854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 4855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 4856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 4858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 4859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 4860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 4862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 4864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 4865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 4868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 4869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48703345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) { 4871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 48723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 48733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 48743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 48753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Chromium Ultra Awesome X Edition"); 4876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 487772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 487872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 487972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 488072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 48823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 4883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 48843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n" 48853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), 48863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 48873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 48883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Return an error, so the transaction stops here (this test isn't 48893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // interested in the rest). 48903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 48913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 48923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Proxy-Connection: close\r\n\r\n"), 48933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 48943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), 48963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes, arraysize(data_writes)); 48973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data); 48983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 49003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 49023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 49033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 49053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 49063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 49073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49083345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) { 49093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 49103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 49113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 49123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 49133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.referrer = GURL("http://the.previous.site.com/"); 49143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 491572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 491672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 491772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 491872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 49193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes[] = { 49203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 49213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 49223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n" 49233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Referer: http://the.previous.site.com/\r\n\r\n"), 49243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 49253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Lastly, the server responds with the actual content. 49273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 49283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.0 200 OK\r\n"), 49293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 49303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 100\r\n\r\n"), 49313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 49323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 49333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), 49353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes, arraysize(data_writes)); 49363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data); 49373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 49393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 49413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 49423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 49443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 49453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 49463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49473345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) { 49483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 49493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 49503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 49513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 495272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 495372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 495472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 495572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 49563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes[] = { 49573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("POST / HTTP/1.1\r\n" 49583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 49593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n" 49603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 0\r\n\r\n"), 49613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 49623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Lastly, the server responds with the actual content. 49643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 49653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.0 200 OK\r\n"), 49663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 49673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 100\r\n\r\n"), 49683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 49693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 49703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), 49723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes, arraysize(data_writes)); 49733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data); 49743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 49763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 49783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 49793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 49813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 49823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 49833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49843345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) { 49853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 49863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "PUT"; 49873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 49883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 498972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 499072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 499172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 499272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 49933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes[] = { 49943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("PUT / HTTP/1.1\r\n" 49953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 49963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n" 49973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 0\r\n\r\n"), 49983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 4999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 5001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 5005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 5006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) { 5022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 5023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "HEAD"; 5024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 5025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 502672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 502772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 502872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 502972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("HEAD / HTTP/1.1\r\n" 5032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 5034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Content-Length: 0\r\n\r\n"), 5035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 5038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 5042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 5043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) { 5059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 5060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 5061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 5062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = LOAD_BYPASS_CACHE; 5063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 506472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 506572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 506672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 506772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 5072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Pragma: no-cache\r\n" 5073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Cache-Control: no-cache\r\n\r\n"), 5074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 5077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 5081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 5082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, 5098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BuildRequest_CacheControlValidateCache) { 5099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 5100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 5101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 5102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = LOAD_VALIDATE_CACHE; 5103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 510472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 510572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 510672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 510772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 5112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Cache-Control: max-age=0\r\n\r\n"), 5113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 5116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 5120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 5121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) { 5137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 5138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 5139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 5140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader("FooHeader", "Bar"); 5141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 514272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 514372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 514472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 514572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 5150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "FooHeader: Bar\r\n\r\n"), 5151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 5154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 5158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 5159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 5164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 5166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 5171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 5172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5174c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) { 5175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 5176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 5177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 5178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader("referer", "www.foo.com"); 5179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader("hEllo", "Kitty"); 5180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader("FoO", "bar"); 5181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 518272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 518372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 518472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 518572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes[] = { 5187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET / HTTP/1.1\r\n" 5188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 5189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 5190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hEllo: Kitty\r\n" 5191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FoO: bar\r\n\r\n"), 5192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 5193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Lastly, the server responds with the actual content. 5195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 5196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.0 200 OK\r\n"), 5197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("Content-Length: 100\r\n\r\n"), 5199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 5200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 5201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) { 521672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 521772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 521872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 521972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 522072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps( 5222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixed("socks4://myproxy:1080")); 5223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 5225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 5226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; 5228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 5229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, write_buffer, arraysize(write_buffer)), 5232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n") 5235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, read_buffer, arraysize(read_buffer)), 5239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 5241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Payload"), 5242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK) 5243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 5258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 5259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_text; 5261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_text); 5262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("Payload", response_text); 5264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) { 526772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 526872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 526972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 527072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 527172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps( 5273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixed("socks4://myproxy:1080")); 5274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 5276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 5277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 }; 5279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; 5280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, reinterpret_cast<char*>(write_buffer), 5283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott arraysize(write_buffer)), 5284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n") 5287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, reinterpret_cast<char*>(read_buffer), 5291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott arraysize(read_buffer)), 5292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 5294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Payload"), 5295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK) 5296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLSocketDataProvider ssl(true, OK); 5303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 5304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 5314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 5315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_text; 5317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_text); 5318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("Payload", response_text); 5320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) { 532372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 532472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 532572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 532672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 532772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps( 5329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixed("socks5://myproxy:1080")); 5330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 5332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 5333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 5335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 5336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char kSOCKS5OkRequest[] = { 5337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x05, // Version 5338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x01, // Command (CONNECT) 5339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x00, // Reserved. 5340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x03, // Address type (DOMAINNAME). 5341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x0E, // Length of domain (14) 5342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Domain string: 5343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 5344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x00, 0x50, // 16-bit port (80) 5345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char kSOCKS5OkResponse[] = 5347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 }; 5348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 5351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)), 5352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n") 5355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 5359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 5360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 5362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Payload"), 5363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK) 5364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 5379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 5380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_text; 5382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_text); 5383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("Payload", response_text); 5385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) { 538872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 538972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 539072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("https://www.google.com/"); 539172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 539272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps( 5394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixed("socks5://myproxy:1080")); 5395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 5397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 5398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; 5400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; 5401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const unsigned char kSOCKS5OkRequest[] = { 5402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x05, // Version 5403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x01, // Command (CONNECT) 5404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x00, // Reserved. 5405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x03, // Address type (DOMAINNAME). 5406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x0E, // Length of domain (14) 5407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Domain string: 5408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 5409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0x01, 0xBB, // 16-bit port (443) 5410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char kSOCKS5OkResponse[] = 5413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 }; 5414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes[] = { 5416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)), 5417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, reinterpret_cast<const char*>(kSOCKS5OkRequest), 5418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott arraysize(kSOCKS5OkRequest)), 5419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n") 5422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)), 5426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)), 5427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\n"), 5428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"), 5429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Payload"), 5430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK) 5431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 5434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 5435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLSocketDataProvider ssl(true, OK); 5438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 5439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 5449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 5450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_text; 5452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_text); 5453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("Payload", response_text); 5455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that for connection endpoints the group names are correctly set. 5458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct GroupNameTest { 5460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string proxy_server; 5461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url; 5462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string expected_group_name; 5463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ssl; 5464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 5465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochscoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests( 5467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SessionDependencies* session_deps) { 5468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps)); 5469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAlternateProtocols* alternate_protocols = 5471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session->mutable_alternate_protocols(); 5472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch alternate_protocols->SetAlternateProtocolFor( 5473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostPortPair("host.with.alternate", 80), 443, 54743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAlternateProtocols::NPN_SPDY_2); 5475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return session; 5477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint GroupNameTransactionHelper( 5480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& url, 5481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const scoped_refptr<HttpNetworkSession>& session) { 5482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 5483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 5484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL(url); 5485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 5486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 548772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 548872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 5490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We do not complete this request, the dtor will clean the transaction up. 5492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return trans->Start(&request, &callback, BoundNetLog()); 5493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5495c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) { 5496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GroupNameTest tests[] = { 5497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 5498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "", // unused 5499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "http://www.google.com/direct", 5500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "www.google.com:80", 5501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 5502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }, 5503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 5504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "", // unused 5505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://[2001:1418:13:1::25]/direct", 5506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "[2001:1418:13:1::25]:80", 5507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 5508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }, 5509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // SSL Tests 5511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 5512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "", // unused 5513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "https://www.google.com/direct_ssl", 5514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ssl/www.google.com:443", 5515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "", // unused 5519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://[2001:1418:13:1::25]/direct", 5520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ssl/[2001:1418:13:1::25]:443", 5521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "", // unused 5525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://host.with.alternate/direct", 5526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ssl/host.with.alternate:443", 5527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 5530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 5532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 5534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SessionDependencies session_deps( 5535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyService::CreateFixed(tests[i].proxy_server)); 5536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session( 5537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetupSessionForGroupNameTests(&session_deps)); 5538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkSessionPeer peer(session); 5540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CaptureGroupNameTransportSocketPool* transport_conn_pool = 5541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new CaptureGroupNameTransportSocketPool(NULL, NULL); 5542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen peer.SetTransportSocketPool(transport_conn_pool); 55433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CaptureGroupNameSSLSocketPool* ssl_conn_pool = 554472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new CaptureGroupNameSSLSocketPool(NULL, NULL); 5545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch peer.SetSSLSocketPool(ssl_conn_pool); 5546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 5548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GroupNameTransactionHelper(tests[i].url, session)); 5549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tests[i].ssl) 5550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(tests[i].expected_group_name, 5551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl_conn_pool->last_group_name_received()); 5552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 5553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(tests[i].expected_group_name, 5554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen transport_conn_pool->last_group_name_received()); 5555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 5556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 5558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5560c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) { 5561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GroupNameTest tests[] = { 5562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http_proxy", 5564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://www.google.com/http_proxy_normal", 5565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "www.google.com:80", 5566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 5567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }, 5568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SSL Tests 5570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 5571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "http_proxy", 5572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "https://www.google.com/http_connect_ssl", 5573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ssl/www.google.com:443", 5574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }, 5576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 5578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http_proxy", 5579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://host.with.alternate/direct", 5580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ssl/host.with.alternate:443", 5581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }, 5583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 5586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 5588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SessionDependencies session_deps( 5589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyService::CreateFixed(tests[i].proxy_server)); 5590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session( 5591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetupSessionForGroupNameTests(&session_deps)); 5592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkSessionPeer peer(session); 5594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostPortPair proxy_host("http_proxy", 80); 55963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CaptureGroupNameHttpProxySocketPool* http_proxy_pool = 559772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new CaptureGroupNameHttpProxySocketPool(NULL, NULL); 5598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch peer.SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); 55993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CaptureGroupNameSSLSocketPool* ssl_conn_pool = 560072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new CaptureGroupNameSSLSocketPool(NULL, NULL); 5601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 5602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 5604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GroupNameTransactionHelper(tests[i].url, session)); 5605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tests[i].ssl) 5606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(tests[i].expected_group_name, 5607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl_conn_pool->last_group_name_received()); 5608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 5609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(tests[i].expected_group_name, 5610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch http_proxy_pool->last_group_name_received()); 5611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 5612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 5614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5616c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) { 5617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GroupNameTest tests[] = { 5618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks4://socks_proxy:1080", 5620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://www.google.com/socks4_direct", 5621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks4/www.google.com:80", 5622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 5623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks5://socks_proxy:1080", 5626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://www.google.com/socks5_direct", 5627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks5/www.google.com:80", 5628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 5629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SSL Tests 5632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks4://socks_proxy:1080", 5634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://www.google.com/socks4_ssl", 5635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks4/ssl/www.google.com:443", 5636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks5://socks_proxy:1080", 5640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://www.google.com/socks5_ssl", 5641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks5/ssl/www.google.com:443", 5642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 5646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks4://socks_proxy:1080", 5647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://host.with.alternate/direct", 5648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "socks4/ssl/host.with.alternate:443", 5649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 5650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 5651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 5652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 5654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 5656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SessionDependencies session_deps( 5657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyService::CreateFixed(tests[i].proxy_server)); 5658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session( 5659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetupSessionForGroupNameTests(&session_deps)); 5660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkSessionPeer peer(session); 5662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostPortPair proxy_host("socks_proxy", 1080); 56643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CaptureGroupNameSOCKSSocketPool* socks_conn_pool = 566572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new CaptureGroupNameSOCKSSocketPool(NULL, NULL); 5666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch peer.SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool); 56673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CaptureGroupNameSSLSocketPool* ssl_conn_pool = 566872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new CaptureGroupNameSSLSocketPool(NULL, NULL); 5669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 5670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 5672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 5674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GroupNameTransactionHelper(tests[i].url, session)); 5675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tests[i].ssl) 5676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(tests[i].expected_group_name, 5677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl_conn_pool->last_group_name_received()); 5678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 5679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(tests[i].expected_group_name, 5680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch socks_conn_pool->last_group_name_received()); 5681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 5682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 5684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) { 568772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 568872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 568972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 569072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps( 5692731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixed("myproxy:70;foobar:80")); 5693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This simulates failure resolving all hostnames; that means we will fail 5695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connecting to both proxies (myproxy:70 and foobar:80). 5696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.host_resolver->rules()->AddSimulatedFailure("*"); 5697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 5699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 5700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 57073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv); 5708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Host resolution observer used by 5711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// HttpNetworkTransactionTest.ResolveMadeWithReferrer to check that host 5712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// resovle requests are issued with a referrer of |expected_referrer|. 5713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ResolutionReferrerObserver : public HostResolver::Observer { 5714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 5715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit ResolutionReferrerObserver(const GURL& expected_referrer) 5716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : expected_referrer_(expected_referrer), 5717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott called_start_with_referrer_(false), 5718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott called_finish_with_referrer_(false) { 5719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 5720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnStartResolution(int id, 5722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HostResolver::RequestInfo& info) { 5723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (info.referrer() == expected_referrer_) 5724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott called_start_with_referrer_ = true; 5725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 5726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnFinishResolutionWithStatus( 5728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int id, bool was_resolved, const HostResolver::RequestInfo& info ) { 5729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (info.referrer() == expected_referrer_) 5730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott called_finish_with_referrer_ = true; 5731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 5732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnCancelResolution(int id, 5734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HostResolver::RequestInfo& info ) { 5735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FAIL() << "Should not be cancelling any requests!"; 5736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 5737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool did_complete_with_expected_referrer() const { 5739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return called_start_with_referrer_ && called_finish_with_referrer_; 5740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 5741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 5743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL expected_referrer_; 5744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool called_start_with_referrer_; 5745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool called_finish_with_referrer_; 5746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(ResolutionReferrerObserver); 5748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 5749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure that when HostResolver::Resolve() is invoked, it passes through 5751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the "referrer". This is depended on by the DNS prefetch observer. 5752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ResolveMadeWithReferrer) { 5753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL referrer = GURL("http://expected-referrer/"); 5754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(referrer.is_valid()); 5755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ResolutionReferrerObserver resolution_observer(referrer); 5756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 575772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Issue a request, containing an HTTP referrer. 575872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 575972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 576072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.referrer = referrer; 576172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 576272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 5764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( 5765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CreateSession(&session_deps))); 5766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Attach an observer to watch the host resolutions being made. 5768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.host_resolver->AddObserver(&resolution_observer); 5769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Connect up a mock socket which will fail when reading. 5771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, ERR_FAILED), 5773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 5775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Run the request until it fails reading from the socket. 5778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_FAILED, rv); 5783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check that the host resolution observer saw |referrer|. 5785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(resolution_observer.did_complete_with_expected_referrer()); 5786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Base test to make sure that when the load flags for a request specify to 5789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// bypass the cache, the DNS cache is not used. 5790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BypassHostCacheOnRefreshHelper(int load_flags) { 579172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Issue a request, asking to bypass the cache(s). 579272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 579372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "GET"; 579472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = load_flags; 579572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/"); 579672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 5798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Select a host resolver that does caching. 5800731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_deps.host_resolver.reset(new MockCachingHostResolver); 5801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( 5803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CreateSession(&session_deps))); 5804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Warm up the host cache so it has an entry for "www.google.com" (by doing 5806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a synchronous lookup.) 5807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressList addrlist; 5808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = session_deps.host_resolver->Resolve( 58093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist, 5810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, BoundNetLog()); 5811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Verify that it was added to host cache, by doing a subsequent async lookup 5814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and confirming it completes synchronously. 5815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback resolve_callback; 5816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = session_deps.host_resolver->Resolve( 58173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist, 5818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &resolve_callback, NULL, BoundNetLog()); 5819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_EQ(OK, rv); 5820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Inject a failure the next time that "www.google.com" is resolved. This way 5822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we can tell if the next lookup hit the cache, or the "network". 5823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (cache --> success, "network" --> failure). 5824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.host_resolver->rules()->AddSimulatedFailure("www.google.com"); 5825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Connect up a mock socket which will fail with ERR_UNEXPECTED during the 5827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // first read -- this won't be reached as the host resolution will fail first. 5828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { MockRead(false, ERR_UNEXPECTED) }; 5829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 5830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Run the request. 5833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Start(&request, &callback, BoundNetLog()); 5835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_EQ(ERR_IO_PENDING, rv); 5836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we bypassed the cache, we would have gotten a failure while resolving 5839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // "www.google.com". 5840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); 5841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// There are multiple load flags that should trigger the host cache bypass. 5844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test each in isolation: 5845c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) { 5846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE); 5847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5849c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) { 5850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE); 5851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5853c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) { 5854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE); 5855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure we can handle an error when writing the request. 5858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, RequestWriteError) { 5859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 5860513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 5861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 5863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 5864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.foo.com/"); 5865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 5866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite write_failure[] = { 5868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite(true, ERR_CONNECTION_RESET), 5869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(NULL, 0, 5871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch write_failure, arraysize(write_failure)); 5872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 5877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 5878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_CONNECTION_RESET, rv); 5884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check that a connection closed after the start of the headers finishes ok. 5887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) { 5888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 5889513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 5890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 5892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 5893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.foo.com/"); 5894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 5895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 5897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1."), 5898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 5899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 5902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 5903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 5905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 5907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 5908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 5913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 5916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response != NULL); 5917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->headers != NULL); 5919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 5920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string response_data; 5922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = ReadTransaction(trans.get(), &response_data); 5923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("", response_data); 5925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 5926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure that a dropped connection while draining the body for auth 5928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// restart does the right thing. 5929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, DrainResetOK) { 5930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SessionDependencies session_deps; 5931513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 5932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 5934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 5935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("http://www.google.com/"); 5936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 5937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes1[] = { 5939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n\r\n"), 5942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads1[] = { 5945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 401 Unauthorized\r\n"), 5946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 5947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 14\r\n\r\n"), 5949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Unauth"), 5950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(true, ERR_CONNECTION_RESET), 5951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 5954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 5955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data1); 5956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After calling trans->RestartWithAuth(), this is the request we should 5958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be issuing -- the final header line contains the credentials. 5959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite data_writes2[] = { 5960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockWrite("GET / HTTP/1.1\r\n" 5961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: www.google.com\r\n" 5962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: keep-alive\r\n" 5963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 5964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lastly, the server responds with the actual content. 5967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads2[] = { 5968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.1 200 OK\r\n"), 5969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 5970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("Content-Length: 100\r\n\r\n"), 5971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 5972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 5973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 5975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 5976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data2); 5977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback1; 5979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 59813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 5983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 5984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback1.WaitForResult(); 5986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 5987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpResponseInfo* response = trans->GetResponseInfo(); 5989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 5990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The password prompt info should have been set in response->auth_challenge. 5992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response->auth_challenge.get() == NULL); 5993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 5995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 5996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(L"basic", response->auth_challenge->scheme); 5997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; 5999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 6001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 6002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 6004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(OK, rv); 6005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response = trans->GetResponseInfo(); 6007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(response == NULL); 6008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(response->auth_challenge.get() == NULL); 6009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(100, response->headers->GetContentLength()); 6010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 6011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test HTTPS connections going through a proxy that sends extra data. 6013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) { 6014731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 6015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpRequestInfo request; 6017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.method = "GET"; 6018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.url = GURL("https://www.google.com/"); 6019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request.load_flags = 0; 6020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead proxy_reads[] = { 6022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"), 6023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK) 6024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 6025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0); 6027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLSocketDataProvider ssl(true, OK); 6028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSocketDataProvider(&data); 6030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 6031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; 6033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott session_deps.socket_factory.ResetNextMockIndexes(); 6035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpTransaction> trans( 6037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HttpNetworkTransaction(CreateSession(&session_deps))); 6038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_IO_PENDING, rv); 6041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 6043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); 6044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 6045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) { 6047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 605272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 605372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 605472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 605572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead data_reads[] = { 6057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"), 6058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockRead(false, OK), 6059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 6060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 6062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 6063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 6065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response != NULL); 6073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 6075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 6076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 6078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = ReadTransaction(trans.get(), &response_data); 6079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); 6080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6082c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) { 6083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "POST"; 6085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/upload"); 6086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.upload_data = new UploadData; 6087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 608972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 609072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 609172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 609272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath temp_file_path; 6094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path)); 6095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const uint64 kFakeSize = 100000; // file is actually blank 6096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<UploadData::Element> elements; 6098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UploadData::Element element; 6099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.SetToFilePath(temp_file_path); 6100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.SetContentLength(kFakeSize); 6101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch elements.push_back(element); 61023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->SetElements(elements); 6103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kFakeSize, request.upload_data->GetContentLength()); 6104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.0 200 OK\r\n\r\n"), 6107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 6108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 6109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 6111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 6112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 6114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 6119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response != NULL); 6123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 6125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 6126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 6128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = ReadTransaction(trans.get(), &response_data); 6129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 6131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::Delete(temp_file_path, false); 6133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6135c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) { 613672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 613772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "POST"; 613872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/upload"); 613972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.upload_data = new UploadData; 614072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 614172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we try to upload an unreadable file, the network stack should report 6143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the file size as zero and upload zero bytes for that file. 6144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans( 6146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new HttpNetworkTransaction(CreateSession(&session_deps))); 6147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath temp_file; 6149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file)); 6150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string temp_file_content("Unreadable file."); 6151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(), 6152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch temp_file_content.length())); 6153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file)); 6154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<UploadData::Element> elements; 6156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UploadData::Element element; 6157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.SetToFilePath(temp_file); 6158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch elements.push_back(element); 61593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->SetElements(elements); 6160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.0 200 OK\r\n\r\n"), 6163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 6164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes[] = { 6166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("POST /upload HTTP/1.1\r\n" 6167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 6169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 0\r\n\r\n"), 6170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(false, OK), 6171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 6173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_writes)); 6174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 6175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 6177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 6182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response != NULL); 6186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 6187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 6188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::Delete(temp_file, false); 6190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6192c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) { 619372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestInfo request; 619472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.method = "POST"; 619572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.url = GURL("http://www.google.com/upload"); 619672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.upload_data = new UploadData; 619772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request.load_flags = 0; 619872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans( 6201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new HttpNetworkTransaction(CreateSession(&session_deps))); 6202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath temp_file; 6204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file)); 6205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string temp_file_contents("Unreadable file."); 6206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string unreadable_contents(temp_file_contents.length(), '\0'); 6207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(), 6208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch temp_file_contents.length())); 6209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<UploadData::Element> elements; 6211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UploadData::Element element; 6212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.SetToFilePath(temp_file); 6213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch elements.push_back(element); 62143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->SetElements(elements); 6215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 401 Unauthorized\r\n"), 6218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 6219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("Content-Length: 0\r\n\r\n"), // No response body. 6220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 6222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("Content-Length: 0\r\n\r\n"), 6223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 6224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes[] = { 6226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("POST /upload HTTP/1.1\r\n" 6227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 6229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 16\r\n\r\n"), 6230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(false, temp_file_contents.c_str()), 6231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("POST /upload HTTP/1.1\r\n" 6233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 6235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 16\r\n" 6236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 6237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(false, unreadable_contents.c_str(), temp_file_contents.length()), 6238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(false, OK), 6239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes, 6241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(data_writes)); 6242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 6243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback1; 6245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 6247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback1.WaitForResult(); 6250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response != NULL); 6254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 6255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine()); 6256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The password prompt info should have been set in response->auth_challenge. 6258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() != NULL); 6259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 6260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); 6261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"basic", response->auth_challenge->scheme); 6262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now make the file unreadable and try again. 6264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file)); 6265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback2; 6267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback2); 6269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback2.WaitForResult(); 6272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 6275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response != NULL); 6276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 6277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() == NULL); 6278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::Delete(temp_file, false); 6281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that changes to Auth realms are treated like auth rejections. 6284c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) { 6285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First transaction will request a resource and receive a Basic challenge 6293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with realm="first_realm". 6294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes1[] = { 6295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET / HTTP/1.1\r\n" 6296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 6298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "\r\n"), 6299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads1[] = { 6301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 401 Unauthorized\r\n" 6302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 6303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "\r\n"), 6304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // After calling trans->RestartWithAuth(), provide an Authentication header 6307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for first_realm. The server will reject and provide a challenge with 6308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // second_realm. 6309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes2[] = { 6310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET / HTTP/1.1\r\n" 6311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 6313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: Basic Zmlyc3Q6YmF6\r\n" 6314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "\r\n"), 6315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads2[] = { 6317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 401 Unauthorized\r\n" 6318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WWW-Authenticate: Basic realm=\"second_realm\"\r\n" 6319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "\r\n"), 6320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This again fails, and goes back to first_realm. Make sure that the 6323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // entry is removed from cache. 6324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes3[] = { 6325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET / HTTP/1.1\r\n" 6326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 6328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: Basic c2Vjb25kOmZvdQ==\r\n" 6329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "\r\n"), 6330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads3[] = { 6332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 401 Unauthorized\r\n" 6333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WWW-Authenticate: Basic realm=\"first_realm\"\r\n" 6334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "\r\n"), 6335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Try one last time (with the correct password) and get the resource. 6338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes4[] = { 6339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET / HTTP/1.1\r\n" 6340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 6342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: Basic Zmlyc3Q6YmFy\r\n" 6343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "\r\n"), 6344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads4[] = { 6346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n" 6347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Type: text/html; charset=iso-8859-1\r\n" 63483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Content-Length: 5\r\n" 63493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "\r\n" 63503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "hello"), 6351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 6354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes1, arraysize(data_writes1)); 6355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 6356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes2, arraysize(data_writes2)); 6357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), 6358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes3, arraysize(data_writes3)); 6359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4), 6360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes4, arraysize(data_writes4)); 6361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data1); 6362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data2); 6363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data3); 6364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data4); 6365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback1; 6367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans( 63693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(CreateSession(&session_deps))); 63703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Issue the first request with Authorize headers. There should be a 6372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // password prompt for first_realm waiting to be filled in after the 6373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // transaction completes. 6374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback1, BoundNetLog()); 6375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback1.WaitForResult(); 6377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 6380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response->auth_challenge.get() == NULL); 6381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 6382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"first_realm", response->auth_challenge->realm); 6383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"basic", response->auth_challenge->scheme); 6384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Issue the second request with an incorrect password. There should be a 6386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // password prompt for second_realm waiting to be filled in after the 6387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // transaction completes. 6388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback2; 63893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFirst, kBaz, &callback2); 6390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback2.WaitForResult(); 6392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 6394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 6395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response->auth_challenge.get() == NULL); 6396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 6397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"second_realm", response->auth_challenge->realm); 6398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"basic", response->auth_challenge->scheme); 6399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Issue the third request with another incorrect password. There should be 6401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a password prompt for first_realm waiting to be filled in. If the password 6402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // prompt is not present, it indicates that the HttpAuthCacheEntry for 6403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // first_realm was not correctly removed. 6404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback3; 64053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kSecond, kFou, &callback3); 6406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback3.WaitForResult(); 6408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 6410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 6411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response->auth_challenge.get() == NULL); 6412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); 6413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"first_realm", response->auth_challenge->realm); 6414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(L"basic", response->auth_challenge->scheme); 6415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Issue the fourth request with the correct password and username. 6417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback4; 64183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFirst, kBar, &callback4); 6419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback4.WaitForResult(); 6421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 6422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 6423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 6424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() == NULL); 6425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6427c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { 64283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos("needs_to_be_set_for_this_test"); 64293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 6430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 64353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(kAlternateProtocolHttpHeader), 6436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 6437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 6438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 6446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 6448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 6450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 6452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 6453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair http_host_port_pair("www.google.com", 80); 6458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpAlternateProtocols& alternate_protocols = 6459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session->alternate_protocols(); 6460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE( 6461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch alternate_protocols.HasAlternateProtocolFor(http_host_port_pair)); 6462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 6467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 6468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response->was_fetched_via_spdy); 6470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response->was_npn_negotiated); 6471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 6473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 6475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(alternate_protocols.HasAlternateProtocolFor(http_host_port_pair)); 6477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpAlternateProtocols::PortProtocolPair alternate = 6478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch alternate_protocols.GetAlternateProtocolFor(http_host_port_pair); 6479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAlternateProtocols::PortProtocolPair expected_alternate; 6480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch expected_alternate.port = 443; 64813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick expected_alternate.protocol = HttpAlternateProtocols::NPN_SPDY_2; 6482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(expected_alternate.Equals(alternate)); 6483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 64853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 6486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) { 64893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 6490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockConnect mock_connect(true, ERR_CONNECTION_REFUSED); 6498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider first_data; 6499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch first_data.set_connect_data(mock_connect); 6500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&first_data); 6501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n\r\n"), 6504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 6505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, OK), 6506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider second_data( 6508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_reads, arraysize(data_reads), NULL, 0); 6509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&second_data); 6510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 6512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 6514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair http_host_port_pair("www.google.com", 80); 6516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAlternateProtocols* alternate_protocols = 6517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session->mutable_alternate_protocols(); 6518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch alternate_protocols->SetAlternateProtocolFor( 6519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch http_host_port_pair, 1234 /* port is ignored by MockConnect anyway */, 65203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAlternateProtocols::NPN_SPDY_2); 6521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 6523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 6530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 6531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 6534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 6536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE( 6538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch alternate_protocols->HasAlternateProtocolFor(http_host_port_pair)); 6539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpAlternateProtocols::PortProtocolPair alternate = 6540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch alternate_protocols->GetAlternateProtocolFor(http_host_port_pair); 6541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(HttpAlternateProtocols::BROKEN, alternate.protocol); 65423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 6543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) { 65463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 65473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(kExpectedNPNString); 6548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead("HTTP/1.1 200 OK\r\n"), 6557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(kAlternateProtocolHttpHeader), 6558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 6559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, OK), 6560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider first_transaction( 6563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_reads, arraysize(data_reads), NULL, 0); 6564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&first_transaction); 6565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SSLSocketDataProvider ssl(true, OK); 6567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 6568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl.next_proto = "spdy/2"; 6569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl.was_npn_negotiated = true; 6570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 6571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 6573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 6574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 6576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); 6577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead spdy_reads[] = { 6578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockRead(*resp), 6579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockRead(*data), 6580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(true, 0, 0), 6581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 6582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<DelayedSocketData> spdy_data( 6584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new DelayedSocketData( 6585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1, // wait for one write to finish before reading. 6586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen spdy_reads, arraysize(spdy_reads), 6587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen spdy_writes, arraysize(spdy_writes))); 6588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(spdy_data); 6589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 6591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider hanging_non_alternate_protocol_socket( 6592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0, NULL, 0); 6593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket.set_connect_data( 6594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen never_finishing_connect); 6595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider( 6596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &hanging_non_alternate_protocol_socket); 6597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TestCompletionCallback callback; 6599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 6601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 6602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 6609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 6610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 6613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 6615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen trans.reset(new HttpNetworkTransaction(session)); 6617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rv = trans->Start(&request, &callback, BoundNetLog()); 6619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 6620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(OK, callback.WaitForResult()); 6621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen response = trans->GetResponseInfo(); 6623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response != NULL); 6624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response->headers != NULL); 6625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(response->was_fetched_via_spdy); 6627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(response->was_npn_negotiated); 6628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("hello!", response_data); 6631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 66323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 66333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 6634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) { 66373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 66383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(kExpectedNPNString); 6639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 66483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(kAlternateProtocolHttpHeader), 6649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 6650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, OK), 6651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider first_transaction( 6654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_reads, arraysize(data_reads), NULL, 0); 6655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Socket 1 is the HTTP transaction with the Alternate-Protocol header. 6656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&first_transaction); 6657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 6659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider hanging_socket( 6660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0, NULL, 0); 6661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_socket.set_connect_data(never_finishing_connect); 6662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Socket 2 and 3 are the hanging Alternate-Protocol and 6663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // non-Alternate-Protocol jobs from the 2nd transaction. 6664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&hanging_socket); 6665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&hanging_socket); 6666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl(true, OK); 6668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 66693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto = "spdy/2"; 6670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.was_npn_negotiated = true; 6671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 6672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 6674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 6675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockWrite spdy_writes[] = { 6676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockWrite(*req1), 6677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockWrite(*req2), 6678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 6679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); 6680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> data1(ConstructSpdyBodyFrame(1, true)); 6681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 6682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> data2(ConstructSpdyBodyFrame(3, true)); 6683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead spdy_reads[] = { 6684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockRead(*resp1), 6685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockRead(*data1), 6686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockRead(*resp2), 6687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockRead(*data2), 6688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), 6689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> spdy_data( 6692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData( 6693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2, // wait for writes to finish before reading. 6694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_reads, arraysize(spdy_reads), 6695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_writes, arraysize(spdy_writes))); 6696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Socket 4 is the successful Alternate-Protocol for transaction 3. 6697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(spdy_data); 6698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3. 6700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&hanging_socket); 6701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 6703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TestCompletionCallback callback1; 6704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpNetworkTransaction trans1(session); 6705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int rv = trans1.Start(&request, &callback1, BoundNetLog()); 6707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 6708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(OK, callback1.WaitForResult()); 6709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const HttpResponseInfo* response = trans1.GetResponseInfo(); 6711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response != NULL); 6712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response->headers != NULL); 6713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string response_data; 6716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data)); 6717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("hello world", response_data); 6718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TestCompletionCallback callback2; 6720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpNetworkTransaction trans2(session); 6721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rv = trans2.Start(&request, &callback2, BoundNetLog()); 6722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 6723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TestCompletionCallback callback3; 6725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpNetworkTransaction trans3(session); 6726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rv = trans3.Start(&request, &callback3, BoundNetLog()); 6727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 6728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(OK, callback2.WaitForResult()); 6730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(OK, callback3.WaitForResult()); 6731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen response = trans2.GetResponseInfo(); 6733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response != NULL); 6734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response->headers != NULL); 6735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(response->was_fetched_via_spdy); 6737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(response->was_npn_negotiated); 6738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data)); 6739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("hello!", response_data); 6740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen response = trans3.GetResponseInfo(); 6742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response != NULL); 6743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(response->headers != NULL); 6744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(response->was_fetched_via_spdy); 6746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(response->was_npn_negotiated); 6747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data)); 6748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("hello!", response_data); 6749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpStreamFactory::set_next_protos(""); 6751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpStreamFactory::set_use_alternate_protocols(false); 6752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 6753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) { 6755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpStreamFactory::set_use_alternate_protocols(true); 6756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpStreamFactory::set_next_protos(kExpectedNPNString); 6757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SessionDependencies session_deps; 6758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpRequestInfo request; 6760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request.method = "GET"; 6761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request.url = GURL("http://www.google.com/"); 6762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request.load_flags = 0; 6763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6764ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead data_reads[] = { 6765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead("HTTP/1.1 200 OK\r\n"), 6766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(kAlternateProtocolHttpHeader), 6767ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead("hello world"), 6768ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(true, OK), 6769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 6770ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider first_transaction( 6772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen data_reads, arraysize(data_reads), NULL, 0); 6773ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&first_transaction); 6774ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6775ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SSLSocketDataProvider ssl(true, OK); 6776ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 6777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl.next_proto = "spdy/2"; 6778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl.was_npn_negotiated = true; 6779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 6780ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6781ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 6782ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider hanging_alternate_protocol_socket( 6783ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0, NULL, 0); 6784ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_alternate_protocol_socket.set_connect_data( 6785ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen never_finishing_connect); 6786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider( 6787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &hanging_alternate_protocol_socket); 6788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 2nd request is just a copy of the first one, over HTTP again. 6790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&first_transaction); 6791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 6793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 6795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 6796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 6803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 6804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 6807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 6809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch trans.reset(new HttpNetworkTransaction(session)); 6811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Start(&request, &callback, BoundNetLog()); 6813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 6817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 6818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 6819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6820ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(response->was_fetched_via_spdy); 6821ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(response->was_npn_negotiated); 6822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ("hello world", response_data); 6825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 68273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 6828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CapturingProxyResolver : public ProxyResolver { 6831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 6832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {} 6833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~CapturingProxyResolver() {} 6834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int GetProxyForURL(const GURL& url, 6836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyInfo* results, 6837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback, 6838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestHandle* request, 6839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 68403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, 68413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair("myproxy", 80)); 6842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch results->UseProxyServer(proxy_server); 6843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch resolved_.push_back(url); 6844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OK; 6845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 6846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void CancelRequest(RequestHandle request) { 6848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 6849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 6850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 685121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual void CancelSetPacScript() { 685221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NOTREACHED(); 685321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 685421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 6855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&, 6856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* /*callback*/) { 6857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OK; 6858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 6859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<GURL>& resolved() const { return resolved_; } 6861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 6863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<GURL> resolved_; 6864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver); 6866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 6867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6868c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForTunneledNpnSpdy) { 68693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 68703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(kExpectedNPNString); 6871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyConfig proxy_config; 6873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch proxy_config.set_auto_detect(true); 6874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch proxy_config.set_pac_url(GURL("http://fooproxyurl")); 6875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CapturingProxyResolver* capturing_proxy_resolver = 6877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new CapturingProxyResolver(); 6878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps(new ProxyService( 6879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver, 6880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL)); 6881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 68893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(kAlternateProtocolHttpHeader), 6890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 6891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, OK), 6892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider first_transaction( 6895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_reads, arraysize(data_reads), NULL, 0); 6896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&first_transaction); 6897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl(true, OK); 6899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 69003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto = "spdy/2"; 6901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.was_npn_negotiated = true; 6902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 6903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 6905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite spdy_writes[] = { 6906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 6907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 6908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: keep-alive\r\n\r\n"), // 0 6909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req) // 3 6910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 6913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 6915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); 6916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead spdy_reads[] = { 6917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1 6918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp.get(), 4), // 2, 4 6919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*data.get(), 4), // 5 6920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0, 4), // 6 6921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> spdy_data( 6924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData( 6925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_reads, arraysize(spdy_reads), 6926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_writes, arraysize(spdy_writes))); 6927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(spdy_data); 6928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 6930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider hanging_non_alternate_protocol_socket( 6931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0, NULL, 0); 6932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket.set_connect_data( 6933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen never_finishing_connect); 6934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider( 6935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &hanging_non_alternate_protocol_socket); 6936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 6938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 6940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 6941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 6943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 6947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 6948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 6949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response->was_fetched_via_spdy); 6951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response->was_npn_negotiated); 6952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 6954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 6956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch trans.reset(new HttpNetworkTransaction(session)); 6958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Start(&request, &callback, BoundNetLog()); 6960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 6961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 6962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 6964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 6965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 6966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 6967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 6968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_npn_negotiated); 6969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 6971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", response_data); 6972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size()); 6973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("http://www.google.com/", 6974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch capturing_proxy_resolver->resolved()[0].spec()); 6975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("https://www.google.com/", 6976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch capturing_proxy_resolver->resolved()[1].spec()); 6977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 69793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 6980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6982c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, 6983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UseAlternateProtocolForNpnSpdyWithExistingSpdySession) { 69843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 69853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(kExpectedNPNString); 6986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 6987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 6989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 6990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 6991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 6992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 6994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 69953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(kAlternateProtocolHttpHeader), 6996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 6997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, OK), 6998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 6999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider first_transaction( 7001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_reads, arraysize(data_reads), NULL, 0); 7002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&first_transaction); 7003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl(true, OK); 7005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 70063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto = "spdy/2"; 7007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.was_npn_negotiated = true; 7008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 7009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we use ssl for spdy here. 7010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySession::SetSSLMode(true); 7011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 7013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 7014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 7016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); 7017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead spdy_reads[] = { 7018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 7019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*data), 7020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), 7021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> spdy_data( 7024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData( 7025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // wait for one write to finish before reading. 7026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_reads, arraysize(spdy_reads), 7027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_writes, arraysize(spdy_writes))); 7028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(spdy_data); 7029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 7031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 7033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 7035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 7037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 7038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 7039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 7041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 7042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 7043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 7044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 7046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 7047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 7048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up an initial SpdySession in the pool to reuse. 70503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", 443); 70513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); 7052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<SpdySession> spdy_session = 7053dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->spdy_session_pool()->Get(pair, BoundNetLog()); 7054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<TransportSocketParams> transport_params( 7055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new TransportSocketParams(host_port_pair, MEDIUM, GURL(), false, false)); 70563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 70573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); 70583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, 7059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen connection->Init(host_port_pair.ToString(), 7060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen transport_params, 7061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOWEST, 7062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &callback, 7063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session->transport_socket_pool(), 70643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog())); 70653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback.WaitForResult()); 70663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 70673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLConfig ssl_config; 70683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session->ssl_config_service()->GetSSLConfig(&ssl_config); 706972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<ClientSocketHandle> ssl_connection(new ClientSocketHandle); 707072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_connection->set_socket(session_deps.socket_factory.CreateSSLClientSocket( 707172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen connection.release(), HostPortPair("" , 443), ssl_config, 707272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NULL /* ssl_host_info */, session_deps.cert_verifier.get(), NULL)); 707372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, ssl_connection->socket()->Connect(&callback)); 70743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback.WaitForResult()); 70753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 707672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(OK, spdy_session->InitializeWithSocket(ssl_connection.release(), 70773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick true, OK)); 70783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch trans.reset(new HttpNetworkTransaction(session)); 7080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Start(&request, &callback, BoundNetLog()); 7082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 7083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 7084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 7086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 7087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 7088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 7089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 7090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_npn_negotiated); 7091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 7093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", response_data); 7094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 70963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 7097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 7098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// GenerateAuthToken is a mighty big test. 7100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// It tests all permutation of GenerateAuthToken behavior: 7101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - Synchronous and Asynchronous completion. 7102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - OK or error on completion. 7103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - Direct connection, non-authenticating proxy, and authenticating proxy. 7104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - HTTP or HTTPS backend (to include proxy tunneling). 7105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - Non-authenticating and authenticating backend. 7106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 7107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In all, there are 44 reasonable permuations (for example, if there are 7108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// problems generating an auth token for an authenticating proxy, we don't 7109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// need to test all permutations of the backend server). 7110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 7111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The test proceeds by going over each of the configuration cases, and 7112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// potentially running up to three rounds in each of the tests. The TestConfig 7113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// specifies both the configuration for the test as well as the expectations 7114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// for the results. 7115c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { 71163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kServer[] = "http://www.example.com"; 71173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kSecureServer[] = "https://www.example.com"; 71183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kProxy[] = "myproxy:70"; 7119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS; 7120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum AuthTiming { 7122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTH_NONE, 7123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTH_SYNC, 7124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTH_ASYNC, 7125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGet( 7128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET / HTTP/1.1\r\n" 7129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n\r\n"); 7131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGetProxy( 7132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET http://www.example.com/ HTTP/1.1\r\n" 7133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: keep-alive\r\n\r\n"); 7135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGetAuth( 7136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET / HTTP/1.1\r\n" 7137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 7139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: auth_token\r\n\r\n"); 7140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGetProxyAuth( 7141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET http://www.example.com/ HTTP/1.1\r\n" 7142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: keep-alive\r\n" 7144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Authorization: auth_token\r\n\r\n"); 7145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGetAuthThroughProxy( 7146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET http://www.example.com/ HTTP/1.1\r\n" 7147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: keep-alive\r\n" 7149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: auth_token\r\n\r\n"); 7150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGetAuthWithProxyAuth( 7151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET http://www.example.com/ HTTP/1.1\r\n" 7152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: keep-alive\r\n" 7154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Authorization: auth_token\r\n" 7155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: auth_token\r\n\r\n"); 7156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kConnect( 7157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "CONNECT www.example.com:443 HTTP/1.1\r\n" 7158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: keep-alive\r\n\r\n"); 7160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kConnectProxyAuth( 7161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "CONNECT www.example.com:443 HTTP/1.1\r\n" 7162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: keep-alive\r\n" 7164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Authorization: auth_token\r\n\r\n"); 7165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead kSuccess( 7167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1 200 OK\r\n" 7168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Type: text/html; charset=iso-8859-1\r\n" 7169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 3\r\n\r\n" 7170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Yes"); 7171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead kFailure( 7172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Should not be called."); 7173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead kServerChallenge( 7174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1 401 Unauthorized\r\n" 7175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WWW-Authenticate: Mock realm=server\r\n" 7176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Type: text/html; charset=iso-8859-1\r\n" 7177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 14\r\n\r\n" 7178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Unauthorized\r\n"); 7179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead kProxyChallenge( 7180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1 407 Unauthorized\r\n" 7181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Authenticate: Mock realm=proxy\r\n" 7182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Proxy-Connection: close\r\n" 7183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Type: text/html; charset=iso-8859-1\r\n" 7184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 14\r\n\r\n" 7185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Unauthorized\r\n"); 7186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead kProxyConnected( 7187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1 200 Connection Established\r\n\r\n"); 7188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with 7190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // no constructors, but the C++ compiler on Windows warns about 7191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // unspecified data in compound literals. So, moved to using constructors, 7192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and TestRound's created with the default constructor should not be used. 7193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TestRound { 7194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound() 7195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : expected_rv(ERR_UNEXPECTED), 7196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extra_write(NULL), 7197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extra_read(NULL) { 7198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(const MockWrite& write_arg, const MockRead& read_arg, 7200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int expected_rv_arg) 7201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : write(write_arg), 7202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch read(read_arg), 7203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch expected_rv(expected_rv_arg), 7204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extra_write(NULL), 7205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extra_read(NULL) { 7206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(const MockWrite& write_arg, const MockRead& read_arg, 7208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int expected_rv_arg, const MockWrite* extra_write_arg, 7209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite* extra_read_arg) 7210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : write(write_arg), 7211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch read(read_arg), 7212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch expected_rv(expected_rv_arg), 7213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extra_write(extra_write_arg), 7214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extra_read(extra_read_arg) { 7215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite write; 7217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead read; 7218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int expected_rv; 7219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite* extra_write; 7220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead* extra_read; 7221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const int kNoSSL = 500; 7224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TestConfig { 7226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* proxy_url; 7227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AuthTiming proxy_auth_timing; 7228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int proxy_auth_rv; 7229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* server_url; 7230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AuthTiming server_auth_timing; 7231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int server_auth_rv; 7232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_auth_rounds; 7233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int first_ssl_round; 7234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound rounds[3]; 7235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_configs[] = { 7236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non-authenticating HTTP server with a direct connection. 7237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 7238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kSuccess, OK)}}, 7239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Authenticating HTTP server with a direct connection. 7240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 7241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 7244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 7247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 7250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non-authenticating HTTP server through a non-authenticating proxy. 7253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL, 7254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kSuccess, OK)}}, 7255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Authenticating HTTP server through a non-authenticating proxy. 7256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL, 7257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kServerChallenge, OK), 7258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 7259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL, 7260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kServerChallenge, OK), 7261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 7262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL, 7263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kServerChallenge, OK), 7264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthThroughProxy, kSuccess, OK)}}, 7265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL, 7266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kServerChallenge, OK), 7267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}}, 7268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non-authenticating HTTP server through an authenticating proxy. 7269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 7270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kSuccess, OK)}}, 7272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 7273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 7275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL, 7276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kSuccess, OK)}}, 7278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL, 7279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kFailure, kAuthErr)}}, 7281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Authenticating HTTP server through an authenticating proxy. 7282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 7283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 7286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 7287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 7290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL, 7291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 7294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL, 7295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 7298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 7299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 7302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 7303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 7306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL, 7307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}}, 7310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL, 7311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGetProxy, kProxyChallenge, OK), 7312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetProxyAuth, kServerChallenge, OK), 7313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}}, 7314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non-authenticating HTTPS server with a direct connection. 7315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 7316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kSuccess, OK)}}, 7317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Authenticating HTTPS server with a direct connection. 7318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 7319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 7322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 7325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 7328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kGet, kServerChallenge, OK), 7329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non-authenticating HTTPS server with a non-authenticating proxy. 7331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0, 7332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}}, 7333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Authenticating HTTPS server through a non-authenticating proxy. 7334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0, 7335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 7336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0, 7338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 7339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0, 7341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 7342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0, 7344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge), 7345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non-Authenticating HTTPS server through an authenticating proxy. 7347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 7348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 7350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 7351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 7353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1, 7354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}}, 7356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL, 7357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kFailure, kAuthErr)}}, 7359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Authenticating HTTPS server through an authenticating proxy. 7360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 7361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 7366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1, 7371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1, 7376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 7381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 7386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1, 7391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kSuccess, OK)}}, 7395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1, 7396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { TestRound(kConnect, kProxyChallenge, OK), 7397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kConnectProxyAuth, kProxyConnected, OK, 7398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGet, &kServerChallenge), 7399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestRound(kGetAuth, kFailure, kAuthErr)}}, 7400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 7403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuthHandlerMock::Factory* auth_factory( 7404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new HttpAuthHandlerMock::Factory()); 7405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.http_auth_handler_factory.reset(auth_factory); 7406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) { 7408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TestConfig& test_config = test_configs[i]; 7409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up authentication handlers as necessary. 7411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (test_config.proxy_auth_timing != AUTH_NONE) { 7412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 7413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string auth_challenge = "Mock realm=proxy"; 7414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL origin(test_config.proxy_url); 7415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(), 7416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_challenge.end()); 7417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY, 7418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin, BoundNetLog()); 7419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->SetGenerateExpectation( 7420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_config.proxy_auth_timing == AUTH_ASYNC, 7421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_config.proxy_auth_rv); 7422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY); 7423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (test_config.server_auth_timing != AUTH_NONE) { 7425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 7426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string auth_challenge = "Mock realm=server"; 7427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL origin(test_config.server_url); 7428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(), 7429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_challenge.end()); 7430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 7431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin, BoundNetLog()); 7432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->SetGenerateExpectation( 7433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_config.server_auth_timing == AUTH_ASYNC, 7434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_config.server_auth_rv); 7435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_SERVER); 7436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (test_config.proxy_url) { 7438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.proxy_service = 7439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixed(test_config.proxy_url); 7440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 74413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.proxy_service = ProxyService::CreateDirect(); 7442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 7445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 7446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL(test_config.server_url); 7447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 7448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 74503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction trans(CreateSession(&session_deps)); 7451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int round = 0; round < test_config.num_auth_rounds; ++round) { 7453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TestRound& read_write_round = test_config.rounds[round]; 7454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up expected reads and writes. 7456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[2]; 7457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads[0] = read_write_round.read; 7458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t length_reads = 1; 7459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (read_write_round.extra_read) { 7460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads[1] = *read_write_round.extra_read; 7461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch length_reads = 2; 7462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[2]; 7465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes[0] = read_write_round.write; 7466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t length_writes = 1; 7467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (read_write_round.extra_write) { 7468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes[1] = *read_write_round.extra_write; 7469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch length_writes = 2; 7470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data_provider( 7472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads, length_reads, writes, length_writes); 7473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data_provider); 7474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add an SSL sequence if necessary. 7476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl_socket_data_provider(false, OK); 7477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (round >= test_config.first_ssl_round) 7478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider( 7479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ssl_socket_data_provider); 7480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start or restart the transaction. 7482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 7483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv; 7484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (round == 0) { 74853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans.Start(&request, &callback, BoundNetLog()); 7486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 74873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans.RestartWithAuth(kFoo, kBar, &callback); 7488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == ERR_IO_PENDING) 7490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 7491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compare results with expected data. 7493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(read_write_round.expected_rv, rv); 74943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans.GetResponseInfo(); 7495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (read_write_round.expected_rv == OK) { 7496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response == NULL); 7497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 7498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response == NULL); 7499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(round + 1, test_config.num_auth_rounds); 7500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 7501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (round + 1 < test_config.num_auth_rounds) { 7503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response->auth_challenge.get() == NULL); 7504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 7505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() == NULL); 7506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 7510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7511c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { 7512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do multi-round authentication and make sure it works correctly. 7513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 7514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuthHandlerMock::Factory* auth_factory( 7515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new HttpAuthHandlerMock::Factory()); 7516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.http_auth_handler_factory.reset(auth_factory); 75173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.proxy_service = ProxyService::CreateDirect(); 7518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1"); 7519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.host_resolver->set_synchronous_mode(true); 7520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); 7522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->set_connection_based(true); 7523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string auth_challenge = "Mock realm=server"; 7524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL origin("http://www.example.com"); 7525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(), 7526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_challenge.end()); 7527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, 7528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin, BoundNetLog()); 7529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_SERVER); 7530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = OK; 7532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = NULL; 7533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 7534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 7535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = origin; 7536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 753772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 753872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 753972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 754072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Use a TCP Socket Pool with only one connection per group. This is used 754172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // to validate that the TCP socket is not released to the pool between 754272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // each round of multi-round authentication. 754372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpNetworkSessionPeer session_peer(session); 7544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ClientSocketPoolHistograms transport_pool_histograms("SmallTCP"); 7545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TransportClientSocketPool* transport_pool = new TransportClientSocketPool( 754672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 50, // Max sockets for pool 754772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1, // Max sockets per group 7548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &transport_pool_histograms, 754972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.host_resolver.get(), 755072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &session_deps.socket_factory, 755172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.net_log); 7552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_peer.SetTransportSocketPool(transport_pool); 755372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 755472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 7555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 7556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGet( 7558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET / HTTP/1.1\r\n" 7559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n\r\n"); 7561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockWrite kGetAuth( 7562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GET / HTTP/1.1\r\n" 7563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.example.com\r\n" 7564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n" 7565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Authorization: auth_token\r\n\r\n"); 7566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead kServerChallenge( 7568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1 401 Unauthorized\r\n" 7569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WWW-Authenticate: Mock realm=server\r\n" 7570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Type: text/html; charset=iso-8859-1\r\n" 7571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 14\r\n\r\n" 7572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Unauthorized\r\n"); 7573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MockRead kSuccess( 7574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1 200 OK\r\n" 7575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Type: text/html; charset=iso-8859-1\r\n" 7576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Content-Length: 3\r\n\r\n" 7577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Yes"); 7578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 7580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First round 7581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kGet, 7582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Second round 7583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kGetAuth, 7584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Third round 7585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kGetAuth, 75863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Fourth round 758772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kGetAuth, 758872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Competing request 758972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kGet, 7590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 7592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First round 7593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kServerChallenge, 7594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Second round 7595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kServerChallenge, 7596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Third round 75973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kServerChallenge, 75983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Fourth round 7599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSuccess, 760072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Competing response 760172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kSuccess, 7602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data_provider(reads, arraysize(reads), 7604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes)); 7605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data_provider); 7606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 760772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const char* const kSocketGroup = "www.example.com:80"; 760872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 760972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // First round of authentication. 7610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->SetGenerateExpectation(false, OK); 7611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Start(&request, &callback, BoundNetLog()); 7612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == ERR_IO_PENDING) 7613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 7614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 7615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 7616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 7617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response->auth_challenge.get() == NULL); 7618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 761972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 762072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // In between rounds, another request comes in for the same domain. 762172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // It should not be able to grab the TCP socket that trans has already 762272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // claimed. 762372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans_compete( 762472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(session)); 762572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback_compete; 762672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans_compete->Start(&request, &callback_compete, BoundNetLog()); 762772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(ERR_IO_PENDING, rv); 762872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // callback_compete.WaitForResult at this point would stall forever, 762972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // since the HttpNetworkTransaction does not release the request back to 763072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the pool until after authentication completes. 7631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 763272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Second round of authentication. 7633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->SetGenerateExpectation(false, OK); 76343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(kFoo, kBar, &callback); 7635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == ERR_IO_PENDING) 7636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 7637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 7638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 7639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 7640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() == NULL); 7641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 7642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 764372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Third round of authentication. 7644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auth_handler->SetGenerateExpectation(false, OK); 76453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(string16(), string16(), &callback); 76463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv == ERR_IO_PENDING) 76473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 76483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 76493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response = trans->GetResponseInfo(); 76503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 76513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->auth_challenge.get() == NULL); 7652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 76533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 765472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Fourth round of authentication, which completes successfully. 76553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick auth_handler->SetGenerateExpectation(false, OK); 76563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->RestartWithAuth(string16(), string16(), &callback); 7657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == ERR_IO_PENDING) 7658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 7659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 7660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response = trans->GetResponseInfo(); 7661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(response == NULL); 7662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->auth_challenge.get() == NULL); 7663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 766472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 766572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Read the body since the fourth round was successful. This will also 766672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // release the socket back to the pool. 766772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50)); 766872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->Read(io_buf, io_buf->size(), &callback); 766972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv == ERR_IO_PENDING) 767072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 767172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(3, rv); 767272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->Read(io_buf, io_buf->size(), &callback); 767372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(0, rv); 767472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // There are still 0 idle sockets, since the trans_compete transaction 767572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // will be handed it immediately after trans releases it to the group. 7676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 767772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 767872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The competing request can now finish. Wait for the headers and then 767972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // read the body. 768072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback_compete.WaitForResult(); 768172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(OK, rv); 768272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans_compete->Read(io_buf, io_buf->size(), &callback); 768372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv == ERR_IO_PENDING) 768472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 768572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(3, rv); 768672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans_compete->Read(io_buf, io_buf->size(), &callback); 768772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(0, rv); 768872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 768972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Finally, the socket is released to the group. 7690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup)); 7691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 7692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TLSDecompressionFailureSocketDataProvider : public SocketDataProvider { 7694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 7695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit TLSDecompressionFailureSocketDataProvider(bool fail_all) 7696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : fail_all_(fail_all) { 7697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual MockRead GetNextRead() { 7700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (fail_all_) 7701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MockRead(false /* async */, ERR_SSL_DECOMPRESSION_FAILURE_ALERT); 7702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MockRead(false /* async */, 7704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nok.\r\n"); 7705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual MockWriteResult OnWrite(const std::string& data) { 7708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MockWriteResult(false /* async */, data.size()); 7709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Reset() { 7712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 7715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool fail_all_; 7716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 7717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we restart a connection when we see a decompression failure from 7719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the peer during the handshake. (In the real world we'll restart with SSLv3 7720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and we won't offer DEFLATE in that case.) 7721c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, RestartAfterTLSDecompressionFailure) { 7722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 7723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 7724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("https://tlsdecompressionfailure.example.com/"); 7725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 7726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 7728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TLSDecompressionFailureSocketDataProvider socket_data_provider1( 7729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false /* fail all reads */); 7730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TLSDecompressionFailureSocketDataProvider socket_data_provider2(false); 7731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl_socket_data_provider1( 7732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, ERR_SSL_DECOMPRESSION_FAILURE_ALERT); 7733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl_socket_data_provider2(false, OK); 7734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1); 7735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2); 7736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider( 7737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ssl_socket_data_provider1); 7738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider( 7739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ssl_socket_data_provider2); 7740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Work around http://crbug.com/37454 7742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider bug37454_connection; 7743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bug37454_connection.set_connect_data(MockConnect(true, ERR_UNEXPECTED)); 7744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&bug37454_connection); 7745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 7747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 7748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 7749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 7751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 7752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 7753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 7755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 7756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 7757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 7758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 7760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 7761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("ok.", response_data); 7762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 7763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we restart a connection if we get a decompression failure from the 7765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// peer while reading the first bytes from the connection. This occurs when the 7766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// peer cannot handle DEFLATE but we're using False Start, so we don't notice 7767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the handshake. 7768c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, 7769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RestartAfterTLSDecompressionFailureWithFalseStart) { 7770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 7771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 7772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("https://tlsdecompressionfailure2.example.com/"); 7773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 7774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 7776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TLSDecompressionFailureSocketDataProvider socket_data_provider1( 7777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true /* fail all reads */); 7778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TLSDecompressionFailureSocketDataProvider socket_data_provider2(false); 7779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl_socket_data_provider1(false, OK); 7780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl_socket_data_provider2(false, OK); 7781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1); 7782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2); 7783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider( 7784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ssl_socket_data_provider1); 7785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider( 7786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ssl_socket_data_provider2); 7787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 7789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 7790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 7791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 7793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 7794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 7795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 7797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 7798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 7799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 7800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 7802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 7803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("ok.", response_data); 7804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 7805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This tests the case that a request is issued via http instead of spdy after 7807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// npn is negotiated. 7808c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) { 78093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 78103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos("\x08http/1.1\x07http1.1"); 7811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 7812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 7813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 7814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("https://www.google.com/"); 7815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 7816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite data_writes[] = { 7818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite("GET / HTTP/1.1\r\n" 7819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Host: www.google.com\r\n" 7820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Connection: keep-alive\r\n\r\n"), 7821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead data_reads[] = { 7824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n"), 78253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(kAlternateProtocolHttpHeader), 7826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world"), 7827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, OK), 7828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl(true, OK); 7831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 7832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.next_proto = "http/1.1"; 7833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 7835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(data_reads, arraysize(data_reads), 7837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_writes, arraysize(data_writes)); 7838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 7839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 7841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 7843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 7844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 7846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 7848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 7849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 7851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 7852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 7853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 7854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 7856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); 7857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world", response_data); 7858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(response->was_fetched_via_spdy); 7860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_npn_negotiated); 7861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 78633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 7864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 7865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7866c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) { 7867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Simulate the SSL handshake completing with an NPN negotiation 7868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // followed by an immediate server closing of the socket. 7869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fix crash: http://crbug.com/46369 78703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 78713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(kExpectedNPNString); 7872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SessionDependencies session_deps; 7873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 7875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 7876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("https://www.google.com/"); 7877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 7878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLSocketDataProvider ssl(true, OK); 7880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 78813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto = "spdy/2"; 7882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl.was_npn_negotiated = true; 7883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 7884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 7886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 7887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead spdy_reads[] = { 7889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, 0, 0) // Not async - return 0 immediately. 7890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 7891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> spdy_data( 7893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData( 7894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // don't wait in this case, immediate hangup. 7895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_reads, arraysize(spdy_reads), 7896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy_writes, arraysize(spdy_writes))); 7897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_deps.socket_factory.AddSocketDataProvider(spdy_data); 7898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 7900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 7902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 7903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 7905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 7906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); 7907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 79093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 79103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 79113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79123345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { 79133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This test ensures that the URL passed into the proxy is upgraded 79143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to https when doing an Alternate Protocol upgrade. 79153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 79163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos( 79173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "\x08http/1.1\x07http1.1\x06spdy/2\x04spdy"); 79183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7919731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 79203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthHandlerMock::Factory* auth_factory = 79213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpAuthHandlerMock::Factory(); 79223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock(); 79233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY); 79243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick auth_factory->set_do_init_from_challenge(true); 79253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.http_auth_handler_factory.reset(auth_factory); 79263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 79283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 79293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com"); 79303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 79313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // First round goes unauthenticated through the proxy. 79333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes_1[] = { 79343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 79353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 79363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n" 79373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "\r\n"), 79383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 79393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads_1[] = { 79403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 79413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n" 79423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Alternate-Protocol: 443:npn-spdy/2\r\n" 79433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: close\r\n" 79443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "\r\n"), 79453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 79463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1), 79473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes_1, arraysize(data_writes_1)); 79483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Second round tries to tunnel to www.google.com due to the 79503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Alternate-Protocol announcement in the first round. It fails due 79513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to a proxy authentication challenge. 79523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // After the failure, a tunnel is established to www.google.com using 79533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Proxy-Authorization headers. There is then a SPDY request round. 79543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 79553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // NOTE: Despite the "Proxy-Connection: Close", these are done on the 79563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // same MockTCPClientSocket since the underlying HttpNetworkClientSocket 79573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // does a Disconnect and Connect on the same socket, rather than trying 79583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to obtain a new one. 79593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 79603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // NOTE: Originally, the proxy response to the second CONNECT request 79613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // simply returned another 407 so the unit test could skip the SSL connection 79623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // establishment and SPDY framing issues. Alas, the 79633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // retry-http-when-alternate-protocol fails logic kicks in, which was more 79643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // complicated to set up expectations for than the SPDY session. 79653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 79673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 79683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); 79693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes_2[] = { 79713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // First connection attempt without Proxy-Authorization. 79723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 79733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 79743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n" 79753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "\r\n"), 79763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Second connection attempt with Proxy-Authorization. 79783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 79793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 79803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n" 79813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Authorization: auth_token\r\n" 79823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "\r\n"), 79833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SPDY request 79853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req), 79863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 79873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n" 79883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Authenticate: Mock\r\n" 79893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: close\r\n" 79903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "\r\n"); 79913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; 79923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads_2[] = { 79933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // First connection attempt fails 79943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1), 79953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, kRejectConnectResponse, 79963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kRejectConnectResponse) - 1, 1), 79973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 79983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Second connection attempt passes 79993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, kAcceptConnectResponse, 80003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kAcceptConnectResponse) -1, 4), 80013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SPDY response 80033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp.get(), 6), 80043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*data.get(), 6), 80053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 6), 80063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 80073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_2( 80083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(data_reads_2, arraysize(data_reads_2), 80093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes_2, arraysize(data_writes_2))); 80103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 80123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 80133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto = "spdy/2"; 80143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.was_npn_negotiated = true; 80153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 8016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 8017ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StaticSocketDataProvider hanging_non_alternate_protocol_socket( 8018ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, 0, NULL, 0); 8019ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket.set_connect_data( 8020ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen never_finishing_connect); 8021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 80223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data_1); 80233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(data_2.get()); 80243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 8025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps.socket_factory.AddSocketDataProvider( 8026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &hanging_non_alternate_protocol_socket); 80273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 80283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // First round should work and provide the Alternate-Protocol state. 80303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback_1; 80313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans_1(new HttpNetworkTransaction(session)); 80323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans_1->Start(&request, &callback_1, BoundNetLog()); 80333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 80343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback_1.WaitForResult()); 80353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Second round should attempt a tunnel connect and get an auth challenge. 80373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback_2; 80383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans_2(new HttpNetworkTransaction(session)); 80393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans_2->Start(&request, &callback_2, BoundNetLog()); 80403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 80413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback_2.WaitForResult()); 80423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans_2->GetResponseInfo(); 80433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 80443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response->auth_challenge.get() == NULL); 80453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Restart with auth. Tunnel should work and response received. 80473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback_3; 80483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans_2->RestartWithAuth(kFoo, kBar, &callback_3); 80493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 80503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback_3.WaitForResult()); 80513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // After all that work, these two lines (or actually, just the scheme) are 80533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // what this test is all about. Make sure it happens correctly. 80543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GURL& request_url = auth_handler->request_url(); 80553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("https", request_url.scheme()); 80563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("www.google.com", request_url.host()); 80573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(""); 80593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 80603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 80613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that if we cancel the transaction as the connection is completing, that 80633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// everything tears down correctly. 80643345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, SimpleCancel) { 80653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup everything about the connection to complete synchronously, so that 80663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // after calling HttpNetworkTransaction::Start, the only thing we're waiting 80673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // for is the callback from the HttpStreamRequest. 80683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Then cancel the transaction. 80693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we don't crash. 80703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockConnect mock_connect(false, OK); 80713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads[] = { 80723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, "HTTP/1.0 200 OK\r\n\r\n"), 80733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, "hello world"), 80743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 80753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 80763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 80783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 80793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 80803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 80813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 808272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 808372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.host_resolver->set_synchronous_mode(true); 808472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpTransaction> trans( 808572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(CreateSession(&session_deps))); 808672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 80873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); 80883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data.set_connect_data(mock_connect); 80893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data); 80903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 80923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 80943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, log.bound()); 80953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 80963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick trans.reset(); // Cancel the transaction here. 80973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 80983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 80993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 81003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test a basic GET request through a proxy. 81023345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, ProxyGet) { 8103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 81043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 81053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.net_log = log.bound().net_log(); 81063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 81073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 81093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 81103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 81113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes1[] = { 81133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" 81143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 81153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 81163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 81173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads1[] = { 81193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 81203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 81213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 100\r\n\r\n"), 81223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 81233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 81243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 81263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes1, arraysize(data_writes1)); 81273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data1); 81283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 81303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 81323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 81343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 81353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback1.WaitForResult(); 81373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 81383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 81403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 81413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers->IsKeepAlive()); 81433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(200, response->headers->response_code()); 81443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(100, response->headers->GetContentLength()); 81453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_proxy); 81463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 81473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 81483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test a basic HTTPS GET request through a proxy. 81503345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { 8151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 81523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 81533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.net_log = log.bound().net_log(); 81543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 81553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 81573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 81583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 81593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Since we have proxy, should try to establish tunnel. 81613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes1[] = { 81623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 81633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 81643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 81653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 81673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 81683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 81693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 81703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads1[] = { 81723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 81733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 OK\r\n"), 81753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), 81763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("Content-Length: 100\r\n\r\n"), 81773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, OK), 81783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 81793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 81813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes1, arraysize(data_writes1)); 81823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data1); 81833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 81843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 81853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 81873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 81893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 81913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 81923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 81933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback1.WaitForResult(); 81943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 819521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 819621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 81973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t pos = ExpectLogContainsSomewhere( 819821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 81993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::PHASE_NONE); 82003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ExpectLogContainsSomewhere( 820121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, pos, 82023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 82033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::PHASE_NONE); 82043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 82063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_FALSE(response == NULL); 82073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers->IsKeepAlive()); 82093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(200, response->headers->response_code()); 82103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(100, response->headers->GetContentLength()); 82113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); 82123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_proxy); 82133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 82143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test a basic HTTPS GET request through a proxy, but the server hangs up 82163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// while establishing the tunnel. 82173345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { 8218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); 82193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 82203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.net_log = log.bound().net_log(); 82213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 82223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 82243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 82253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 82263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Since we have proxy, should try to establish tunnel. 82283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite data_writes1[] = { 82293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" 82303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 82313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"), 82323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite("GET / HTTP/1.1\r\n" 82343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 82353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Connection: keep-alive\r\n\r\n"), 82363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 82373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead data_reads1[] = { 82393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 82403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 82413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0), // EOF 82423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 82433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 82453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_writes1, arraysize(data_writes1)); 82463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(&data1); 82473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 82483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 82493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 82513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 82533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback1, log.bound()); 82553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 82563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback1.WaitForResult(); 82583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_EMPTY_RESPONSE, rv); 825921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 826021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 82613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t pos = ExpectLogContainsSomewhere( 826221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 82633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::PHASE_NONE); 82643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ExpectLogContainsSomewhere( 826521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, pos, 82663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, 82673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::PHASE_NONE); 82683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 82693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test for crbug.com/55424. 82713345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) { 82723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SessionDependencies session_deps; 82733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet( 82753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "https://www.google.com", false, 1, LOWEST)); 82763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 82773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 82793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true)); 82803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead spdy_reads[] = { 82813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 82823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*data), 82833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0), 82843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 82853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> spdy_data( 82873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData( 82883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // wait for one write to finish before reading. 82893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_reads, arraysize(spdy_reads), 82903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_writes, arraysize(spdy_writes))); 82913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSocketDataProvider(spdy_data); 82923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SSLSocketDataProvider ssl(true, OK); 82943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; 82953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.next_proto = "spdy/2"; 82963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl.was_npn_negotiated = true; 82973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); 82983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 82993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 83003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 83013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Set up an initial SpdySession in the pool to reuse. 83023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", 443); 83033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); 83043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<SpdySession> spdy_session = 8305dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->spdy_session_pool()->Get(pair, BoundNetLog()); 8306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<TransportSocketParams> transport_params( 8307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new TransportSocketParams(host_port_pair, MEDIUM, GURL(), false, false)); 83083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 83093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 83103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); 83113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, 8312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen connection->Init(host_port_pair.ToString(), transport_params, 8313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOWEST, &callback, 8314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session->transport_socket_pool(), BoundNetLog())); 83153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback.WaitForResult()); 83163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_session->InitializeWithSocket(connection.release(), false, OK); 83173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 83183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 83193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "GET"; 83203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("https://www.google.com/"); 83213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.load_flags = 0; 83223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 83233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This is the important line that marks this as a preconnect. 83243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED; 83253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 83263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 83273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 83283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&request, &callback, BoundNetLog()); 83293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 83303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, callback.WaitForResult()); 8331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 8332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Given a net error, cause that error to be returned from the first Write() 83344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// call and verify that the HttpTransaction fails with that error. 83354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochstatic void CheckErrorIsPassedBack(int error, bool async) { 833672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpRequestInfo request_info; 833772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.url = GURL("https://www.example.com/"); 833872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.method = "GET"; 833972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.load_flags = net::LOAD_NORMAL; 834072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 83414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SessionDependencies session_deps; 83424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 83434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SSLSocketDataProvider ssl_data(async, OK); 83444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::MockWrite data_writes[] = { 83454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::MockWrite(async, error), 83464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 83474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::StaticSocketDataProvider data(NULL, 0, 83484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch data_writes, arraysize(data_writes)); 83494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch session_deps.socket_factory.AddSocketDataProvider(&data); 83504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data); 83514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 83524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 83534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 83544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 83554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch TestCompletionCallback callback; 83564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int rv = trans->Start(&request_info, &callback, net::BoundNetLog()); 83574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 83584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = callback.WaitForResult(); 83594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_EQ(error, rv); 83604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 83614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 83624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST_F(HttpNetworkTransactionTest, SSLWriteCertError) { 83634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Just check a grab bag of cert errors. 83644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch static const int kErrors[] = { 83654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ERR_CERT_COMMON_NAME_INVALID, 83664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ERR_CERT_AUTHORITY_INVALID, 83674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ERR_CERT_DATE_INVALID, 83684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 83694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (size_t i = 0; i < arraysize(kErrors); i++) { 83704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CheckErrorIsPassedBack(kErrors[i], false /* not async */); 83714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CheckErrorIsPassedBack(kErrors[i], true /* async */); 83724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 83734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 83744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 837572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Ensure that a client certificate is removed from the SSL client auth 837672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// cache when: 837772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1) No proxy is involved. 837872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 2) TLS False Start is disabled. 837972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3) The initial TLS handshake requests a client certificate. 838072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 4) The client supplies an invalid/unacceptable certificate. 838172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) { 838272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpRequestInfo request_info; 838372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.url = GURL("https://www.example.com/"); 838472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.method = "GET"; 838572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.load_flags = net::LOAD_NORMAL; 838672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 838772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 838872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 838972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 839072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cert_request->host_and_port = "www.example.com:443"; 839172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 839272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // [ssl_]data1 contains the data for the first SSL handshake. When a 839372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // CertificateRequest is received for the first time, the handshake will 839472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // be aborted to allow the caller to provide a certificate. 839572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data1(true /* async */, 839672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 839772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data1.cert_request_info = cert_request.get(); 839872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1); 839972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 840072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data1); 840172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 840272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // [ssl_]data2 contains the data for the second SSL handshake. When TLS 840372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // False Start is not being used, the result of the SSL handshake will be 840472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // returned as part of the SSLClientSocket::Connect() call. This test 840572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // matches the result of a server sending a handshake_failure alert, 840672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // rather than a Finished message, because it requires a client 840772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // certificate and none was supplied. 840872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data2(true /* async */, 840972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_SSL_PROTOCOL_ERROR); 841072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data2.cert_request_info = cert_request.get(); 841172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2); 841272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 841372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data2); 841472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 841572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // [ssl_]data3 contains the data for the third SSL handshake. When a 841672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // connection to a server fails during an SSL handshake, 841772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // HttpNetworkTransaction will attempt to fallback to SSLv3 if the initial 841872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // connection was attempted with TLSv1. This is transparent to the caller 841972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // of the HttpNetworkTransaction. Because this test failure is due to 842072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // requiring a client certificate, this fallback handshake should also 842172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // fail. 842272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data3(true /* async */, 842372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_SSL_PROTOCOL_ERROR); 842472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data3.cert_request_info = cert_request.get(); 842572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3); 842672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 842772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data3); 842872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 842972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 843072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 843172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 843272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Begin the SSL handshake with the peer. This consumes ssl_data1. 843372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback; 843472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = trans->Start(&request_info, &callback, net::BoundNetLog()); 843572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_IO_PENDING, rv); 843672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 843772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Complete the SSL handshake, which should abort due to requiring a 843872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // client certificate. 843972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 844072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 844172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 844272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Indicate that no certificate should be supplied. From the perspective 844372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // of SSLClientCertCache, NULL is just as meaningful as a real 844472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // certificate, so this is the same as supply a 844572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // legitimate-but-unacceptable certificate. 844672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithCertificate(NULL, &callback); 844772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_IO_PENDING, rv); 844872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 844972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure the certificate was added to the client auth cache before 845072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // allowing the connection to continue restarting. 845172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<X509Certificate> client_cert; 845272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 845372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 845472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(NULL, client_cert.get()); 845572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 845672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Restart the handshake. This will consume ssl_data2, which fails, and 845772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // then consume ssl_data3, which should also fail. The result code is 845872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // checked against what ssl_data3 should return. 845972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 846072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 846172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 846272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure that the client certificate is removed from the cache on a 846372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // handshake failure. 846472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 846572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 846672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 846772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 846872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Ensure that a client certificate is removed from the SSL client auth 846972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// cache when: 847072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1) No proxy is involved. 847172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 2) TLS False Start is enabled. 847272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3) The initial TLS handshake requests a client certificate. 847372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 4) The client supplies an invalid/unacceptable certificate. 847472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) { 847572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpRequestInfo request_info; 847672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.url = GURL("https://www.example.com/"); 847772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.method = "GET"; 847872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.load_flags = net::LOAD_NORMAL; 847972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 848072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps; 848172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 848272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 848372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cert_request->host_and_port = "www.example.com:443"; 848472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 848572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // When TLS False Start is used, SSLClientSocket::Connect() calls will 848672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // return successfully after reading up to the peer's Certificate message. 848772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // This is to allow the caller to call SSLClientSocket::Write(), which can 848872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // enqueue application data to be sent in the same packet as the 848972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // ChangeCipherSpec and Finished messages. 849072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The actual handshake will be finished when SSLClientSocket::Read() is 849172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // called, which expects to process the peer's ChangeCipherSpec and 849272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Finished messages. If there was an error negotiating with the peer, 849372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // such as due to the peer requiring a client certificate when none was 849472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // supplied, the alert sent by the peer won't be processed until Read() is 849572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // called. 849672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 849772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Like the non-False Start case, when a client certificate is requested by 849872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the peer, the handshake is aborted during the Connect() call. 849972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // [ssl_]data1 represents the initial SSL handshake with the peer. 850072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data1(true /* async */, 850172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 850272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data1.cert_request_info = cert_request.get(); 850372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1); 850472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 850572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data1); 850672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 850772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // When a client certificate is supplied, Connect() will not be aborted 850872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // when the peer requests the certificate. Instead, the handshake will 850972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // artificially succeed, allowing the caller to write the HTTP request to 851072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the socket. The handshake messages are not processed until Read() is 851172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // called, which then detects that the handshake was aborted, due to the 851272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // peer sending a handshake_failure because it requires a client 851372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // certificate. 851472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data2(true /* async */, net::OK); 851572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data2.cert_request_info = cert_request.get(); 851672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2); 851772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::MockRead data2_reads[] = { 851872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::MockRead(true /* async */, net::ERR_SSL_PROTOCOL_ERROR), 851972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 852072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data2( 852172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data2_reads, arraysize(data2_reads), NULL, 0); 852272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data2); 852372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 852472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is 852572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the data for the SSL handshake once the TLSv1 connection falls back to 852672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // SSLv3. It has the same behaviour as [ssl_]data2. 852772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data3(true /* async */, net::OK); 852872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data3.cert_request_info = cert_request.get(); 852972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3); 853072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data3( 853172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data2_reads, arraysize(data2_reads), NULL, 0); 853272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data3); 853372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 853472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 853572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); 853672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 853772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Begin the initial SSL handshake. 853872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback; 853972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = trans->Start(&request_info, &callback, net::BoundNetLog()); 854072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_IO_PENDING, rv); 854172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 854272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Complete the SSL handshake, which should abort due to requiring a 854372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // client certificate. 854472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 854572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 854672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 854772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Indicate that no certificate should be supplied. From the perspective 854872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // of SSLClientCertCache, NULL is just as meaningful as a real 854972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // certificate, so this is the same as supply a 855072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // legitimate-but-unacceptable certificate. 855172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithCertificate(NULL, &callback); 855272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_IO_PENDING, rv); 855372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 855472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure the certificate was added to the client auth cache before 855572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // allowing the connection to continue restarting. 855672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<X509Certificate> client_cert; 855772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 855872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 855972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(NULL, client_cert.get()); 856072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 856172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 856272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Restart the handshake. This will consume ssl_data2, which fails, and 856372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // then consume ssl_data3, which should also fail. The result code is 856472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // checked against what ssl_data3 should return. 856572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 856672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 856772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 856872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure that the client certificate is removed from the cache on a 856972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // handshake failure. 857072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 857172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 857272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 857372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 857472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Ensure that a client certificate is removed from the SSL client auth 857572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// cache when: 857672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1) An HTTPS proxy is involved. 857772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3) The HTTPS proxy requests a client certificate. 857872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 4) The client supplies an invalid/unacceptable certificate for the 857972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// proxy. 858072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The test is repeated twice, first for connecting to an HTTPS endpoint, 858172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// then for connecting to an HTTP endpoint. 858272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) { 858372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionDependencies session_deps( 858472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProxyService::CreateFixed("https://proxy:70")); 858572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 858672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.net_log = log.bound().net_log(); 858772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 858872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); 858972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cert_request->host_and_port = "proxy:70"; 859072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 859172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of 859272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // [ssl_]data[1-3]. Rather than represending the endpoint 859372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // (www.example.com:443), they represent failures with the HTTPS proxy 859472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // (proxy:70). 859572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data1(true /* async */, 859672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 859772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data1.cert_request_info = cert_request.get(); 859872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1); 859972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); 860072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data1); 860172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 860272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data2(true /* async */, 860372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_SSL_PROTOCOL_ERROR); 860472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data2.cert_request_info = cert_request.get(); 860572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2); 860672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); 860772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data2); 860872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 860972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SSLSocketDataProvider ssl_data3(true /* async */, 861072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_SSL_PROTOCOL_ERROR); 861172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ssl_data3.cert_request_info = cert_request.get(); 861272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3); 861372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); 861472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.AddSocketDataProvider(&data3); 861572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 861672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::HttpRequestInfo requests[2]; 861772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen requests[0].url = GURL("https://www.example.com/"); 861872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen requests[0].method = "GET"; 861972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen requests[0].load_flags = net::LOAD_NORMAL; 862072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 862172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen requests[1].url = GURL("http://www.example.com/"); 862272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen requests[1].method = "GET"; 862372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen requests[1].load_flags = net::LOAD_NORMAL; 862472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 862572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < arraysize(requests); ++i) { 862672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen session_deps.socket_factory.ResetNextMockIndexes(); 862772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); 862872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<HttpNetworkTransaction> trans( 862972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HttpNetworkTransaction(session)); 863072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 863172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Begin the SSL handshake with the proxy. 863272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TestCompletionCallback callback; 863372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = trans->Start(&requests[i], &callback, net::BoundNetLog()); 863472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_IO_PENDING, rv); 863572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 863672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Complete the SSL handshake, which should abort due to requiring a 863772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // client certificate. 863872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 863972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 864072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 864172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Indicate that no certificate should be supplied. From the perspective 864272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // of SSLClientCertCache, NULL is just as meaningful as a real 864372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // certificate, so this is the same as supply a 864472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // legitimate-but-unacceptable certificate. 864572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = trans->RestartWithCertificate(NULL, &callback); 864672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_IO_PENDING, rv); 864772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 864872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure the certificate was added to the client auth cache before 864972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // allowing the connection to continue restarting. 865072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<X509Certificate> client_cert; 865172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70", 865272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 865372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(NULL, client_cert.get()); 865472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure the certificate was NOT cached for the endpoint. This only 865572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // applies to HTTPS requests, but is fine to check for HTTP requests. 865672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 865772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 865872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 865972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Restart the handshake. This will consume ssl_data2, which fails, and 866072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // then consume ssl_data3, which should also fail. The result code is 866172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // checked against what ssl_data3 should return. 866272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = callback.WaitForResult(); 866372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv); 866472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 866572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Now that the new handshake has failed, ensure that the client 866672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // certificate was removed from the client auth cache. 866772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70", 866872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 866972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", 867072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &client_cert)); 867172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 867272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 867372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 8675