blob: 9284f760377f213ddefa0e75753a69576fa122f8 [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
9#include <string>
[email protected]95d88ffe2010-02-04 21:25:3310#include <vector>
[email protected]77848d12008-11-14 00:00:2211
[email protected]2d731a32010-04-29 01:04:0612#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3013#include "base/compiler_specific.h"
[email protected]95d88ffe2010-02-04 21:25:3314#include "base/file_path.h"
15#include "base/file_util.h"
[email protected]3b63f8f42011-03-28 01:54:1516#include "base/memory/scoped_ptr.h"
[email protected]5e6efa52011-06-27 17:26:4117#include "base/metrics/histogram.h"
[email protected]f36a8132011-09-02 18:36:3318#include "base/test/test_file_util.h"
[email protected]be1ce6a72010-08-03 14:35:2219#include "base/utf_string_conversions.h"
[email protected]277d5942010-08-11 21:02:3520#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1221#include "net/base/capturing_net_log.h"
[email protected]bacff652009-03-31 17:50:3322#include "net/base/completion_callback.h"
[email protected]98e1cd012011-11-08 15:33:0923#include "net/base/host_cache.h"
[email protected]b59ff372009-07-15 22:04:3224#include "net/base/mock_host_resolver.h"
[email protected]169d0012010-05-10 23:20:1225#include "net/base/net_log.h"
26#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3127#include "net/base/request_priority.h"
[email protected]bd0b6772011-01-11 19:59:3028#include "net/base/ssl_cert_request_info.h"
[email protected]db36938c2009-08-19 21:48:4229#include "net/base/ssl_config_service_defaults.h"
[email protected]bacff652009-03-31 17:50:3330#include "net/base/ssl_info.h"
initial.commit586acc5fe2008-07-26 22:42:5231#include "net/base/test_completion_callback.h"
32#include "net/base/upload_data.h"
[email protected]3c32c5f2010-05-18 15:18:1233#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0034#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2935#include "net/http/http_auth_handler_ntlm.h"
[email protected]0877e3d2009-10-17 22:29:5736#include "net/http/http_basic_stream.h"
[email protected]3deb9a52010-11-11 00:24:4037#include "net/http/http_net_log_params.h"
initial.commit586acc5fe2008-07-26 22:42:5238#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5639#include "net/http/http_network_session_peer.h"
[email protected]17291a022011-10-10 07:32:5340#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5741#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3842#include "net/http/http_stream_factory.h"
initial.commit586acc5fe2008-07-26 22:42:5243#include "net/http/http_transaction_unittest.h"
[email protected]51fff29d2008-12-19 22:17:5344#include "net/proxy/proxy_config_service_fixed.h"
[email protected]631f1322010-04-30 17:59:1145#include "net/proxy/proxy_resolver.h"
46#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4447#include "net/socket/client_socket_factory.h"
[email protected]a42dbd142011-11-17 16:42:0248#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]f7984fc62009-06-22 23:26:4449#include "net/socket/socket_test_util.h"
50#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5451#include "net/spdy/spdy_framer.h"
52#include "net/spdy/spdy_session.h"
53#include "net/spdy/spdy_session_pool.h"
54#include "net/spdy/spdy_test_util.h"
initial.commit586acc5fe2008-07-26 22:42:5255#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1556#include "testing/platform_test.h"
initial.commit586acc5fe2008-07-26 22:42:5257
58//-----------------------------------------------------------------------------
59
[email protected]13c8a092010-07-29 06:15:4460namespace {
61
62const string16 kBar(ASCIIToUTF16("bar"));
63const string16 kBar2(ASCIIToUTF16("bar2"));
64const string16 kBar3(ASCIIToUTF16("bar3"));
65const string16 kBaz(ASCIIToUTF16("baz"));
66const string16 kFirst(ASCIIToUTF16("first"));
67const string16 kFoo(ASCIIToUTF16("foo"));
68const string16 kFoo2(ASCIIToUTF16("foo2"));
69const string16 kFoo3(ASCIIToUTF16("foo3"));
70const string16 kFou(ASCIIToUTF16("fou"));
71const string16 kSecond(ASCIIToUTF16("second"));
72const string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
73const string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
74
[email protected]5285d972011-10-18 18:56:3475// MakeNextProtos is a utility function that returns a vector of std::strings
76// from its arguments. Don't forget to terminate the argument list with a NULL.
77std::vector<std::string> MakeNextProtos(const char* a, ...) {
78 std::vector<std::string> ret;
79 ret.push_back(a);
80
81 va_list args;
82 va_start(args, a);
83
84 for (;;) {
85 const char* value = va_arg(args, const char*);
86 if (value == NULL)
87 break;
88 ret.push_back(value);
89 }
90 va_end(args);
91
92 return ret;
93}
94
95// SpdyNextProtos returns a vector of NPN protocol strings for negotiating
96// SPDY.
97std::vector<std::string> SpdyNextProtos() {
[email protected]42baef7a2011-12-10 04:52:1098 return MakeNextProtos("http/1.1", "spdy/2", "spdy/2.1", NULL);
[email protected]5285d972011-10-18 18:56:3499}
100
[email protected]13c8a092010-07-29 06:15:44101} // namespace
102
[email protected]89ceba9a2009-03-21 03:46:06103namespace net {
104
[email protected]e44de5d2009-06-05 20:12:45105// Helper to manage the lifetimes of the dependencies for a
106// HttpNetworkTransaction.
[email protected]ac039522010-06-15 16:39:44107struct SessionDependencies {
[email protected]228ff742009-06-05 01:19:59108 // Default set of dependencies -- "null" proxy service.
[email protected]db36938c2009-08-19 21:48:42109 SessionDependencies()
110 : host_resolver(new MockHostResolver),
[email protected]822581d2010-12-16 17:27:15111 cert_verifier(new CertVerifier),
[email protected]ebeefff32010-09-15 05:10:02112 proxy_service(ProxyService::CreateDirect()),
[email protected]d1eda932009-11-04 01:03:10113 ssl_config_service(new SSLConfigServiceDefaults),
[email protected]f660e4b2010-09-29 14:20:08114 http_auth_handler_factory(
[email protected]73c45322010-10-01 23:57:54115 HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
[email protected]a7ea8832010-07-12 17:54:54116 net_log(NULL) {}
[email protected]228ff742009-06-05 01:19:59117
118 // Custom proxy service dependency.
[email protected]e44de5d2009-06-05 20:12:45119 explicit SessionDependencies(ProxyService* proxy_service)
[email protected]db36938c2009-08-19 21:48:42120 : host_resolver(new MockHostResolver),
[email protected]822581d2010-12-16 17:27:15121 cert_verifier(new CertVerifier),
[email protected]db36938c2009-08-19 21:48:42122 proxy_service(proxy_service),
[email protected]d1eda932009-11-04 01:03:10123 ssl_config_service(new SSLConfigServiceDefaults),
[email protected]f660e4b2010-09-29 14:20:08124 http_auth_handler_factory(
[email protected]73c45322010-10-01 23:57:54125 HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
[email protected]a7ea8832010-07-12 17:54:54126 net_log(NULL) {}
[email protected]228ff742009-06-05 01:19:59127
[email protected]73c45322010-10-01 23:57:54128 scoped_ptr<MockHostResolverBase> host_resolver;
[email protected]822581d2010-12-16 17:27:15129 scoped_ptr<CertVerifier> cert_verifier;
[email protected]6104ea5d2011-04-27 21:37:12130 scoped_ptr<ProxyService> proxy_service;
[email protected]db36938c2009-08-19 21:48:42131 scoped_refptr<SSLConfigService> ssl_config_service;
[email protected]228ff742009-06-05 01:19:59132 MockClientSocketFactory socket_factory;
[email protected]fa55e192010-02-15 14:25:50133 scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
[email protected]17291a022011-10-10 07:32:53134 HttpServerPropertiesImpl http_server_properties;
[email protected]a7ea8832010-07-12 17:54:54135 NetLog* net_log;
[email protected]228ff742009-06-05 01:19:59136};
137
[email protected]228ff742009-06-05 01:19:59138HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
[email protected]9e1bdd32011-02-03 21:48:34139 net::HttpNetworkSession::Params params;
140 params.client_socket_factory = &session_deps->socket_factory;
141 params.host_resolver = session_deps->host_resolver.get();
142 params.cert_verifier = session_deps->cert_verifier.get();
[email protected]6104ea5d2011-04-27 21:37:12143 params.proxy_service = session_deps->proxy_service.get();
[email protected]9e1bdd32011-02-03 21:48:34144 params.ssl_config_service = session_deps->ssl_config_service;
145 params.http_auth_handler_factory =
146 session_deps->http_auth_handler_factory.get();
[email protected]17291a022011-10-10 07:32:53147 params.http_server_properties = &session_deps->http_server_properties;
[email protected]9e1bdd32011-02-03 21:48:34148 params.net_log = session_deps->net_log;
149 return new HttpNetworkSession(params);
[email protected]e8d536192008-10-17 22:21:14150}
151
[email protected]89836e22008-09-25 20:33:42152class HttpNetworkTransactionTest : public PlatformTest {
[email protected]e3ceb682011-06-28 23:55:46153 protected:
154 struct SimpleGetHelperResult {
155 int rv;
156 std::string status_line;
157 std::string response_data;
158 };
159
[email protected]2ff8b312010-04-26 22:20:54160 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50161 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
162 MessageLoop::current()->RunAllPending();
[email protected]2ff8b312010-04-26 22:20:54163 spdy::SpdyFramer::set_enable_compression_default(false);
164 }
165
[email protected]0e75a732008-10-16 20:36:09166 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50167 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
168 MessageLoop::current()->RunAllPending();
[email protected]2ff8b312010-04-26 22:20:54169 spdy::SpdyFramer::set_enable_compression_default(true);
[email protected]0e75a732008-10-16 20:36:09170 // Empty the current queue.
171 MessageLoop::current()->RunAllPending();
172 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50173 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
174 MessageLoop::current()->RunAllPending();
[email protected]0e75a732008-10-16 20:36:09175 }
176
[email protected]202965992011-12-07 23:04:51177 // Either |write_failure| specifies a write failure or |read_failure|
178 // specifies a read failure when using a reused socket. In either case, the
179 // failure should cause the network transaction to resend the request, and the
180 // other argument should be NULL.
181 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
182 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52183
[email protected]5a60c8b2011-10-19 20:14:29184 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
185 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15186 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52187
[email protected]ff007e162009-05-23 09:13:15188 HttpRequestInfo request;
189 request.method = "GET";
190 request.url = GURL("http://www.google.com/");
191 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52192
[email protected]cb9bf6ca2011-01-28 13:15:27193 SessionDependencies session_deps;
194 scoped_ptr<HttpTransaction> trans(
195 new HttpNetworkTransaction(CreateSession(&session_deps)));
196
[email protected]5a60c8b2011-10-19 20:14:29197 for (size_t i = 0; i < data_count; ++i) {
198 session_deps.socket_factory.AddSocketDataProvider(data[i]);
199 }
initial.commit586acc5fe2008-07-26 22:42:52200
[email protected]f1f3f0f82011-10-01 20:38:10201 TestOldCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52202
[email protected]169d0012010-05-10 23:20:12203 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]3deb9a52010-11-11 00:24:40204 EXPECT_TRUE(log.bound().IsLoggingAllEvents());
[email protected]169d0012010-05-10 23:20:12205 int rv = trans->Start(&request, &callback, log.bound());
[email protected]ff007e162009-05-23 09:13:15206 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52207
[email protected]ff007e162009-05-23 09:13:15208 out.rv = callback.WaitForResult();
209 if (out.rv != OK)
210 return out;
211
212 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50213 // Can't use ASSERT_* inside helper functions like this, so
214 // return an error.
215 if (response == NULL || response->headers == NULL) {
216 out.rv = ERR_UNEXPECTED;
217 return out;
218 }
[email protected]ff007e162009-05-23 09:13:15219 out.status_line = response->headers->GetStatusLine();
220
[email protected]6d81b482011-02-22 19:47:19221 EXPECT_EQ("192.0.2.33", response->socket_address.host());
222 EXPECT_EQ(0, response->socket_address.port());
223
[email protected]ff007e162009-05-23 09:13:15224 rv = ReadTransaction(trans.get(), &out.response_data);
225 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40226
227 net::CapturingNetLog::EntryList entries;
228 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39229 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40230 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12231 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39232 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40233 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39234 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
235 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15236
[email protected]b2fcd0e2010-12-01 15:19:40237 CapturingNetLog::Entry entry = entries[pos];
[email protected]3deb9a52010-11-11 00:24:40238 NetLogHttpRequestParameter* request_params =
239 static_cast<NetLogHttpRequestParameter*>(entry.extra_parameters.get());
240 EXPECT_EQ("GET / HTTP/1.1\r\n", request_params->GetLine());
241 EXPECT_EQ("Host: www.google.com\r\n"
242 "Connection: keep-alive\r\n\r\n",
243 request_params->GetHeaders().ToString());
244
[email protected]aecfbf22008-10-16 02:02:47245 return out;
[email protected]ff007e162009-05-23 09:13:15246 }
initial.commit586acc5fe2008-07-26 22:42:52247
[email protected]5a60c8b2011-10-19 20:14:29248 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
249 size_t reads_count) {
250 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
251 StaticSocketDataProvider* data[] = { &reads };
252 return SimpleGetHelperForData(data, 1);
253 }
254
[email protected]ff007e162009-05-23 09:13:15255 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
256 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52257
[email protected]ff007e162009-05-23 09:13:15258 void ConnectStatusHelper(const MockRead& status);
[email protected]ff007e162009-05-23 09:13:15259};
[email protected]231d5a32008-09-13 00:45:27260
[email protected]15a5ccf82008-10-23 19:57:43261// Fill |str| with a long header list that consumes >= |size| bytes.
262void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19263 const char* row =
264 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
265 const int sizeof_row = strlen(row);
266 const int num_rows = static_cast<int>(
267 ceil(static_cast<float>(size) / sizeof_row));
268 const int sizeof_data = num_rows * sizeof_row;
269 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43270 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51271
[email protected]4ddaf2502008-10-23 18:26:19272 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43273 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19274}
275
[email protected]385a4672009-03-11 22:21:29276// Alternative functions that eliminate randomness and dependency on the local
277// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20278void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29279 static const uint8 bytes[] = {
280 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
281 };
282 static size_t current_byte = 0;
283 for (size_t i = 0; i < n; ++i) {
284 output[i] = bytes[current_byte++];
285 current_byte %= arraysize(bytes);
286 }
287}
288
[email protected]fe2bc6a2009-03-23 16:52:20289void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29290 static const uint8 bytes[] = {
291 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
292 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
293 };
294 static size_t current_byte = 0;
295 for (size_t i = 0; i < n; ++i) {
296 output[i] = bytes[current_byte++];
297 current_byte %= arraysize(bytes);
298 }
299}
300
[email protected]fe2bc6a2009-03-23 16:52:20301std::string MockGetHostName() {
302 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29303}
304
[email protected]e60e47a2010-07-14 03:37:18305template<typename ParentPool>
306class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31307 public:
[email protected]9e1bdd32011-02-03 21:48:34308 CaptureGroupNameSocketPool(HostResolver* host_resolver,
309 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18310
[email protected]d80a4322009-08-14 07:07:49311 const std::string last_group_name_received() const {
312 return last_group_name_;
313 }
314
[email protected]684970b2009-08-14 04:54:46315 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49316 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31317 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31318 ClientSocketHandle* handle,
[email protected]f1f3f0f82011-10-01 20:38:10319 OldCompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53320 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31321 last_group_name_ = group_name;
322 return ERR_IO_PENDING;
323 }
[email protected]04e5be32009-06-26 20:00:31324 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21325 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31326 virtual void ReleaseSocket(const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10327 StreamSocket* socket,
[email protected]9f95c692011-02-11 19:20:19328 int id) {}
[email protected]04e5be32009-06-26 20:00:31329 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31330 virtual int IdleSocketCount() const {
331 return 0;
332 }
333 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
334 return 0;
335 }
336 virtual LoadState GetLoadState(const std::string& group_name,
337 const ClientSocketHandle* handle) const {
338 return LOAD_STATE_IDLE;
339 }
[email protected]a796bcec2010-03-22 17:17:26340 virtual base::TimeDelta ConnectionTimeout() const {
341 return base::TimeDelta();
342 }
[email protected]d80a4322009-08-14 07:07:49343
344 private:
[email protected]04e5be32009-06-26 20:00:31345 std::string last_group_name_;
346};
347
[email protected]ab739042011-04-07 15:22:28348typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
349CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13350typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
351CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06352typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11353CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18354typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
355CaptureGroupNameSSLSocketPool;
356
357template<typename ParentPool>
358CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34359 HostResolver* host_resolver,
360 CertVerifier* /* cert_verifier */)
361 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18362
363template<>
[email protected]2df19bb2010-08-25 20:13:46364CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34365 HostResolver* host_resolver,
366 CertVerifier* /* cert_verifier */)
367 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46368
369template<>
[email protected]e60e47a2010-07-14 03:37:18370CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34371 HostResolver* host_resolver,
372 CertVerifier* cert_verifier)
[email protected]3ed7496f2011-12-15 18:27:40373 : SSLClientSocketPool(0, 0, NULL, host_resolver, cert_verifier, NULL,
[email protected]c3456bb2011-12-12 22:22:19374 NULL, NULL, "", NULL, NULL, NULL, NULL, NULL, NULL) {}
[email protected]2227c692010-05-04 15:36:11375
[email protected]231d5a32008-09-13 00:45:27376//-----------------------------------------------------------------------------
377
[email protected]dae22c52010-07-30 02:16:35378// This is the expected return from a current server advertising SPDY.
379static const char kAlternateProtocolHttpHeader[] =
380 "Alternate-Protocol: 443:npn-spdy/2\r\n\r\n";
381
[email protected]79cb5c12011-09-12 13:12:04382// Helper functions for validating that AuthChallengeInfo's are correctly
383// configured for common cases.
384bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
385 if (!auth_challenge)
386 return false;
387 EXPECT_FALSE(auth_challenge->is_proxy);
388 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
389 EXPECT_EQ("MyRealm1", auth_challenge->realm);
390 EXPECT_EQ("basic", auth_challenge->scheme);
391 return true;
392}
393
394bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
395 if (!auth_challenge)
396 return false;
397 EXPECT_TRUE(auth_challenge->is_proxy);
398 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
399 EXPECT_EQ("MyRealm1", auth_challenge->realm);
400 EXPECT_EQ("basic", auth_challenge->scheme);
401 return true;
402}
403
404bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
405 if (!auth_challenge)
406 return false;
407 EXPECT_FALSE(auth_challenge->is_proxy);
408 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
409 EXPECT_EQ("digestive", auth_challenge->realm);
410 EXPECT_EQ("digest", auth_challenge->scheme);
411 return true;
412}
413
414bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
415 if (!auth_challenge)
416 return false;
417 EXPECT_FALSE(auth_challenge->is_proxy);
418 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
419 EXPECT_EQ(std::string(), auth_challenge->realm);
420 EXPECT_EQ("ntlm", auth_challenge->scheme);
421 return true;
422}
423
[email protected]231d5a32008-09-13 00:45:27424TEST_F(HttpNetworkTransactionTest, Basic) {
[email protected]228ff742009-06-05 01:19:59425 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40426 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:43427 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]231d5a32008-09-13 00:45:27428}
429
430TEST_F(HttpNetworkTransactionTest, SimpleGET) {
431 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35432 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
433 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42434 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27435 };
[email protected]31a2bfe2010-02-09 08:03:39436 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
437 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42438 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27439 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
440 EXPECT_EQ("hello world", out.response_data);
441}
442
443// Response with no status line.
444TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
445 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35446 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42447 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27448 };
[email protected]31a2bfe2010-02-09 08:03:39449 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
450 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42451 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27452 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
453 EXPECT_EQ("hello world", out.response_data);
454}
455
456// Allow up to 4 bytes of junk to precede status line.
457TEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) {
458 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35459 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]1c773ea12009-04-28 19:58:42460 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27461 };
[email protected]31a2bfe2010-02-09 08:03:39462 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
463 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42464 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27465 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
466 EXPECT_EQ("DATA", out.response_data);
467}
468
469// Allow up to 4 bytes of junk to precede status line.
470TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
471 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35472 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]1c773ea12009-04-28 19:58:42473 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27474 };
[email protected]31a2bfe2010-02-09 08:03:39475 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
476 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42477 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27478 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
479 EXPECT_EQ("DATA", out.response_data);
480}
481
482// Beyond 4 bytes of slop and it should fail to find a status line.
483TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
484 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35485 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]1c773ea12009-04-28 19:58:42486 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27487 };
[email protected]31a2bfe2010-02-09 08:03:39488 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
489 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42490 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25491 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
492 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27493}
494
495// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
496TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
497 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35498 MockRead("\n"),
499 MockRead("\n"),
500 MockRead("Q"),
501 MockRead("J"),
502 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]1c773ea12009-04-28 19:58:42503 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27504 };
[email protected]31a2bfe2010-02-09 08:03:39505 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
506 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42507 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27508 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
509 EXPECT_EQ("DATA", out.response_data);
510}
511
512// Close the connection before enough bytes to have a status line.
513TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
514 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35515 MockRead("HTT"),
[email protected]1c773ea12009-04-28 19:58:42516 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27517 };
[email protected]31a2bfe2010-02-09 08:03:39518 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
519 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42520 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27521 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
522 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52523}
524
[email protected]f9d44aa2008-09-23 23:57:17525// Simulate a 204 response, lacking a Content-Length header, sent over a
526// persistent connection. The response should still terminate since a 204
527// cannot have a response body.
528TEST_F(HttpNetworkTransactionTest, StopsReading204) {
529 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35530 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
531 MockRead("junk"), // Should not be read!!
[email protected]1c773ea12009-04-28 19:58:42532 MockRead(false, OK),
[email protected]f9d44aa2008-09-23 23:57:17533 };
[email protected]31a2bfe2010-02-09 08:03:39534 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
535 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42536 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17537 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
538 EXPECT_EQ("", out.response_data);
539}
540
[email protected]0877e3d2009-10-17 22:29:57541// A simple request using chunked encoding with some extra data after.
542// (Like might be seen in a pipelined response.)
543TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
544 MockRead data_reads[] = {
545 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
546 MockRead("5\r\nHello\r\n"),
547 MockRead("1\r\n"),
548 MockRead(" \r\n"),
549 MockRead("5\r\nworld\r\n"),
550 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
551 MockRead(false, OK),
552 };
[email protected]31a2bfe2010-02-09 08:03:39553 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
554 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57555 EXPECT_EQ(OK, out.rv);
556 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
557 EXPECT_EQ("Hello world", out.response_data);
558}
559
[email protected]9fe44f52010-09-23 18:36:00560// Next tests deal with http://crbug.com/56344.
561
562TEST_F(HttpNetworkTransactionTest,
563 MultipleContentLengthHeadersNoTransferEncoding) {
564 MockRead data_reads[] = {
565 MockRead("HTTP/1.1 200 OK\r\n"),
566 MockRead("Content-Length: 10\r\n"),
567 MockRead("Content-Length: 5\r\n\r\n"),
568 };
569 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
570 arraysize(data_reads));
571 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
572}
573
574TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04575 DuplicateContentLengthHeadersNoTransferEncoding) {
576 MockRead data_reads[] = {
577 MockRead("HTTP/1.1 200 OK\r\n"),
578 MockRead("Content-Length: 5\r\n"),
579 MockRead("Content-Length: 5\r\n\r\n"),
580 MockRead("Hello"),
581 };
582 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
583 arraysize(data_reads));
584 EXPECT_EQ(OK, out.rv);
585 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
586 EXPECT_EQ("Hello", out.response_data);
587}
588
589TEST_F(HttpNetworkTransactionTest,
590 ComplexContentLengthHeadersNoTransferEncoding) {
591 // More than 2 dupes.
592 {
593 MockRead data_reads[] = {
594 MockRead("HTTP/1.1 200 OK\r\n"),
595 MockRead("Content-Length: 5\r\n"),
596 MockRead("Content-Length: 5\r\n"),
597 MockRead("Content-Length: 5\r\n\r\n"),
598 MockRead("Hello"),
599 };
600 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
601 arraysize(data_reads));
602 EXPECT_EQ(OK, out.rv);
603 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
604 EXPECT_EQ("Hello", out.response_data);
605 }
606 // HTTP/1.0
607 {
608 MockRead data_reads[] = {
609 MockRead("HTTP/1.0 200 OK\r\n"),
610 MockRead("Content-Length: 5\r\n"),
611 MockRead("Content-Length: 5\r\n"),
612 MockRead("Content-Length: 5\r\n\r\n"),
613 MockRead("Hello"),
614 };
615 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
616 arraysize(data_reads));
617 EXPECT_EQ(OK, out.rv);
618 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
619 EXPECT_EQ("Hello", out.response_data);
620 }
621 // 2 dupes and one mismatched.
622 {
623 MockRead data_reads[] = {
624 MockRead("HTTP/1.1 200 OK\r\n"),
625 MockRead("Content-Length: 10\r\n"),
626 MockRead("Content-Length: 10\r\n"),
627 MockRead("Content-Length: 5\r\n\r\n"),
628 };
629 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
630 arraysize(data_reads));
631 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
632 }
633}
634
635TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00636 MultipleContentLengthHeadersTransferEncoding) {
637 MockRead data_reads[] = {
638 MockRead("HTTP/1.1 200 OK\r\n"),
639 MockRead("Content-Length: 666\r\n"),
640 MockRead("Content-Length: 1337\r\n"),
641 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
642 MockRead("5\r\nHello\r\n"),
643 MockRead("1\r\n"),
644 MockRead(" \r\n"),
645 MockRead("5\r\nworld\r\n"),
646 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
647 MockRead(false, OK),
648 };
649 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
650 arraysize(data_reads));
651 EXPECT_EQ(OK, out.rv);
652 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
653 EXPECT_EQ("Hello world", out.response_data);
654}
655
[email protected]1628fe92011-10-04 23:04:55656// Next tests deal with http://crbug.com/98895.
657
658// Checks that a single Content-Disposition header results in no error.
659TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
660 MockRead data_reads[] = {
661 MockRead("HTTP/1.1 200 OK\r\n"),
662 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
663 MockRead("Content-Length: 5\r\n\r\n"),
664 MockRead("Hello"),
665 };
666 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
667 arraysize(data_reads));
668 EXPECT_EQ(OK, out.rv);
669 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
670 EXPECT_EQ("Hello", out.response_data);
671}
672
673// Checks that two identical Content-Disposition headers result in an error.
674TEST_F(HttpNetworkTransactionTest,
675 DuplicateIdenticalContentDispositionHeaders) {
676 MockRead data_reads[] = {
677 MockRead("HTTP/1.1 200 OK\r\n"),
678 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
679 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
680 MockRead("Content-Length: 5\r\n\r\n"),
681 MockRead("Hello"),
682 };
683 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
684 arraysize(data_reads));
685 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
686}
687
688// Checks that two distinct Content-Disposition headers result in an error.
689TEST_F(HttpNetworkTransactionTest, DuplicateDistinctContentDispositionHeaders) {
690 MockRead data_reads[] = {
691 MockRead("HTTP/1.1 200 OK\r\n"),
692 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
693 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
694 MockRead("Content-Length: 5\r\n\r\n"),
695 MockRead("Hello"),
696 };
697 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
698 arraysize(data_reads));
699 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
700}
701
702// Checks the behavior of a single Location header.
703TEST_F(HttpNetworkTransactionTest, SingleLocationHeader) {
704 MockRead data_reads[] = {
705 MockRead("HTTP/1.1 302 Redirect\r\n"),
706 MockRead("Location: http://good.com/\r\n"),
707 MockRead("Content-Length: 0\r\n\r\n"),
708 MockRead(false, OK),
709 };
710
711 HttpRequestInfo request;
712 request.method = "GET";
713 request.url = GURL("http://redirect.com/");
714 request.load_flags = 0;
715
716 SessionDependencies session_deps;
717 scoped_ptr<HttpTransaction> trans(
718 new HttpNetworkTransaction(CreateSession(&session_deps)));
719
720 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
721 session_deps.socket_factory.AddSocketDataProvider(&data);
722
723 TestOldCompletionCallback callback;
724
725 int rv = trans->Start(&request, &callback, BoundNetLog());
726 EXPECT_EQ(ERR_IO_PENDING, rv);
727
728 EXPECT_EQ(OK, callback.WaitForResult());
729
730 const HttpResponseInfo* response = trans->GetResponseInfo();
731 ASSERT_TRUE(response != NULL && response->headers != NULL);
732 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
733 std::string url;
734 EXPECT_TRUE(response->headers->IsRedirect(&url));
735 EXPECT_EQ("http://good.com/", url);
736}
737
738// Checks that two identical Location headers result in an error.
739TEST_F(HttpNetworkTransactionTest, DuplicateIdenticalLocationHeaders) {
740 MockRead data_reads[] = {
741 MockRead("HTTP/1.1 302 Redirect\r\n"),
742 MockRead("Location: http://good.com/\r\n"),
743 MockRead("Location: http://good.com/\r\n"),
744 MockRead("Content-Length: 0\r\n\r\n"),
745 MockRead(false, OK),
746 };
747 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
748 arraysize(data_reads));
749 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
750}
751
752// Checks that two distinct Location headers result in an error.
753TEST_F(HttpNetworkTransactionTest, DuplicateDistinctLocationHeaders) {
754 MockRead data_reads[] = {
755 MockRead("HTTP/1.1 302 Redirect\r\n"),
756 MockRead("Location: http://good.com/\r\n"),
757 MockRead("Location: http://evil.com/\r\n"),
758 MockRead("Content-Length: 0\r\n\r\n"),
759 MockRead(false, OK),
760 };
761 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
762 arraysize(data_reads));
763 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
764}
765
[email protected]ef0faf2e72009-03-05 23:27:23766// Do a request using the HEAD method. Verify that we don't try to read the
767// message body (since HEAD has none).
768TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42769 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23770 request.method = "HEAD";
771 request.url = GURL("http://www.google.com/");
772 request.load_flags = 0;
773
[email protected]cb9bf6ca2011-01-28 13:15:27774 SessionDependencies session_deps;
775 scoped_ptr<HttpTransaction> trans(
776 new HttpNetworkTransaction(CreateSession(&session_deps)));
777
[email protected]ef0faf2e72009-03-05 23:27:23778 MockWrite data_writes1[] = {
779 MockWrite("HEAD / HTTP/1.1\r\n"
780 "Host: www.google.com\r\n"
781 "Connection: keep-alive\r\n"
782 "Content-Length: 0\r\n\r\n"),
783 };
784 MockRead data_reads1[] = {
785 MockRead("HTTP/1.1 404 Not Found\r\n"),
786 MockRead("Server: Blah\r\n"),
787 MockRead("Content-Length: 1234\r\n\r\n"),
788
789 // No response body because the test stops reading here.
[email protected]1c773ea12009-04-28 19:58:42790 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23791 };
792
[email protected]31a2bfe2010-02-09 08:03:39793 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
794 data_writes1, arraysize(data_writes1));
[email protected]5ecc992a42009-11-11 01:41:59795 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23796
[email protected]f1f3f0f82011-10-01 20:38:10797 TestOldCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23798
[email protected]5a1d7ca2010-04-28 20:12:27799 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42800 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23801
802 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42803 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23804
[email protected]1c773ea12009-04-28 19:58:42805 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50806 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23807
808 // Check that the headers got parsed.
809 EXPECT_TRUE(response->headers != NULL);
810 EXPECT_EQ(1234, response->headers->GetContentLength());
811 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
812
813 std::string server_header;
814 void* iter = NULL;
815 bool has_server_header = response->headers->EnumerateHeader(
816 &iter, "Server", &server_header);
817 EXPECT_TRUE(has_server_header);
818 EXPECT_EQ("Blah", server_header);
819
820 // Reading should give EOF right away, since there is no message body
821 // (despite non-zero content-length).
822 std::string response_data;
823 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42824 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23825 EXPECT_EQ("", response_data);
826}
827
initial.commit586acc5fe2008-07-26 22:42:52828TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]228ff742009-06-05 01:19:59829 SessionDependencies session_deps;
[email protected]ad8e04a2010-11-01 04:16:27830 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
initial.commit586acc5fe2008-07-26 22:42:52831
832 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35833 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
834 MockRead("hello"),
835 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
836 MockRead("world"),
[email protected]1c773ea12009-04-28 19:58:42837 MockRead(false, OK),
initial.commit586acc5fe2008-07-26 22:42:52838 };
[email protected]31a2bfe2010-02-09 08:03:39839 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:59840 session_deps.socket_factory.AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52841
[email protected]0b0bf032010-09-21 18:08:50842 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:52843 "hello", "world"
844 };
845
846 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42847 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52848 request.method = "GET";
849 request.url = GURL("http://www.google.com/");
850 request.load_flags = 0;
851
[email protected]cb9bf6ca2011-01-28 13:15:27852 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
853
[email protected]f1f3f0f82011-10-01 20:38:10854 TestOldCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52855
[email protected]5a1d7ca2010-04-28 20:12:27856 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42857 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52858
859 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42860 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52861
[email protected]1c773ea12009-04-28 19:58:42862 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50863 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:52864
865 EXPECT_TRUE(response->headers != NULL);
[email protected]3d2a59b2008-09-26 19:44:25866 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:52867
868 std::string response_data;
[email protected]af4876d2008-10-21 23:10:57869 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42870 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:25871 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:52872 }
873}
874
875TEST_F(HttpNetworkTransactionTest, Ignores100) {
[email protected]1c773ea12009-04-28 19:58:42876 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52877 request.method = "POST";
878 request.url = GURL("http://www.foo.com/");
[email protected]1c773ea12009-04-28 19:58:42879 request.upload_data = new UploadData;
initial.commit586acc5fe2008-07-26 22:42:52880 request.upload_data->AppendBytes("foo", 3);
881 request.load_flags = 0;
882
[email protected]cb9bf6ca2011-01-28 13:15:27883 SessionDependencies session_deps;
884 scoped_ptr<HttpTransaction> trans(
885 new HttpNetworkTransaction(CreateSession(&session_deps)));
886
initial.commit586acc5fe2008-07-26 22:42:52887 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35888 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
889 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
890 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42891 MockRead(false, OK),
initial.commit586acc5fe2008-07-26 22:42:52892 };
[email protected]31a2bfe2010-02-09 08:03:39893 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:59894 session_deps.socket_factory.AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52895
[email protected]f1f3f0f82011-10-01 20:38:10896 TestOldCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52897
[email protected]5a1d7ca2010-04-28 20:12:27898 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42899 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52900
901 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42902 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52903
[email protected]1c773ea12009-04-28 19:58:42904 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50905 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:52906
907 EXPECT_TRUE(response->headers != NULL);
[email protected]3d2a59b2008-09-26 19:44:25908 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:52909
910 std::string response_data;
[email protected]af4876d2008-10-21 23:10:57911 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42912 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:25913 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:52914}
915
[email protected]3a2d3662009-03-27 03:49:14916// This test is almost the same as Ignores100 above, but the response contains
917// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:57918// HTTP/1.1 and the two status headers are read in one read.
[email protected]3a2d3662009-03-27 03:49:14919TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:42920 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:14921 request.method = "GET";
922 request.url = GURL("http://www.foo.com/");
923 request.load_flags = 0;
924
[email protected]cb9bf6ca2011-01-28 13:15:27925 SessionDependencies session_deps;
926 scoped_ptr<HttpTransaction> trans(
927 new HttpNetworkTransaction(CreateSession(&session_deps)));
928
[email protected]3a2d3662009-03-27 03:49:14929 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:57930 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
931 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:14932 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42933 MockRead(false, OK),
[email protected]3a2d3662009-03-27 03:49:14934 };
[email protected]31a2bfe2010-02-09 08:03:39935 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:59936 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:14937
[email protected]f1f3f0f82011-10-01 20:38:10938 TestOldCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:14939
[email protected]5a1d7ca2010-04-28 20:12:27940 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42941 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:14942
943 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42944 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:14945
[email protected]1c773ea12009-04-28 19:58:42946 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50947 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:14948
949 EXPECT_TRUE(response->headers != NULL);
950 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
951
952 std::string response_data;
953 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42954 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:14955 EXPECT_EQ("hello world", response_data);
956}
957
[email protected]ee9410e72010-01-07 01:42:38958TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:38959 HttpRequestInfo request;
960 request.method = "POST";
961 request.url = GURL("http://www.foo.com/");
962 request.load_flags = 0;
963
[email protected]cb9bf6ca2011-01-28 13:15:27964 SessionDependencies session_deps;
965 scoped_ptr<HttpTransaction> trans(
966 new HttpNetworkTransaction(CreateSession(&session_deps)));
967
[email protected]ee9410e72010-01-07 01:42:38968 MockRead data_reads[] = {
969 MockRead(false, "HTTP/1.0 100 Continue\r\n"),
970 MockRead(true, 0),
971 };
[email protected]31a2bfe2010-02-09 08:03:39972 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]ee9410e72010-01-07 01:42:38973 session_deps.socket_factory.AddSocketDataProvider(&data);
974
[email protected]f1f3f0f82011-10-01 20:38:10975 TestOldCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:38976
[email protected]5a1d7ca2010-04-28 20:12:27977 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:38978 EXPECT_EQ(ERR_IO_PENDING, rv);
979
980 rv = callback.WaitForResult();
981 EXPECT_EQ(OK, rv);
982
983 std::string response_data;
984 rv = ReadTransaction(trans.get(), &response_data);
985 EXPECT_EQ(OK, rv);
986 EXPECT_EQ("", response_data);
987}
988
989TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:38990 HttpRequestInfo request;
991 request.method = "POST";
992 request.url = GURL("http://www.foo.com/");
993 request.load_flags = 0;
994
[email protected]cb9bf6ca2011-01-28 13:15:27995 SessionDependencies session_deps;
996 scoped_ptr<HttpTransaction> trans(
997 new HttpNetworkTransaction(CreateSession(&session_deps)));
998
[email protected]ee9410e72010-01-07 01:42:38999 MockRead data_reads[] = {
1000 MockRead(true, 0),
1001 };
[email protected]31a2bfe2010-02-09 08:03:391002 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]ee9410e72010-01-07 01:42:381003 session_deps.socket_factory.AddSocketDataProvider(&data);
1004
[email protected]f1f3f0f82011-10-01 20:38:101005 TestOldCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381006
[email protected]5a1d7ca2010-04-28 20:12:271007 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381008 EXPECT_EQ(ERR_IO_PENDING, rv);
1009
1010 rv = callback.WaitForResult();
1011 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1012}
1013
[email protected]3d2a59b2008-09-26 19:44:251014void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511015 const MockWrite* write_failure,
1016 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421017 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521018 request.method = "GET";
1019 request.url = GURL("http://www.foo.com/");
1020 request.load_flags = 0;
1021
[email protected]cb9bf6ca2011-01-28 13:15:271022 SessionDependencies session_deps;
1023 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
1024
[email protected]202965992011-12-07 23:04:511025 // Written data for successfully sending both requests.
1026 MockWrite data1_writes[] = {
1027 MockWrite("GET / HTTP/1.1\r\n"
1028 "Host: www.foo.com\r\n"
1029 "Connection: keep-alive\r\n\r\n"),
1030 MockWrite("GET / HTTP/1.1\r\n"
1031 "Host: www.foo.com\r\n"
1032 "Connection: keep-alive\r\n\r\n")
1033 };
1034
1035 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521036 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351037 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1038 MockRead("hello"),
[email protected]202965992011-12-07 23:04:511039 MockRead(true, OK),
initial.commit586acc5fe2008-07-26 22:42:521040 };
[email protected]202965992011-12-07 23:04:511041
1042 if (write_failure) {
1043 ASSERT_TRUE(!read_failure);
1044 data1_writes[1] = *write_failure;
1045 } else {
1046 ASSERT_TRUE(read_failure);
1047 data1_reads[2] = *read_failure;
1048 }
1049
1050 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1051 data1_writes, arraysize(data1_writes));
[email protected]5ecc992a42009-11-11 01:41:591052 session_deps.socket_factory.AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521053
1054 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351055 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1056 MockRead("world"),
[email protected]1c773ea12009-04-28 19:58:421057 MockRead(true, OK),
initial.commit586acc5fe2008-07-26 22:42:521058 };
[email protected]31a2bfe2010-02-09 08:03:391059 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:591060 session_deps.socket_factory.AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521061
1062 const char* kExpectedResponseData[] = {
1063 "hello", "world"
1064 };
1065
1066 for (int i = 0; i < 2; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101067 TestOldCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521068
[email protected]5695b8c2009-09-30 21:36:431069 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
initial.commit586acc5fe2008-07-26 22:42:521070
[email protected]5a1d7ca2010-04-28 20:12:271071 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421072 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521073
1074 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421075 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521076
[email protected]1c773ea12009-04-28 19:58:421077 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501078 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521079
1080 EXPECT_TRUE(response->headers != NULL);
[email protected]3d2a59b2008-09-26 19:44:251081 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521082
1083 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571084 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421085 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251086 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521087 }
1088}
[email protected]3d2a59b2008-09-26 19:44:251089
[email protected]202965992011-12-07 23:04:511090TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
1091 MockWrite write_failure(true, ERR_SOCKET_NOT_CONNECTED);
1092 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1093}
1094
[email protected]3d2a59b2008-09-26 19:44:251095TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421096 MockRead read_failure(true, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511097 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251098}
1099
1100TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]1c773ea12009-04-28 19:58:421101 MockRead read_failure(false, OK); // EOF
[email protected]202965992011-12-07 23:04:511102 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251103}
1104
1105TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421106 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251107 request.method = "GET";
1108 request.url = GURL("http://www.google.com/");
1109 request.load_flags = 0;
1110
[email protected]cb9bf6ca2011-01-28 13:15:271111 SessionDependencies session_deps;
1112 scoped_ptr<HttpTransaction> trans(
1113 new HttpNetworkTransaction(CreateSession(&session_deps)));
1114
[email protected]3d2a59b2008-09-26 19:44:251115 MockRead data_reads[] = {
[email protected]1c773ea12009-04-28 19:58:421116 MockRead(true, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351117 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1118 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:421119 MockRead(false, OK),
[email protected]3d2a59b2008-09-26 19:44:251120 };
[email protected]31a2bfe2010-02-09 08:03:391121 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:591122 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251123
[email protected]f1f3f0f82011-10-01 20:38:101124 TestOldCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251125
[email protected]5a1d7ca2010-04-28 20:12:271126 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421127 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251128
1129 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421130 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251131
[email protected]1c773ea12009-04-28 19:58:421132 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251133 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251134}
1135
1136// What do various browsers do when the server closes a non-keepalive
1137// connection without sending any response header or body?
1138//
1139// IE7: error page
1140// Safari 3.1.2 (Windows): error page
1141// Firefox 3.0.1: blank page
1142// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421143// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1144// Us: error page (EMPTY_RESPONSE)
[email protected]3d2a59b2008-09-26 19:44:251145TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
1146 MockRead data_reads[] = {
[email protected]1c773ea12009-04-28 19:58:421147 MockRead(false, OK), // EOF
[email protected]217e6022008-09-29 18:18:351148 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1149 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:421150 MockRead(false, OK),
[email protected]3d2a59b2008-09-26 19:44:251151 };
[email protected]31a2bfe2010-02-09 08:03:391152 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1153 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421154 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251155}
[email protected]038e9a32008-10-08 22:40:161156
[email protected]0b0bf032010-09-21 18:08:501157// Test that we correctly reuse a keep-alive connection after not explicitly
1158// reading the body.
1159TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131160 HttpRequestInfo request;
1161 request.method = "GET";
1162 request.url = GURL("http://www.foo.com/");
1163 request.load_flags = 0;
1164
[email protected]cb9bf6ca2011-01-28 13:15:271165 SessionDependencies session_deps;
1166 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
1167
[email protected]0b0bf032010-09-21 18:08:501168 // Note that because all these reads happen in the same
1169 // StaticSocketDataProvider, it shows that the same socket is being reused for
1170 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131171 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501172 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1173 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131174 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501175 MockRead("HTTP/1.1 302 Found\r\n"
1176 "Content-Length: 0\r\n\r\n"),
1177 MockRead("HTTP/1.1 302 Found\r\n"
1178 "Content-Length: 5\r\n\r\n"
1179 "hello"),
1180 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1181 "Content-Length: 0\r\n\r\n"),
1182 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1183 "Content-Length: 5\r\n\r\n"
1184 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131185 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1186 MockRead("hello"),
1187 };
1188 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1189 session_deps.socket_factory.AddSocketDataProvider(&data1);
1190
1191 MockRead data2_reads[] = {
1192 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
1193 };
1194 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1195 session_deps.socket_factory.AddSocketDataProvider(&data2);
1196
[email protected]0b0bf032010-09-21 18:08:501197 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1198 std::string response_lines[kNumUnreadBodies];
1199
1200 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101201 TestOldCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131202
1203 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
1204
1205 int rv = trans->Start(&request, &callback, BoundNetLog());
1206 EXPECT_EQ(ERR_IO_PENDING, rv);
1207
1208 rv = callback.WaitForResult();
1209 EXPECT_EQ(OK, rv);
1210
1211 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501212 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131213
[email protected]0b0bf032010-09-21 18:08:501214 ASSERT_TRUE(response->headers != NULL);
1215 response_lines[i] = response->headers->GetStatusLine();
1216
1217 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131218 }
[email protected]0b0bf032010-09-21 18:08:501219
1220 const char* const kStatusLines[] = {
1221 "HTTP/1.1 204 No Content",
1222 "HTTP/1.1 205 Reset Content",
1223 "HTTP/1.1 304 Not Modified",
1224 "HTTP/1.1 302 Found",
1225 "HTTP/1.1 302 Found",
1226 "HTTP/1.1 301 Moved Permanently",
1227 "HTTP/1.1 301 Moved Permanently",
1228 };
1229
1230 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1231 forgot_to_update_kStatusLines);
1232
1233 for (int i = 0; i < kNumUnreadBodies; ++i)
1234 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1235
[email protected]f1f3f0f82011-10-01 20:38:101236 TestOldCompletionCallback callback;
[email protected]0b0bf032010-09-21 18:08:501237 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
1238 int rv = trans->Start(&request, &callback, BoundNetLog());
1239 EXPECT_EQ(ERR_IO_PENDING, rv);
1240 rv = callback.WaitForResult();
1241 EXPECT_EQ(OK, rv);
1242 const HttpResponseInfo* response = trans->GetResponseInfo();
1243 ASSERT_TRUE(response != NULL);
1244 ASSERT_TRUE(response->headers != NULL);
1245 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1246 std::string response_data;
1247 rv = ReadTransaction(trans.get(), &response_data);
1248 EXPECT_EQ(OK, rv);
1249 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131250}
1251
[email protected]038e9a32008-10-08 22:40:161252// Test the request-challenge-retry sequence for basic auth.
1253// (basic auth is the easiest to mock, because it has no randomness).
1254TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421255 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161256 request.method = "GET";
1257 request.url = GURL("http://www.google.com/");
1258 request.load_flags = 0;
1259
[email protected]cb9bf6ca2011-01-28 13:15:271260 SessionDependencies session_deps;
1261 scoped_ptr<HttpTransaction> trans(
1262 new HttpNetworkTransaction(CreateSession(&session_deps)));
1263
[email protected]f9ee6b52008-11-08 06:46:231264 MockWrite data_writes1[] = {
1265 MockWrite("GET / HTTP/1.1\r\n"
1266 "Host: www.google.com\r\n"
1267 "Connection: keep-alive\r\n\r\n"),
1268 };
1269
[email protected]038e9a32008-10-08 22:40:161270 MockRead data_reads1[] = {
1271 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1272 // Give a couple authenticate options (only the middle one is actually
1273 // supported).
[email protected]22927ad2009-09-21 19:56:191274 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161275 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1276 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1277 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1278 // Large content-length -- won't matter, as connection will be reset.
1279 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421280 MockRead(false, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161281 };
1282
1283 // After calling trans->RestartWithAuth(), this is the request we should
1284 // be issuing -- the final header line contains the credentials.
1285 MockWrite data_writes2[] = {
1286 MockWrite("GET / HTTP/1.1\r\n"
1287 "Host: www.google.com\r\n"
1288 "Connection: keep-alive\r\n"
1289 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1290 };
1291
1292 // Lastly, the server responds with the actual content.
1293 MockRead data_reads2[] = {
1294 MockRead("HTTP/1.0 200 OK\r\n"),
1295 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1296 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421297 MockRead(false, OK),
[email protected]038e9a32008-10-08 22:40:161298 };
1299
[email protected]31a2bfe2010-02-09 08:03:391300 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1301 data_writes1, arraysize(data_writes1));
1302 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1303 data_writes2, arraysize(data_writes2));
[email protected]5ecc992a42009-11-11 01:41:591304 session_deps.socket_factory.AddSocketDataProvider(&data1);
1305 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161306
[email protected]f1f3f0f82011-10-01 20:38:101307 TestOldCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161308
[email protected]5a1d7ca2010-04-28 20:12:271309 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421310 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161311
1312 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421313 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161314
[email protected]1c773ea12009-04-28 19:58:421315 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501316 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041317 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161318
[email protected]f1f3f0f82011-10-01 20:38:101319 TestOldCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161320
[email protected]f3cf9802011-10-28 18:44:581321 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]1c773ea12009-04-28 19:58:421322 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161323
1324 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421325 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161326
1327 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501328 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161329 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1330 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161331}
1332
[email protected]861fcd52009-08-26 02:33:461333TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461334 HttpRequestInfo request;
1335 request.method = "GET";
1336 request.url = GURL("http://www.google.com/");
1337 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1338
[email protected]cb9bf6ca2011-01-28 13:15:271339 SessionDependencies session_deps;
1340 scoped_ptr<HttpTransaction> trans(
1341 new HttpNetworkTransaction(CreateSession(&session_deps)));
1342
[email protected]861fcd52009-08-26 02:33:461343 MockWrite data_writes[] = {
1344 MockWrite("GET / HTTP/1.1\r\n"
1345 "Host: www.google.com\r\n"
1346 "Connection: keep-alive\r\n\r\n"),
1347 };
1348
1349 MockRead data_reads[] = {
1350 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1351 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1352 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1353 // Large content-length -- won't matter, as connection will be reset.
1354 MockRead("Content-Length: 10000\r\n\r\n"),
1355 MockRead(false, ERR_FAILED),
1356 };
1357
[email protected]31a2bfe2010-02-09 08:03:391358 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1359 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:591360 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]f1f3f0f82011-10-01 20:38:101361 TestOldCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461362
[email protected]5a1d7ca2010-04-28 20:12:271363 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461364 EXPECT_EQ(ERR_IO_PENDING, rv);
1365
1366 rv = callback.WaitForResult();
1367 EXPECT_EQ(0, rv);
1368
1369 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501370 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461371 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1372}
1373
[email protected]2d2697f92009-02-18 21:00:321374// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1375// connection.
1376TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421377 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321378 request.method = "GET";
1379 request.url = GURL("http://www.google.com/");
1380 request.load_flags = 0;
1381
[email protected]cb9bf6ca2011-01-28 13:15:271382 SessionDependencies session_deps;
1383 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
1384
[email protected]2d2697f92009-02-18 21:00:321385 MockWrite data_writes1[] = {
1386 MockWrite("GET / HTTP/1.1\r\n"
1387 "Host: www.google.com\r\n"
1388 "Connection: keep-alive\r\n\r\n"),
1389
1390 // After calling trans->RestartWithAuth(), this is the request we should
1391 // be issuing -- the final header line contains the credentials.
1392 MockWrite("GET / HTTP/1.1\r\n"
1393 "Host: www.google.com\r\n"
1394 "Connection: keep-alive\r\n"
1395 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1396 };
1397
1398 MockRead data_reads1[] = {
1399 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1400 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1401 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1402 MockRead("Content-Length: 14\r\n\r\n"),
1403 MockRead("Unauthorized\r\n"),
1404
1405 // Lastly, the server responds with the actual content.
1406 MockRead("HTTP/1.1 200 OK\r\n"),
1407 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501408 MockRead("Content-Length: 5\r\n\r\n"),
1409 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321410 };
1411
[email protected]2d0a4f92011-05-05 16:38:461412 // If there is a regression where we disconnect a Keep-Alive
1413 // connection during an auth roundtrip, we'll end up reading this.
1414 MockRead data_reads2[] = {
1415 MockRead(false, ERR_FAILED),
1416 };
1417
[email protected]31a2bfe2010-02-09 08:03:391418 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1419 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461420 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1421 NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:591422 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]2d0a4f92011-05-05 16:38:461423 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321424
[email protected]f1f3f0f82011-10-01 20:38:101425 TestOldCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321426
[email protected]0b0bf032010-09-21 18:08:501427 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]5a1d7ca2010-04-28 20:12:271428 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421429 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321430
1431 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421432 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321433
[email protected]1c773ea12009-04-28 19:58:421434 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501435 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041436 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321437
[email protected]f1f3f0f82011-10-01 20:38:101438 TestOldCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321439
[email protected]f3cf9802011-10-28 18:44:581440 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]1c773ea12009-04-28 19:58:421441 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321442
1443 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421444 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321445
1446 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501447 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321448 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501449 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321450}
1451
1452// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1453// connection and with no response body to drain.
1454TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421455 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321456 request.method = "GET";
1457 request.url = GURL("http://www.google.com/");
1458 request.load_flags = 0;
1459
[email protected]cb9bf6ca2011-01-28 13:15:271460 SessionDependencies session_deps;
1461 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
1462
[email protected]2d2697f92009-02-18 21:00:321463 MockWrite data_writes1[] = {
1464 MockWrite("GET / HTTP/1.1\r\n"
1465 "Host: www.google.com\r\n"
1466 "Connection: keep-alive\r\n\r\n"),
1467
1468 // After calling trans->RestartWithAuth(), this is the request we should
1469 // be issuing -- the final header line contains the credentials.
1470 MockWrite("GET / HTTP/1.1\r\n"
1471 "Host: www.google.com\r\n"
1472 "Connection: keep-alive\r\n"
1473 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1474 };
1475
[email protected]2d2697f92009-02-18 21:00:321476 MockRead data_reads1[] = {
1477 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1478 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311479 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321480
1481 // Lastly, the server responds with the actual content.
1482 MockRead("HTTP/1.1 200 OK\r\n"),
1483 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501484 MockRead("Content-Length: 5\r\n\r\n"),
1485 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321486 };
1487
[email protected]2d0a4f92011-05-05 16:38:461488 // An incorrect reconnect would cause this to be read.
1489 MockRead data_reads2[] = {
1490 MockRead(false, ERR_FAILED),
1491 };
1492
[email protected]31a2bfe2010-02-09 08:03:391493 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1494 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461495 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1496 NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:591497 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]2d0a4f92011-05-05 16:38:461498 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321499
[email protected]f1f3f0f82011-10-01 20:38:101500 TestOldCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321501
[email protected]0b0bf032010-09-21 18:08:501502 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]5a1d7ca2010-04-28 20:12:271503 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421504 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321505
1506 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421507 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321508
[email protected]1c773ea12009-04-28 19:58:421509 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501510 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041511 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321512
[email protected]f1f3f0f82011-10-01 20:38:101513 TestOldCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321514
[email protected]f3cf9802011-10-28 18:44:581515 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]1c773ea12009-04-28 19:58:421516 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321517
1518 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421519 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321520
1521 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501522 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321523 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501524 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321525}
1526
1527// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1528// connection and with a large response body to drain.
1529TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421530 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321531 request.method = "GET";
1532 request.url = GURL("http://www.google.com/");
1533 request.load_flags = 0;
1534
[email protected]cb9bf6ca2011-01-28 13:15:271535 SessionDependencies session_deps;
1536 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
1537
[email protected]2d2697f92009-02-18 21:00:321538 MockWrite data_writes1[] = {
1539 MockWrite("GET / HTTP/1.1\r\n"
1540 "Host: www.google.com\r\n"
1541 "Connection: keep-alive\r\n\r\n"),
1542
1543 // After calling trans->RestartWithAuth(), this is the request we should
1544 // be issuing -- the final header line contains the credentials.
1545 MockWrite("GET / HTTP/1.1\r\n"
1546 "Host: www.google.com\r\n"
1547 "Connection: keep-alive\r\n"
1548 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1549 };
1550
1551 // Respond with 5 kb of response body.
1552 std::string large_body_string("Unauthorized");
1553 large_body_string.append(5 * 1024, ' ');
1554 large_body_string.append("\r\n");
1555
1556 MockRead data_reads1[] = {
1557 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1558 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1559 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1560 // 5134 = 12 + 5 * 1024 + 2
1561 MockRead("Content-Length: 5134\r\n\r\n"),
1562 MockRead(true, large_body_string.data(), large_body_string.size()),
1563
1564 // Lastly, the server responds with the actual content.
1565 MockRead("HTTP/1.1 200 OK\r\n"),
1566 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501567 MockRead("Content-Length: 5\r\n\r\n"),
1568 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321569 };
1570
[email protected]2d0a4f92011-05-05 16:38:461571 // An incorrect reconnect would cause this to be read.
1572 MockRead data_reads2[] = {
1573 MockRead(false, ERR_FAILED),
1574 };
1575
[email protected]31a2bfe2010-02-09 08:03:391576 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1577 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461578 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1579 NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:591580 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]2d0a4f92011-05-05 16:38:461581 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321582
[email protected]f1f3f0f82011-10-01 20:38:101583 TestOldCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321584
[email protected]0b0bf032010-09-21 18:08:501585 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]5a1d7ca2010-04-28 20:12:271586 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421587 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321588
1589 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421590 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321591
[email protected]1c773ea12009-04-28 19:58:421592 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501593 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041594 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321595
[email protected]f1f3f0f82011-10-01 20:38:101596 TestOldCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321597
[email protected]f3cf9802011-10-28 18:44:581598 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]1c773ea12009-04-28 19:58:421599 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321600
1601 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421602 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321603
1604 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501605 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321606 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501607 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321608}
1609
1610// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:311611// connection, but the server gets impatient and closes the connection.
1612TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:311613 HttpRequestInfo request;
1614 request.method = "GET";
1615 request.url = GURL("http://www.google.com/");
1616 request.load_flags = 0;
1617
[email protected]cb9bf6ca2011-01-28 13:15:271618 SessionDependencies session_deps;
1619 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
1620
[email protected]11203f012009-11-12 23:02:311621 MockWrite data_writes1[] = {
1622 MockWrite("GET / HTTP/1.1\r\n"
1623 "Host: www.google.com\r\n"
1624 "Connection: keep-alive\r\n\r\n"),
1625 // This simulates the seemingly successful write to a closed connection
1626 // if the bug is not fixed.
1627 MockWrite("GET / HTTP/1.1\r\n"
1628 "Host: www.google.com\r\n"
1629 "Connection: keep-alive\r\n"
1630 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1631 };
1632
1633 MockRead data_reads1[] = {
1634 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1635 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1636 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1637 MockRead("Content-Length: 14\r\n\r\n"),
1638 // Tell MockTCPClientSocket to simulate the server closing the connection.
1639 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1640 MockRead("Unauthorized\r\n"),
1641 MockRead(false, OK), // The server closes the connection.
1642 };
1643
1644 // After calling trans->RestartWithAuth(), this is the request we should
1645 // be issuing -- the final header line contains the credentials.
1646 MockWrite data_writes2[] = {
1647 MockWrite("GET / HTTP/1.1\r\n"
1648 "Host: www.google.com\r\n"
1649 "Connection: keep-alive\r\n"
1650 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1651 };
1652
1653 // Lastly, the server responds with the actual content.
1654 MockRead data_reads2[] = {
1655 MockRead("HTTP/1.1 200 OK\r\n"),
1656 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501657 MockRead("Content-Length: 5\r\n\r\n"),
1658 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:311659 };
1660
[email protected]31a2bfe2010-02-09 08:03:391661 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1662 data_writes1, arraysize(data_writes1));
1663 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1664 data_writes2, arraysize(data_writes2));
[email protected]11203f012009-11-12 23:02:311665 session_deps.socket_factory.AddSocketDataProvider(&data1);
1666 session_deps.socket_factory.AddSocketDataProvider(&data2);
1667
[email protected]f1f3f0f82011-10-01 20:38:101668 TestOldCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:311669
[email protected]0b0bf032010-09-21 18:08:501670 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]5a1d7ca2010-04-28 20:12:271671 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]11203f012009-11-12 23:02:311672 EXPECT_EQ(ERR_IO_PENDING, rv);
1673
1674 rv = callback1.WaitForResult();
1675 EXPECT_EQ(OK, rv);
1676
1677 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501678 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041679 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:311680
[email protected]f1f3f0f82011-10-01 20:38:101681 TestOldCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:311682
[email protected]f3cf9802011-10-28 18:44:581683 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]11203f012009-11-12 23:02:311684 EXPECT_EQ(ERR_IO_PENDING, rv);
1685
1686 rv = callback2.WaitForResult();
1687 EXPECT_EQ(OK, rv);
1688
1689 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501690 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:311691 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501692 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:311693}
1694
[email protected]394816e92010-08-03 07:38:591695// Test the request-challenge-retry sequence for basic auth, over a connection
1696// that requires a restart when setting up an SSL tunnel.
1697TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:591698 HttpRequestInfo request;
1699 request.method = "GET";
1700 request.url = GURL("https://www.google.com/");
1701 // when the no authentication data flag is set.
1702 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1703
[email protected]cb9bf6ca2011-01-28 13:15:271704 // Configure against proxy server "myproxy:70".
1705 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
1706 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1707 session_deps.net_log = log.bound().net_log();
1708 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
1709
[email protected]394816e92010-08-03 07:38:591710 // Since we have proxy, should try to establish tunnel.
1711 MockWrite data_writes1[] = {
1712 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1713 "Host: www.google.com\r\n"
1714 "Proxy-Connection: keep-alive\r\n\r\n"),
1715
1716 // After calling trans->RestartWithAuth(), this is the request we should
1717 // be issuing -- the final header line contains the credentials.
1718 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1719 "Host: www.google.com\r\n"
1720 "Proxy-Connection: keep-alive\r\n"
1721 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1722
1723 MockWrite("GET / HTTP/1.1\r\n"
1724 "Host: www.google.com\r\n"
1725 "Connection: keep-alive\r\n\r\n"),
1726 };
1727
1728 // The proxy responds to the connect with a 407, using a persistent
1729 // connection.
1730 MockRead data_reads1[] = {
1731 // No credentials.
1732 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
1733 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1734 MockRead("Proxy-Connection: close\r\n\r\n"),
1735
1736 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
1737
1738 MockRead("HTTP/1.1 200 OK\r\n"),
1739 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501740 MockRead("Content-Length: 5\r\n\r\n"),
1741 MockRead(false, "hello"),
[email protected]394816e92010-08-03 07:38:591742 };
1743
1744 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1745 data_writes1, arraysize(data_writes1));
1746 session_deps.socket_factory.AddSocketDataProvider(&data1);
1747 SSLSocketDataProvider ssl(true, OK);
1748 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
1749
[email protected]f1f3f0f82011-10-01 20:38:101750 TestOldCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:591751
[email protected]0b0bf032010-09-21 18:08:501752 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
1753
[email protected]394816e92010-08-03 07:38:591754 int rv = trans->Start(&request, &callback1, log.bound());
1755 EXPECT_EQ(ERR_IO_PENDING, rv);
1756
1757 rv = callback1.WaitForResult();
1758 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:401759 net::CapturingNetLog::EntryList entries;
1760 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:591761 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:401762 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:591763 NetLog::PHASE_NONE);
1764 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:401765 entries, pos,
[email protected]394816e92010-08-03 07:38:591766 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1767 NetLog::PHASE_NONE);
1768
1769 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501770 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041771 ASSERT_FALSE(response->headers == NULL);
[email protected]394816e92010-08-03 07:38:591772 EXPECT_EQ(407, response->headers->response_code());
1773 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:041774 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:591775
[email protected]f1f3f0f82011-10-01 20:38:101776 TestOldCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:591777
[email protected]f3cf9802011-10-28 18:44:581778 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]394816e92010-08-03 07:38:591779 EXPECT_EQ(ERR_IO_PENDING, rv);
1780
1781 rv = callback2.WaitForResult();
1782 EXPECT_EQ(OK, rv);
1783
1784 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501785 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:591786
1787 EXPECT_TRUE(response->headers->IsKeepAlive());
1788 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:501789 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:591790 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
1791
1792 // The password prompt info should not be set.
1793 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501794
1795 trans.reset();
[email protected]102e27c2011-02-23 01:01:311796 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:591797}
1798
[email protected]11203f012009-11-12 23:02:311799// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:321800// proxy connection, when setting up an SSL tunnel.
1801TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:271802 HttpRequestInfo request;
1803 request.method = "GET";
1804 request.url = GURL("https://www.google.com/");
1805 // Ensure that proxy authentication is attempted even
1806 // when the no authentication data flag is set.
1807 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1808
[email protected]2d2697f92009-02-18 21:00:321809 // Configure against proxy server "myproxy:70".
[email protected]81cdfcd2010-10-16 00:49:001810 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]a7ea8832010-07-12 17:54:541811 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1812 session_deps.net_log = log.bound().net_log();
[email protected]228ff742009-06-05 01:19:591813 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]2d2697f92009-02-18 21:00:321814
[email protected]5695b8c2009-09-30 21:36:431815 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]2d2697f92009-02-18 21:00:321816
[email protected]2d2697f92009-02-18 21:00:321817 // Since we have proxy, should try to establish tunnel.
1818 MockWrite data_writes1[] = {
1819 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:451820 "Host: www.google.com\r\n"
1821 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:321822
1823 // After calling trans->RestartWithAuth(), this is the request we should
1824 // be issuing -- the final header line contains the credentials.
1825 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1826 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:451827 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:321828 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
1829 };
1830
1831 // The proxy responds to the connect with a 407, using a persistent
1832 // connection.
1833 MockRead data_reads1[] = {
1834 // No credentials.
1835 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
1836 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1837 MockRead("Content-Length: 10\r\n\r\n"),
1838 MockRead("0123456789"),
1839
1840 // Wrong credentials (wrong password).
1841 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
1842 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1843 MockRead("Content-Length: 10\r\n\r\n"),
1844 // No response body because the test stops reading here.
[email protected]1c773ea12009-04-28 19:58:421845 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:321846 };
1847
[email protected]31a2bfe2010-02-09 08:03:391848 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1849 data_writes1, arraysize(data_writes1));
[email protected]5ecc992a42009-11-11 01:41:591850 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:321851
[email protected]f1f3f0f82011-10-01 20:38:101852 TestOldCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321853
[email protected]dbb83db2010-05-11 18:13:391854 int rv = trans->Start(&request, &callback1, log.bound());
[email protected]1c773ea12009-04-28 19:58:421855 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321856
1857 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421858 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:401859 net::CapturingNetLog::EntryList entries;
1860 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:391861 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:401862 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:391863 NetLog::PHASE_NONE);
1864 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:401865 entries, pos,
[email protected]dbb83db2010-05-11 18:13:391866 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1867 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:321868
[email protected]1c773ea12009-04-28 19:58:421869 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501870 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041871 ASSERT_FALSE(response->headers == NULL);
[email protected]2d2697f92009-02-18 21:00:321872 EXPECT_TRUE(response->headers->IsKeepAlive());
1873 EXPECT_EQ(407, response->headers->response_code());
1874 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:421875 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:041876 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321877
[email protected]f1f3f0f82011-10-01 20:38:101878 TestOldCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321879
1880 // Wrong password (should be "bar").
[email protected]f3cf9802011-10-28 18:44:581881 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), &callback2);
[email protected]1c773ea12009-04-28 19:58:421882 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321883
1884 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421885 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321886
1887 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501888 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041889 ASSERT_FALSE(response->headers == NULL);
[email protected]2d2697f92009-02-18 21:00:321890 EXPECT_TRUE(response->headers->IsKeepAlive());
1891 EXPECT_EQ(407, response->headers->response_code());
1892 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:421893 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:041894 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:131895
[email protected]e60e47a2010-07-14 03:37:181896 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
1897 // out of scope.
[email protected]102e27c2011-02-23 01:01:311898 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:321899}
1900
[email protected]a8e9b162009-03-12 00:06:441901// Test that we don't read the response body when we fail to establish a tunnel,
1902// even if the user cancels the proxy's auth attempt.
1903TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:271904 HttpRequestInfo request;
1905 request.method = "GET";
1906 request.url = GURL("https://www.google.com/");
1907 request.load_flags = 0;
1908
[email protected]a8e9b162009-03-12 00:06:441909 // Configure against proxy server "myproxy:70".
[email protected]81cdfcd2010-10-16 00:49:001910 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:441911
[email protected]e44de5d2009-06-05 20:12:451912 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]a8e9b162009-03-12 00:06:441913
[email protected]5695b8c2009-09-30 21:36:431914 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]a8e9b162009-03-12 00:06:441915
[email protected]a8e9b162009-03-12 00:06:441916 // Since we have proxy, should try to establish tunnel.
1917 MockWrite data_writes[] = {
1918 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:451919 "Host: www.google.com\r\n"
1920 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:441921 };
1922
1923 // The proxy responds to the connect with a 407.
1924 MockRead data_reads[] = {
1925 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
1926 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1927 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421928 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:441929 };
1930
[email protected]31a2bfe2010-02-09 08:03:391931 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1932 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:591933 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:441934
[email protected]f1f3f0f82011-10-01 20:38:101935 TestOldCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:441936
[email protected]5a1d7ca2010-04-28 20:12:271937 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421938 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:441939
1940 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421941 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:441942
[email protected]1c773ea12009-04-28 19:58:421943 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501944 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:441945
1946 EXPECT_TRUE(response->headers->IsKeepAlive());
1947 EXPECT_EQ(407, response->headers->response_code());
1948 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:421949 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:441950
1951 std::string response_data;
1952 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421953 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:181954
1955 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:311956 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:441957}
1958
[email protected]8fdbcd22010-05-05 02:54:521959// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
1960// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
1961TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:521962 HttpRequestInfo request;
1963 request.method = "GET";
1964 request.url = GURL("http://www.google.com/");
1965 request.load_flags = 0;
1966
[email protected]cb9bf6ca2011-01-28 13:15:271967 // We are using a DIRECT connection (i.e. no proxy) for this session.
1968 SessionDependencies session_deps;
1969 scoped_ptr<HttpTransaction> trans(
1970 new HttpNetworkTransaction(CreateSession(&session_deps)));
1971
[email protected]8fdbcd22010-05-05 02:54:521972 MockWrite data_writes1[] = {
1973 MockWrite("GET / HTTP/1.1\r\n"
1974 "Host: www.google.com\r\n"
1975 "Connection: keep-alive\r\n\r\n"),
1976 };
1977
1978 MockRead data_reads1[] = {
1979 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
1980 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1981 // Large content-length -- won't matter, as connection will be reset.
1982 MockRead("Content-Length: 10000\r\n\r\n"),
1983 MockRead(false, ERR_FAILED),
1984 };
1985
1986 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1987 data_writes1, arraysize(data_writes1));
1988 session_deps.socket_factory.AddSocketDataProvider(&data1);
1989
[email protected]f1f3f0f82011-10-01 20:38:101990 TestOldCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:521991
1992 int rv = trans->Start(&request, &callback, BoundNetLog());
1993 EXPECT_EQ(ERR_IO_PENDING, rv);
1994
1995 rv = callback.WaitForResult();
1996 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
1997}
1998
[email protected]7a67a8152010-11-05 18:31:101999// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2000// through a non-authenticating proxy. The request should fail with
2001// ERR_UNEXPECTED_PROXY_AUTH.
2002// Note that it is impossible to detect if an HTTP server returns a 407 through
2003// a non-authenticating proxy - there is nothing to indicate whether the
2004// response came from the proxy or the server, so it is treated as if the proxy
2005// issued the challenge.
2006TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272007 HttpRequestInfo request;
2008 request.method = "GET";
2009 request.url = GURL("https://www.google.com/");
2010
[email protected]7a67a8152010-11-05 18:31:102011 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
2012 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2013 session_deps.net_log = log.bound().net_log();
2014 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2015
[email protected]7a67a8152010-11-05 18:31:102016 // Since we have proxy, should try to establish tunnel.
2017 MockWrite data_writes1[] = {
2018 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2019 "Host: www.google.com\r\n"
2020 "Proxy-Connection: keep-alive\r\n\r\n"),
2021
2022 MockWrite("GET / HTTP/1.1\r\n"
2023 "Host: www.google.com\r\n"
2024 "Connection: keep-alive\r\n\r\n"),
2025 };
2026
2027 MockRead data_reads1[] = {
2028 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2029
2030 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2031 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2032 MockRead("\r\n"),
2033 MockRead(false, OK),
2034 };
2035
2036 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2037 data_writes1, arraysize(data_writes1));
2038 session_deps.socket_factory.AddSocketDataProvider(&data1);
2039 SSLSocketDataProvider ssl(true, OK);
2040 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2041
[email protected]f1f3f0f82011-10-01 20:38:102042 TestOldCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102043
2044 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2045
2046 int rv = trans->Start(&request, &callback1, log.bound());
2047 EXPECT_EQ(ERR_IO_PENDING, rv);
2048
2049 rv = callback1.WaitForResult();
2050 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]b2fcd0e2010-12-01 15:19:402051 net::CapturingNetLog::EntryList entries;
2052 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102053 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402054 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102055 NetLog::PHASE_NONE);
2056 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402057 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102058 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2059 NetLog::PHASE_NONE);
2060}
[email protected]2df19bb2010-08-25 20:13:462061
2062// Test a simple get through an HTTPS Proxy.
2063TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272064 HttpRequestInfo request;
2065 request.method = "GET";
2066 request.url = GURL("http://www.google.com/");
2067
[email protected]2df19bb2010-08-25 20:13:462068 // Configure against https proxy server "proxy:70".
[email protected]3912662a32011-10-04 00:51:112069 SessionDependencies session_deps(ProxyService::CreateFixed(
2070 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:462071 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2072 session_deps.net_log = log.bound().net_log();
2073 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2074
[email protected]2df19bb2010-08-25 20:13:462075 // Since we have proxy, should use full url
2076 MockWrite data_writes1[] = {
2077 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2078 "Host: www.google.com\r\n"
2079 "Proxy-Connection: keep-alive\r\n\r\n"),
2080 };
2081
2082 MockRead data_reads1[] = {
2083 MockRead("HTTP/1.1 200 OK\r\n"),
2084 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2085 MockRead("Content-Length: 100\r\n\r\n"),
2086 MockRead(false, OK),
2087 };
2088
2089 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2090 data_writes1, arraysize(data_writes1));
2091 session_deps.socket_factory.AddSocketDataProvider(&data1);
2092 SSLSocketDataProvider ssl(true, OK);
2093 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2094
[email protected]f1f3f0f82011-10-01 20:38:102095 TestOldCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462096
[email protected]0b0bf032010-09-21 18:08:502097 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2098
[email protected]2df19bb2010-08-25 20:13:462099 int rv = trans->Start(&request, &callback1, log.bound());
2100 EXPECT_EQ(ERR_IO_PENDING, rv);
2101
2102 rv = callback1.WaitForResult();
2103 EXPECT_EQ(OK, rv);
2104
2105 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502106 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462107
2108 EXPECT_TRUE(response->headers->IsKeepAlive());
2109 EXPECT_EQ(200, response->headers->response_code());
2110 EXPECT_EQ(100, response->headers->GetContentLength());
2111 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2112
2113 // The password prompt info should not be set.
2114 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2115}
2116
[email protected]7642b5ae2010-09-01 20:55:172117// Test a SPDY get through an HTTPS Proxy.
2118TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272119 HttpRequestInfo request;
2120 request.method = "GET";
2121 request.url = GURL("http://www.google.com/");
2122 request.load_flags = 0;
2123
[email protected]7642b5ae2010-09-01 20:55:172124 // Configure against https proxy server "proxy:70".
[email protected]3912662a32011-10-04 00:51:112125 SessionDependencies session_deps(ProxyService::CreateFixed(
2126 "https://proxy:70"));
[email protected]7642b5ae2010-09-01 20:55:172127 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2128 session_deps.net_log = log.bound().net_log();
2129 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2130
[email protected]7642b5ae2010-09-01 20:55:172131 // fetch http://www.google.com/ via SPDY
2132 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST,
2133 false));
2134 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2135
2136 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
2137 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
2138 MockRead spdy_reads[] = {
2139 CreateMockRead(*resp),
2140 CreateMockRead(*data),
2141 MockRead(true, 0, 0),
2142 };
2143
2144 scoped_refptr<DelayedSocketData> spdy_data(
2145 new DelayedSocketData(
2146 1, // wait for one write to finish before reading.
2147 spdy_reads, arraysize(spdy_reads),
2148 spdy_writes, arraysize(spdy_writes)));
2149 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
2150
2151 SSLSocketDataProvider ssl(true, OK);
2152 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
2153 ssl.next_proto = "spdy/2";
2154 ssl.was_npn_negotiated = true;
2155 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2156
[email protected]f1f3f0f82011-10-01 20:38:102157 TestOldCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172158
[email protected]0b0bf032010-09-21 18:08:502159 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2160
[email protected]7642b5ae2010-09-01 20:55:172161 int rv = trans->Start(&request, &callback1, log.bound());
2162 EXPECT_EQ(ERR_IO_PENDING, rv);
2163
2164 rv = callback1.WaitForResult();
2165 EXPECT_EQ(OK, rv);
2166
2167 const HttpResponseInfo* response = trans->GetResponseInfo();
2168 ASSERT_TRUE(response != NULL);
2169 ASSERT_TRUE(response->headers != NULL);
2170 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2171
2172 std::string response_data;
2173 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2174 EXPECT_EQ(net::kUploadData, response_data);
2175}
2176
[email protected]dc7bd1c52010-11-12 00:01:132177// Test a SPDY get through an HTTPS Proxy.
2178TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272179 HttpRequestInfo request;
2180 request.method = "GET";
2181 request.url = GURL("http://www.google.com/");
2182 request.load_flags = 0;
2183
[email protected]79cb5c12011-09-12 13:12:042184 // Configure against https proxy server "myproxy:70".
[email protected]dc7bd1c52010-11-12 00:01:132185 SessionDependencies session_deps(
[email protected]79cb5c12011-09-12 13:12:042186 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]dc7bd1c52010-11-12 00:01:132187 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2188 session_deps.net_log = log.bound().net_log();
2189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2190
[email protected]dc7bd1c52010-11-12 00:01:132191 // The first request will be a bare GET, the second request will be a
2192 // GET with a Proxy-Authorization header.
2193 scoped_ptr<spdy::SpdyFrame> req_get(
2194 ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
2195 const char* const kExtraAuthorizationHeaders[] = {
2196 "proxy-authorization",
2197 "Basic Zm9vOmJhcg==",
2198 };
2199 scoped_ptr<spdy::SpdyFrame> req_get_authorization(
2200 ConstructSpdyGet(
2201 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders)/2,
2202 false, 3, LOWEST, false));
2203 MockWrite spdy_writes[] = {
2204 CreateMockWrite(*req_get, 1),
2205 CreateMockWrite(*req_get_authorization, 4),
2206 };
2207
2208 // The first response is a 407 proxy authentication challenge, and the second
2209 // response will be a 200 response since the second request includes a valid
2210 // Authorization header.
2211 const char* const kExtraAuthenticationHeaders[] = {
2212 "Proxy-Authenticate",
2213 "Basic realm=\"MyRealm1\""
2214 };
2215 scoped_ptr<spdy::SpdyFrame> resp_authentication(
2216 ConstructSpdySynReplyError(
2217 "407 Proxy Authentication Required",
2218 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2219 1));
2220 scoped_ptr<spdy::SpdyFrame> body_authentication(
2221 ConstructSpdyBodyFrame(1, true));
2222 scoped_ptr<spdy::SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3));
2223 scoped_ptr<spdy::SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true));
2224 MockRead spdy_reads[] = {
2225 CreateMockRead(*resp_authentication, 2),
2226 CreateMockRead(*body_authentication, 3),
2227 CreateMockRead(*resp_data, 5),
2228 CreateMockRead(*body_data, 6),
2229 MockRead(true, 0, 7),
2230 };
2231
2232 scoped_refptr<OrderedSocketData> data(
2233 new OrderedSocketData(spdy_reads, arraysize(spdy_reads),
2234 spdy_writes, arraysize(spdy_writes)));
2235 session_deps.socket_factory.AddSocketDataProvider(data);
2236
2237 SSLSocketDataProvider ssl(true, OK);
2238 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
2239 ssl.next_proto = "spdy/2";
2240 ssl.was_npn_negotiated = true;
2241 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2242
[email protected]f1f3f0f82011-10-01 20:38:102243 TestOldCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132244
2245 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2246
2247 int rv = trans->Start(&request, &callback1, log.bound());
2248 EXPECT_EQ(ERR_IO_PENDING, rv);
2249
2250 rv = callback1.WaitForResult();
2251 EXPECT_EQ(OK, rv);
2252
2253 const HttpResponseInfo* const response = trans->GetResponseInfo();
2254
2255 ASSERT_TRUE(response != NULL);
2256 ASSERT_TRUE(response->headers != NULL);
2257 EXPECT_EQ(407, response->headers->response_code());
2258 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042259 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132260
[email protected]f1f3f0f82011-10-01 20:38:102261 TestOldCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132262
[email protected]f3cf9802011-10-28 18:44:582263 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]dc7bd1c52010-11-12 00:01:132264 EXPECT_EQ(ERR_IO_PENDING, rv);
2265
2266 rv = callback2.WaitForResult();
2267 EXPECT_EQ(OK, rv);
2268
2269 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2270
2271 ASSERT_TRUE(response_restart != NULL);
2272 ASSERT_TRUE(response_restart->headers != NULL);
2273 EXPECT_EQ(200, response_restart->headers->response_code());
2274 // The password prompt info should not be set.
2275 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2276}
2277
[email protected]d9da5fe2010-10-13 22:37:162278// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
2279TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272280 HttpRequestInfo request;
2281 request.method = "GET";
2282 request.url = GURL("https://www.google.com/");
2283 request.load_flags = 0;
2284
[email protected]d9da5fe2010-10-13 22:37:162285 // Configure against https proxy server "proxy:70".
[email protected]3912662a32011-10-04 00:51:112286 SessionDependencies session_deps(ProxyService::CreateFixed(
2287 "https://proxy:70"));
[email protected]d9da5fe2010-10-13 22:37:162288 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2289 session_deps.net_log = log.bound().net_log();
2290 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2291
2292 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2293
[email protected]d9da5fe2010-10-13 22:37:162294 // CONNECT to www.google.com:443 via SPDY
2295 scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1));
2296 // fetch https://www.google.com/ via HTTP
2297
2298 const char get[] = "GET / HTTP/1.1\r\n"
2299 "Host: www.google.com\r\n"
2300 "Connection: keep-alive\r\n\r\n";
2301 scoped_ptr<spdy::SpdyFrame> wrapped_get(
2302 ConstructSpdyBodyFrame(1, get, strlen(get), false));
2303 MockWrite spdy_writes[] = {
2304 CreateMockWrite(*connect, 1),
2305 CreateMockWrite(*wrapped_get, 3)
2306 };
2307
2308 scoped_ptr<spdy::SpdyFrame> conn_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
2309 const char resp[] = "HTTP/1.1 200 OK\r\n"
2310 "Content-Length: 10\r\n\r\n";
2311
2312 scoped_ptr<spdy::SpdyFrame> wrapped_get_resp(
2313 ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
2314 scoped_ptr<spdy::SpdyFrame> wrapped_body(
2315 ConstructSpdyBodyFrame(1, "1234567890", 10, false));
2316 MockRead spdy_reads[] = {
2317 CreateMockRead(*conn_resp, 2, true),
2318 CreateMockRead(*wrapped_get_resp, 4, true),
2319 CreateMockRead(*wrapped_body, 5, true),
2320 CreateMockRead(*wrapped_body, 6, true),
2321 MockRead(true, 0, 7),
2322 };
2323
2324 scoped_refptr<OrderedSocketData> spdy_data(
2325 new OrderedSocketData(
2326 spdy_reads, arraysize(spdy_reads),
2327 spdy_writes, arraysize(spdy_writes)));
2328 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
2329
2330 SSLSocketDataProvider ssl(true, OK);
2331 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
2332 ssl.next_proto = "spdy/2";
2333 ssl.was_npn_negotiated = true;
2334 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2335 SSLSocketDataProvider ssl2(true, OK);
2336 ssl2.was_npn_negotiated = false;
2337 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
2338
[email protected]f1f3f0f82011-10-01 20:38:102339 TestOldCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162340
2341 int rv = trans->Start(&request, &callback1, log.bound());
2342 EXPECT_EQ(ERR_IO_PENDING, rv);
2343
2344 rv = callback1.WaitForResult();
2345 EXPECT_EQ(OK, rv);
2346
2347 const HttpResponseInfo* response = trans->GetResponseInfo();
2348 ASSERT_TRUE(response != NULL);
2349 ASSERT_TRUE(response->headers != NULL);
2350 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2351
2352 std::string response_data;
2353 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2354 EXPECT_EQ("1234567890", response_data);
2355}
2356
2357// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
2358TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:272359 HttpRequestInfo request;
2360 request.method = "GET";
2361 request.url = GURL("https://www.google.com/");
2362 request.load_flags = 0;
2363
[email protected]d9da5fe2010-10-13 22:37:162364 // Configure against https proxy server "proxy:70".
[email protected]3912662a32011-10-04 00:51:112365 SessionDependencies session_deps(ProxyService::CreateFixed(
2366 "https://proxy:70"));
[email protected]d9da5fe2010-10-13 22:37:162367 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2368 session_deps.net_log = log.bound().net_log();
2369 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2370
2371 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2372
[email protected]d9da5fe2010-10-13 22:37:162373 // CONNECT to www.google.com:443 via SPDY
2374 scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1));
2375 // fetch https://www.google.com/ via SPDY
2376 const char* const kMyUrl = "https://www.google.com/";
2377 scoped_ptr<spdy::SpdyFrame> get(ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
2378 scoped_ptr<spdy::SpdyFrame> wrapped_get(ConstructWrappedSpdyFrame(get, 1));
2379 MockWrite spdy_writes[] = {
2380 CreateMockWrite(*connect, 1),
2381 CreateMockWrite(*wrapped_get, 3)
2382 };
2383
2384 scoped_ptr<spdy::SpdyFrame> conn_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
2385 scoped_ptr<spdy::SpdyFrame> get_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
2386 scoped_ptr<spdy::SpdyFrame> wrapped_get_resp(
2387 ConstructWrappedSpdyFrame(get_resp, 1));
2388 scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
2389 scoped_ptr<spdy::SpdyFrame> wrapped_body(ConstructWrappedSpdyFrame(body, 1));
2390 MockRead spdy_reads[] = {
2391 CreateMockRead(*conn_resp, 2, true),
2392 CreateMockRead(*wrapped_get_resp, 4, true),
2393 CreateMockRead(*wrapped_body, 5, true),
2394 MockRead(true, 0, 1),
2395 };
2396
2397 scoped_refptr<OrderedSocketData> spdy_data(
2398 new OrderedSocketData(
2399 spdy_reads, arraysize(spdy_reads),
2400 spdy_writes, arraysize(spdy_writes)));
2401 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
2402
2403 SSLSocketDataProvider ssl(true, OK);
2404 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
2405 ssl.next_proto = "spdy/2";
2406 ssl.was_npn_negotiated = true;
2407 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2408 SSLSocketDataProvider ssl2(true, OK);
2409 ssl2.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
2410 ssl2.next_proto = "spdy/2";
2411 ssl2.was_npn_negotiated = true;
2412 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
2413
[email protected]f1f3f0f82011-10-01 20:38:102414 TestOldCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162415
2416 int rv = trans->Start(&request, &callback1, log.bound());
2417 EXPECT_EQ(ERR_IO_PENDING, rv);
2418
2419 rv = callback1.WaitForResult();
2420 EXPECT_EQ(OK, rv);
2421
2422 const HttpResponseInfo* response = trans->GetResponseInfo();
2423 ASSERT_TRUE(response != NULL);
2424 ASSERT_TRUE(response->headers != NULL);
2425 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2426
2427 std::string response_data;
2428 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2429 EXPECT_EQ(net::kUploadData, response_data);
2430}
2431
2432// Test a SPDY CONNECT failure through an HTTPS Proxy.
2433TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:272434 HttpRequestInfo request;
2435 request.method = "GET";
2436 request.url = GURL("https://www.google.com/");
2437 request.load_flags = 0;
2438
[email protected]d9da5fe2010-10-13 22:37:162439 // Configure against https proxy server "proxy:70".
[email protected]3912662a32011-10-04 00:51:112440 SessionDependencies session_deps(ProxyService::CreateFixed(
2441 "https://proxy:70"));
[email protected]d9da5fe2010-10-13 22:37:162442 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2443 session_deps.net_log = log.bound().net_log();
2444 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2445
2446 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2447
[email protected]d9da5fe2010-10-13 22:37:162448 // CONNECT to www.google.com:443 via SPDY
2449 scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1));
2450 scoped_ptr<spdy::SpdyFrame> get(ConstructSpdyRstStream(1, spdy::CANCEL));
2451
2452 MockWrite spdy_writes[] = {
2453 CreateMockWrite(*connect, 1),
2454 CreateMockWrite(*get, 3),
2455 };
2456
2457 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdySynReplyError(1));
2458 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
2459 MockRead spdy_reads[] = {
2460 CreateMockRead(*resp, 2, true),
2461 MockRead(true, 0, 4),
2462 };
2463
2464 scoped_refptr<OrderedSocketData> spdy_data(
2465 new OrderedSocketData(
2466 spdy_reads, arraysize(spdy_reads),
2467 spdy_writes, arraysize(spdy_writes)));
2468 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
2469
2470 SSLSocketDataProvider ssl(true, OK);
2471 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
2472 ssl.next_proto = "spdy/2";
2473 ssl.was_npn_negotiated = true;
2474 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2475 SSLSocketDataProvider ssl2(true, OK);
2476 ssl2.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
2477 ssl2.next_proto = "spdy/2";
2478 ssl2.was_npn_negotiated = true;
2479 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
2480
[email protected]f1f3f0f82011-10-01 20:38:102481 TestOldCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162482
2483 int rv = trans->Start(&request, &callback1, log.bound());
2484 EXPECT_EQ(ERR_IO_PENDING, rv);
2485
2486 rv = callback1.WaitForResult();
[email protected]511f6f52010-12-17 03:58:292487 EXPECT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:162488
2489 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502490 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:292491 EXPECT_EQ(500, response->headers->response_code());
[email protected]d9da5fe2010-10-13 22:37:162492}
2493
[email protected]2df19bb2010-08-25 20:13:462494// Test the challenge-response-retry sequence through an HTTPS Proxy
2495TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:462496 HttpRequestInfo request;
2497 request.method = "GET";
2498 request.url = GURL("http://www.google.com/");
2499 // when the no authentication data flag is set.
2500 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2501
[email protected]79cb5c12011-09-12 13:12:042502 // Configure against https proxy server "myproxy:70".
2503 SessionDependencies session_deps(
2504 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:272505 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2506 session_deps.net_log = log.bound().net_log();
2507 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2508
[email protected]2df19bb2010-08-25 20:13:462509 // Since we have proxy, should use full url
2510 MockWrite data_writes1[] = {
2511 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2512 "Host: www.google.com\r\n"
2513 "Proxy-Connection: keep-alive\r\n\r\n"),
2514
2515 // After calling trans->RestartWithAuth(), this is the request we should
2516 // be issuing -- the final header line contains the credentials.
2517 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2518 "Host: www.google.com\r\n"
2519 "Proxy-Connection: keep-alive\r\n"
2520 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2521 };
2522
2523 // The proxy responds to the GET with a 407, using a persistent
2524 // connection.
2525 MockRead data_reads1[] = {
2526 // No credentials.
2527 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2528 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2529 MockRead("Proxy-Connection: keep-alive\r\n"),
2530 MockRead("Content-Length: 0\r\n\r\n"),
2531
2532 MockRead("HTTP/1.1 200 OK\r\n"),
2533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2534 MockRead("Content-Length: 100\r\n\r\n"),
2535 MockRead(false, OK),
2536 };
2537
2538 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2539 data_writes1, arraysize(data_writes1));
2540 session_deps.socket_factory.AddSocketDataProvider(&data1);
2541 SSLSocketDataProvider ssl(true, OK);
2542 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
2543
[email protected]f1f3f0f82011-10-01 20:38:102544 TestOldCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462545
[email protected]0b0bf032010-09-21 18:08:502546 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2547
[email protected]2df19bb2010-08-25 20:13:462548 int rv = trans->Start(&request, &callback1, log.bound());
2549 EXPECT_EQ(ERR_IO_PENDING, rv);
2550
2551 rv = callback1.WaitForResult();
2552 EXPECT_EQ(OK, rv);
2553
2554 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502555 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042556 ASSERT_FALSE(response->headers == NULL);
[email protected]2df19bb2010-08-25 20:13:462557 EXPECT_EQ(407, response->headers->response_code());
2558 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042559 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:462560
[email protected]f1f3f0f82011-10-01 20:38:102561 TestOldCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:462562
[email protected]f3cf9802011-10-28 18:44:582563 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]2df19bb2010-08-25 20:13:462564 EXPECT_EQ(ERR_IO_PENDING, rv);
2565
2566 rv = callback2.WaitForResult();
2567 EXPECT_EQ(OK, rv);
2568
2569 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502570 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462571
2572 EXPECT_TRUE(response->headers->IsKeepAlive());
2573 EXPECT_EQ(200, response->headers->response_code());
2574 EXPECT_EQ(100, response->headers->GetContentLength());
2575 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2576
2577 // The password prompt info should not be set.
2578 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2579}
2580
[email protected]ff007e162009-05-23 09:13:152581void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:082582 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:422583 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:082584 request.method = "GET";
2585 request.url = GURL("https://www.google.com/");
2586 request.load_flags = 0;
2587
[email protected]cb9bf6ca2011-01-28 13:15:272588 // Configure against proxy server "myproxy:70".
2589 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
2590
2591 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2592
[email protected]c744cf22009-02-27 07:28:082593 // Since we have proxy, should try to establish tunnel.
2594 MockWrite data_writes[] = {
2595 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452596 "Host: www.google.com\r\n"
2597 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:082598 };
2599
2600 MockRead data_reads[] = {
2601 status,
2602 MockRead("Content-Length: 10\r\n\r\n"),
2603 // No response body because the test stops reading here.
[email protected]1c773ea12009-04-28 19:58:422604 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:082605 };
2606
[email protected]31a2bfe2010-02-09 08:03:392607 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2608 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:592609 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:082610
[email protected]f1f3f0f82011-10-01 20:38:102611 TestOldCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:082612
[email protected]0b0bf032010-09-21 18:08:502613 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
2614
[email protected]5a1d7ca2010-04-28 20:12:272615 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422616 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:082617
2618 rv = callback.WaitForResult();
2619 EXPECT_EQ(expected_status, rv);
2620}
2621
[email protected]ff007e162009-05-23 09:13:152622void HttpNetworkTransactionTest::ConnectStatusHelper(const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:082623 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:422624 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:082625}
2626
2627TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
2628 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
2629}
2630
2631TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
2632 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
2633}
2634
2635TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
2636 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
2637}
2638
2639TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
2640 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
2641}
2642
2643TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
2644 ConnectStatusHelper(
2645 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
2646}
2647
2648TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
2649 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
2650}
2651
2652TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
2653 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
2654}
2655
2656TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
2657 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
2658}
2659
2660TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
2661 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
2662}
2663
2664TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
2665 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
2666}
2667
2668TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
2669 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
2670}
2671
2672TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
2673 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
2674}
2675
2676TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
2677 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
2678}
2679
2680TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
2681 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
2682}
2683
2684TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
2685 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
2686}
2687
2688TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
2689 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
2690}
2691
2692TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
2693 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
2694}
2695
2696TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
2697 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
2698}
2699
2700TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
2701 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
2702}
2703
2704TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
2705 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
2706}
2707
2708TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
2709 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
2710}
2711
2712TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
2713 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
2714}
2715
2716TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
2717 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
2718}
2719
2720TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
2721 ConnectStatusHelperWithExpectedStatus(
2722 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:542723 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:082724}
2725
2726TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
2727 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
2728}
2729
2730TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
2731 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
2732}
2733
2734TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
2735 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
2736}
2737
2738TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
2739 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
2740}
2741
2742TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
2743 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
2744}
2745
2746TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
2747 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
2748}
2749
2750TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
2751 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
2752}
2753
2754TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
2755 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
2756}
2757
2758TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
2759 ConnectStatusHelper(
2760 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
2761}
2762
2763TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
2764 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
2765}
2766
2767TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
2768 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
2769}
2770
2771TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
2772 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
2773}
2774
2775TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
2776 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
2777}
2778
2779TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
2780 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
2781}
2782
2783TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
2784 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
2785}
2786
2787TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
2788 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
2789}
2790
[email protected]038e9a32008-10-08 22:40:162791// Test the flow when both the proxy server AND origin server require
2792// authentication. Again, this uses basic auth for both since that is
2793// the simplest to mock.
2794TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:272795 HttpRequestInfo request;
2796 request.method = "GET";
2797 request.url = GURL("http://www.google.com/");
2798 request.load_flags = 0;
2799
[email protected]81cdfcd2010-10-16 00:49:002800 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:012801
[email protected]038e9a32008-10-08 22:40:162802 // Configure against proxy server "myproxy:70".
[email protected]1c773ea12009-04-28 19:58:422803 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]5695b8c2009-09-30 21:36:432804 CreateSession(&session_deps)));
[email protected]038e9a32008-10-08 22:40:162805
[email protected]f9ee6b52008-11-08 06:46:232806 MockWrite data_writes1[] = {
2807 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2808 "Host: www.google.com\r\n"
2809 "Proxy-Connection: keep-alive\r\n\r\n"),
2810 };
2811
[email protected]038e9a32008-10-08 22:40:162812 MockRead data_reads1[] = {
2813 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
2814 // Give a couple authenticate options (only the middle one is actually
2815 // supported).
[email protected]22927ad2009-09-21 19:56:192816 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162817 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2818 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2819 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2820 // Large content-length -- won't matter, as connection will be reset.
2821 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422822 MockRead(false, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162823 };
2824
2825 // After calling trans->RestartWithAuth() the first time, this is the
2826 // request we should be issuing -- the final header line contains the
2827 // proxy's credentials.
2828 MockWrite data_writes2[] = {
2829 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2830 "Host: www.google.com\r\n"
2831 "Proxy-Connection: keep-alive\r\n"
2832 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2833 };
2834
2835 // Now the proxy server lets the request pass through to origin server.
2836 // The origin server responds with a 401.
2837 MockRead data_reads2[] = {
2838 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2839 // Note: We are using the same realm-name as the proxy server. This is
2840 // completely valid, as realms are unique across hosts.
2841 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2842 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2843 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422844 MockRead(false, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:162845 };
2846
2847 // After calling trans->RestartWithAuth() the second time, we should send
2848 // the credentials for both the proxy and origin server.
2849 MockWrite data_writes3[] = {
2850 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2851 "Host: www.google.com\r\n"
2852 "Proxy-Connection: keep-alive\r\n"
2853 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
2854 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
2855 };
2856
2857 // Lastly we get the desired content.
2858 MockRead data_reads3[] = {
2859 MockRead("HTTP/1.0 200 OK\r\n"),
2860 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2861 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422862 MockRead(false, OK),
[email protected]038e9a32008-10-08 22:40:162863 };
2864
[email protected]31a2bfe2010-02-09 08:03:392865 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2866 data_writes1, arraysize(data_writes1));
2867 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2868 data_writes2, arraysize(data_writes2));
2869 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
2870 data_writes3, arraysize(data_writes3));
[email protected]5ecc992a42009-11-11 01:41:592871 session_deps.socket_factory.AddSocketDataProvider(&data1);
2872 session_deps.socket_factory.AddSocketDataProvider(&data2);
2873 session_deps.socket_factory.AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:162874
[email protected]f1f3f0f82011-10-01 20:38:102875 TestOldCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162876
[email protected]5a1d7ca2010-04-28 20:12:272877 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422878 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162879
2880 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422881 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162882
[email protected]1c773ea12009-04-28 19:58:422883 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502884 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042885 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162886
[email protected]f1f3f0f82011-10-01 20:38:102887 TestOldCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162888
[email protected]f3cf9802011-10-28 18:44:582889 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]1c773ea12009-04-28 19:58:422890 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162891
2892 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422893 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162894
2895 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502896 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042897 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162898
[email protected]f1f3f0f82011-10-01 20:38:102899 TestOldCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:162900
[email protected]f3cf9802011-10-28 18:44:582901 rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2), &callback3);
[email protected]1c773ea12009-04-28 19:58:422902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162903
2904 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422905 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162906
2907 response = trans->GetResponseInfo();
2908 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2909 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162910}
[email protected]4ddaf2502008-10-23 18:26:192911
[email protected]ea9dc9a2009-09-05 00:43:322912// For the NTLM implementation using SSPI, we skip the NTLM tests since we
2913// can't hook into its internals to cause it to generate predictable NTLM
2914// authorization headers.
2915#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:292916// The NTLM authentication unit tests were generated by capturing the HTTP
2917// requests and responses using Fiddler 2 and inspecting the generated random
2918// bytes in the debugger.
2919
2920// Enter the correct password and authenticate successfully.
2921TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:422922 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:242923 request.method = "GET";
2924 request.url = GURL("http://172.22.68.17/kids/login.aspx");
2925 request.load_flags = 0;
2926
[email protected]cb9bf6ca2011-01-28 13:15:272927 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
2928 MockGetHostName);
2929 SessionDependencies session_deps;
2930 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
2931
[email protected]3f918782009-02-28 01:29:242932 MockWrite data_writes1[] = {
2933 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
2934 "Host: 172.22.68.17\r\n"
2935 "Connection: keep-alive\r\n\r\n"),
2936 };
2937
2938 MockRead data_reads1[] = {
2939 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:042940 // Negotiate and NTLM are often requested together. However, we only want
2941 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
2942 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:242943 MockRead("WWW-Authenticate: NTLM\r\n"),
2944 MockRead("Connection: close\r\n"),
2945 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:362946 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:242947 // Missing content -- won't matter, as connection will be reset.
[email protected]1c773ea12009-04-28 19:58:422948 MockRead(false, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:242949 };
2950
2951 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:222952 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:242953 // request we should be issuing -- the final header line contains a Type
2954 // 1 message.
2955 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
2956 "Host: 172.22.68.17\r\n"
2957 "Connection: keep-alive\r\n"
2958 "Authorization: NTLM "
2959 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
2960
2961 // After calling trans->RestartWithAuth(), we should send a Type 3 message
2962 // (the credentials for the origin server). The second request continues
2963 // on the same connection.
2964 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
2965 "Host: 172.22.68.17\r\n"
2966 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:292967 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
2968 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
2969 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
2970 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
2971 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:242972 };
2973
2974 MockRead data_reads2[] = {
2975 // The origin server responds with a Type 2 message.
2976 MockRead("HTTP/1.1 401 Access Denied\r\n"),
2977 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:292978 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:242979 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
2980 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
2981 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
2982 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
2983 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
2984 "BtAAAAAAA=\r\n"),
2985 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:362986 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:242987 MockRead("You are not authorized to view this page\r\n"),
2988
2989 // Lastly we get the desired content.
2990 MockRead("HTTP/1.1 200 OK\r\n"),
2991 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
2992 MockRead("Content-Length: 13\r\n\r\n"),
2993 MockRead("Please Login\r\n"),
[email protected]1c773ea12009-04-28 19:58:422994 MockRead(false, OK),
[email protected]3f918782009-02-28 01:29:242995 };
2996
[email protected]31a2bfe2010-02-09 08:03:392997 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2998 data_writes1, arraysize(data_writes1));
2999 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3000 data_writes2, arraysize(data_writes2));
[email protected]5ecc992a42009-11-11 01:41:593001 session_deps.socket_factory.AddSocketDataProvider(&data1);
3002 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:243003
[email protected]f1f3f0f82011-10-01 20:38:103004 TestOldCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:243005
[email protected]0b0bf032010-09-21 18:08:503006 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3007
[email protected]5a1d7ca2010-04-28 20:12:273008 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423009 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243010
3011 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423012 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243013
[email protected]0757e7702009-03-27 04:00:223014 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3015
[email protected]1c773ea12009-04-28 19:58:423016 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043017 ASSERT_FALSE(response == NULL);
3018 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:243019
[email protected]f1f3f0f82011-10-01 20:38:103020 TestOldCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:253021
[email protected]f3cf9802011-10-28 18:44:583022 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
3023 &callback2);
[email protected]10af5fe72011-01-31 16:17:253024 EXPECT_EQ(ERR_IO_PENDING, rv);
3025
3026 rv = callback2.WaitForResult();
3027 EXPECT_EQ(OK, rv);
3028
3029 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3030
3031 response = trans->GetResponseInfo();
3032 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:253033 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3034
[email protected]f1f3f0f82011-10-01 20:38:103035 TestOldCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:243036
[email protected]f3cf9802011-10-28 18:44:583037 rv = trans->RestartWithAuth(AuthCredentials(), &callback3);
[email protected]1c773ea12009-04-28 19:58:423038 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243039
[email protected]0757e7702009-03-27 04:00:223040 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423041 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243042
3043 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503044 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:243045 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3046 EXPECT_EQ(13, response->headers->GetContentLength());
3047}
3048
[email protected]385a4672009-03-11 22:21:293049// Enter a wrong password, and then the correct one.
3050TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:423051 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:293052 request.method = "GET";
3053 request.url = GURL("http://172.22.68.17/kids/login.aspx");
3054 request.load_flags = 0;
3055
[email protected]cb9bf6ca2011-01-28 13:15:273056 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
3057 MockGetHostName);
3058 SessionDependencies session_deps;
3059 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
3060
[email protected]385a4672009-03-11 22:21:293061 MockWrite data_writes1[] = {
3062 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3063 "Host: 172.22.68.17\r\n"
3064 "Connection: keep-alive\r\n\r\n"),
3065 };
3066
3067 MockRead data_reads1[] = {
3068 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043069 // Negotiate and NTLM are often requested together. However, we only want
3070 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3071 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:293072 MockRead("WWW-Authenticate: NTLM\r\n"),
3073 MockRead("Connection: close\r\n"),
3074 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363075 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:293076 // Missing content -- won't matter, as connection will be reset.
[email protected]1c773ea12009-04-28 19:58:423077 MockRead(false, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:293078 };
3079
3080 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:223081 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:293082 // request we should be issuing -- the final header line contains a Type
3083 // 1 message.
3084 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3085 "Host: 172.22.68.17\r\n"
3086 "Connection: keep-alive\r\n"
3087 "Authorization: NTLM "
3088 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3089
3090 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3091 // (the credentials for the origin server). The second request continues
3092 // on the same connection.
3093 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3094 "Host: 172.22.68.17\r\n"
3095 "Connection: keep-alive\r\n"
3096 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3097 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3098 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
3099 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
3100 "4Ww7b7E=\r\n\r\n"),
3101 };
3102
3103 MockRead data_reads2[] = {
3104 // The origin server responds with a Type 2 message.
3105 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3106 MockRead("WWW-Authenticate: NTLM "
3107 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
3108 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3109 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3110 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3111 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3112 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3113 "BtAAAAAAA=\r\n"),
3114 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363115 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:293116 MockRead("You are not authorized to view this page\r\n"),
3117
3118 // Wrong password.
3119 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:293120 MockRead("WWW-Authenticate: NTLM\r\n"),
3121 MockRead("Connection: close\r\n"),
3122 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363123 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:293124 // Missing content -- won't matter, as connection will be reset.
[email protected]1c773ea12009-04-28 19:58:423125 MockRead(false, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:293126 };
3127
3128 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:223129 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:293130 // request we should be issuing -- the final header line contains a Type
3131 // 1 message.
3132 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3133 "Host: 172.22.68.17\r\n"
3134 "Connection: keep-alive\r\n"
3135 "Authorization: NTLM "
3136 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3137
3138 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3139 // (the credentials for the origin server). The second request continues
3140 // on the same connection.
3141 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3142 "Host: 172.22.68.17\r\n"
3143 "Connection: keep-alive\r\n"
3144 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3145 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3146 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
3147 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
3148 "+4MUm7c=\r\n\r\n"),
3149 };
3150
3151 MockRead data_reads3[] = {
3152 // The origin server responds with a Type 2 message.
3153 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3154 MockRead("WWW-Authenticate: NTLM "
3155 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
3156 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3157 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3158 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3159 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3160 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3161 "BtAAAAAAA=\r\n"),
3162 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363163 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:293164 MockRead("You are not authorized to view this page\r\n"),
3165
3166 // Lastly we get the desired content.
3167 MockRead("HTTP/1.1 200 OK\r\n"),
3168 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3169 MockRead("Content-Length: 13\r\n\r\n"),
3170 MockRead("Please Login\r\n"),
[email protected]1c773ea12009-04-28 19:58:423171 MockRead(false, OK),
[email protected]385a4672009-03-11 22:21:293172 };
3173
[email protected]31a2bfe2010-02-09 08:03:393174 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3175 data_writes1, arraysize(data_writes1));
3176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3177 data_writes2, arraysize(data_writes2));
3178 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3179 data_writes3, arraysize(data_writes3));
[email protected]5ecc992a42009-11-11 01:41:593180 session_deps.socket_factory.AddSocketDataProvider(&data1);
3181 session_deps.socket_factory.AddSocketDataProvider(&data2);
3182 session_deps.socket_factory.AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:293183
[email protected]f1f3f0f82011-10-01 20:38:103184 TestOldCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:293185
[email protected]0b0bf032010-09-21 18:08:503186 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3187
[email protected]5a1d7ca2010-04-28 20:12:273188 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423189 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:293190
3191 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423192 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:293193
[email protected]0757e7702009-03-27 04:00:223194 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:293195
[email protected]1c773ea12009-04-28 19:58:423196 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503197 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043198 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:293199
[email protected]f1f3f0f82011-10-01 20:38:103200 TestOldCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:293201
[email protected]0757e7702009-03-27 04:00:223202 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:583203 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
3204 &callback2);
[email protected]1c773ea12009-04-28 19:58:423205 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:293206
[email protected]10af5fe72011-01-31 16:17:253207 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423208 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:293209
[email protected]0757e7702009-03-27 04:00:223210 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]f1f3f0f82011-10-01 20:38:103211 TestOldCompletionCallback callback3;
[email protected]f3cf9802011-10-28 18:44:583212 rv = trans->RestartWithAuth(AuthCredentials(), &callback3);
[email protected]1c773ea12009-04-28 19:58:423213 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:253214 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423215 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:223216 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3217
3218 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043219 ASSERT_FALSE(response == NULL);
3220 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:223221
[email protected]f1f3f0f82011-10-01 20:38:103222 TestOldCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:223223
3224 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:583225 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
3226 &callback4);
[email protected]10af5fe72011-01-31 16:17:253227 EXPECT_EQ(ERR_IO_PENDING, rv);
3228
3229 rv = callback4.WaitForResult();
3230 EXPECT_EQ(OK, rv);
3231
3232 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3233
[email protected]f1f3f0f82011-10-01 20:38:103234 TestOldCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:253235
3236 // One more roundtrip
[email protected]f3cf9802011-10-28 18:44:583237 rv = trans->RestartWithAuth(AuthCredentials(), &callback5);
[email protected]1c773ea12009-04-28 19:58:423238 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:223239
3240 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423241 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:223242
[email protected]385a4672009-03-11 22:21:293243 response = trans->GetResponseInfo();
3244 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3245 EXPECT_EQ(13, response->headers->GetContentLength());
3246}
[email protected]ea9dc9a2009-09-05 00:43:323247#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:293248
[email protected]4ddaf2502008-10-23 18:26:193249// Test reading a server response which has only headers, and no body.
3250// After some maximum number of bytes is consumed, the transaction should
3251// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
3252TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:423253 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:193254 request.method = "GET";
3255 request.url = GURL("http://www.google.com/");
3256 request.load_flags = 0;
3257
[email protected]cb9bf6ca2011-01-28 13:15:273258 SessionDependencies session_deps;
3259 scoped_ptr<HttpTransaction> trans(
3260 new HttpNetworkTransaction(CreateSession(&session_deps)));
3261
[email protected]b75b7b2f2009-10-06 00:54:533262 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:433263 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:533264 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:193265
3266 MockRead data_reads[] = {
3267 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]15a5ccf82008-10-23 19:57:433268 MockRead(true, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:193269 MockRead("\r\nBODY"),
[email protected]1c773ea12009-04-28 19:58:423270 MockRead(false, OK),
[email protected]4ddaf2502008-10-23 18:26:193271 };
[email protected]31a2bfe2010-02-09 08:03:393272 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:593273 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:193274
[email protected]f1f3f0f82011-10-01 20:38:103275 TestOldCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:193276
[email protected]5a1d7ca2010-04-28 20:12:273277 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423278 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:193279
3280 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423281 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:193282
[email protected]1c773ea12009-04-28 19:58:423283 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:193284 EXPECT_TRUE(response == NULL);
3285}
[email protected]f4e426b2008-11-05 00:24:493286
3287// Make sure that we don't try to reuse a TCPClientSocket when failing to
3288// establish tunnel.
3289// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]ab739042011-04-07 15:22:283290TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273291 HttpRequestInfo request;
3292 request.method = "GET";
3293 request.url = GURL("https://www.google.com/");
3294 request.load_flags = 0;
3295
[email protected]f4e426b2008-11-05 00:24:493296 // Configure against proxy server "myproxy:70".
[email protected]81cdfcd2010-10-16 00:49:003297 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:013298
[email protected]228ff742009-06-05 01:19:593299 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]f4e426b2008-11-05 00:24:493300
[email protected]5695b8c2009-09-30 21:36:433301 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]f4e426b2008-11-05 00:24:493302
[email protected]f4e426b2008-11-05 00:24:493303 // Since we have proxy, should try to establish tunnel.
3304 MockWrite data_writes1[] = {
3305 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453306 "Host: www.google.com\r\n"
3307 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:493308 };
3309
[email protected]77848d12008-11-14 00:00:223310 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:493311 // connection. Usually a proxy would return 501 (not implemented),
3312 // or 200 (tunnel established).
3313 MockRead data_reads1[] = {
3314 MockRead("HTTP/1.1 404 Not Found\r\n"),
3315 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:423316 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:493317 };
3318
[email protected]31a2bfe2010-02-09 08:03:393319 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3320 data_writes1, arraysize(data_writes1));
[email protected]5ecc992a42009-11-11 01:41:593321 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:493322
[email protected]f1f3f0f82011-10-01 20:38:103323 TestOldCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:493324
[email protected]5a1d7ca2010-04-28 20:12:273325 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423326 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:493327
3328 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423329 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:493330
[email protected]1c773ea12009-04-28 19:58:423331 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:083332 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:493333
[email protected]b4404c02009-04-10 16:38:523334 // Empty the current queue. This is necessary because idle sockets are
3335 // added to the connection pool asynchronously with a PostTask.
3336 MessageLoop::current()->RunAllPending();
3337
[email protected]f4e426b2008-11-05 00:24:493338 // We now check to make sure the TCPClientSocket was not added back to
3339 // the pool.
[email protected]a42dbd142011-11-17 16:42:023340 EXPECT_EQ(0, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]f4e426b2008-11-05 00:24:493341 trans.reset();
[email protected]b4404c02009-04-10 16:38:523342 MessageLoop::current()->RunAllPending();
[email protected]f4e426b2008-11-05 00:24:493343 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]a42dbd142011-11-17 16:42:023344 EXPECT_EQ(0, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]f4e426b2008-11-05 00:24:493345}
[email protected]372d34a2008-11-05 21:30:513346
[email protected]1b157c02009-04-21 01:55:403347// Make sure that we recycle a socket after reading all of the response body.
3348TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:423349 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:403350 request.method = "GET";
3351 request.url = GURL("http://www.google.com/");
3352 request.load_flags = 0;
3353
[email protected]cb9bf6ca2011-01-28 13:15:273354 SessionDependencies session_deps;
3355 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
3356
3357 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3358
[email protected]1b157c02009-04-21 01:55:403359 MockRead data_reads[] = {
3360 // A part of the response body is received with the response headers.
3361 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
3362 // The rest of the response body is received in two parts.
3363 MockRead("lo"),
3364 MockRead(" world"),
3365 MockRead("junk"), // Should not be read!!
[email protected]1c773ea12009-04-28 19:58:423366 MockRead(false, OK),
[email protected]1b157c02009-04-21 01:55:403367 };
3368
[email protected]31a2bfe2010-02-09 08:03:393369 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:593370 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:403371
[email protected]f1f3f0f82011-10-01 20:38:103372 TestOldCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:403373
[email protected]5a1d7ca2010-04-28 20:12:273374 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423375 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:403376
3377 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423378 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:403379
[email protected]1c773ea12009-04-28 19:58:423380 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503381 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:403382
3383 EXPECT_TRUE(response->headers != NULL);
3384 std::string status_line = response->headers->GetStatusLine();
3385 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
3386
[email protected]a42dbd142011-11-17 16:42:023387 EXPECT_EQ(0, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]1b157c02009-04-21 01:55:403388
3389 std::string response_data;
3390 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423391 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:403392 EXPECT_EQ("hello world", response_data);
3393
3394 // Empty the current queue. This is necessary because idle sockets are
3395 // added to the connection pool asynchronously with a PostTask.
3396 MessageLoop::current()->RunAllPending();
3397
3398 // We now check to make sure the socket was added back to the pool.
[email protected]a42dbd142011-11-17 16:42:023399 EXPECT_EQ(1, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]1b157c02009-04-21 01:55:403400}
3401
[email protected]76a505b2010-08-25 06:23:003402// Make sure that we recycle a SSL socket after reading all of the response
3403// body.
3404TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
3405 SessionDependencies session_deps;
3406 HttpRequestInfo request;
3407 request.method = "GET";
3408 request.url = GURL("https://www.google.com/");
3409 request.load_flags = 0;
3410
3411 MockWrite data_writes[] = {
3412 MockWrite("GET / HTTP/1.1\r\n"
3413 "Host: www.google.com\r\n"
3414 "Connection: keep-alive\r\n\r\n"),
3415 };
3416
3417 MockRead data_reads[] = {
3418 MockRead("HTTP/1.1 200 OK\r\n"),
3419 MockRead("Content-Length: 11\r\n\r\n"),
3420 MockRead("hello world"),
3421 MockRead(false, OK),
3422 };
3423
3424 SSLSocketDataProvider ssl(true, OK);
3425 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
3426
3427 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3428 data_writes, arraysize(data_writes));
3429 session_deps.socket_factory.AddSocketDataProvider(&data);
3430
[email protected]f1f3f0f82011-10-01 20:38:103431 TestOldCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:003432
3433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
3434 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3435
3436 int rv = trans->Start(&request, &callback, BoundNetLog());
3437
3438 EXPECT_EQ(ERR_IO_PENDING, rv);
3439 EXPECT_EQ(OK, callback.WaitForResult());
3440
3441 const HttpResponseInfo* response = trans->GetResponseInfo();
3442 ASSERT_TRUE(response != NULL);
3443 ASSERT_TRUE(response->headers != NULL);
3444 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3445
[email protected]a42dbd142011-11-17 16:42:023446 EXPECT_EQ(0, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]76a505b2010-08-25 06:23:003447
3448 std::string response_data;
3449 rv = ReadTransaction(trans.get(), &response_data);
3450 EXPECT_EQ(OK, rv);
3451 EXPECT_EQ("hello world", response_data);
3452
3453 // Empty the current queue. This is necessary because idle sockets are
3454 // added to the connection pool asynchronously with a PostTask.
3455 MessageLoop::current()->RunAllPending();
3456
3457 // We now check to make sure the socket was added back to the pool.
[email protected]a42dbd142011-11-17 16:42:023458 EXPECT_EQ(1, session->GetSSLSocketPool()->IdleSocketCount());
[email protected]76a505b2010-08-25 06:23:003459}
3460
3461// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
3462// from the pool and make sure that we recover okay.
3463TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
3464 SessionDependencies session_deps;
3465 HttpRequestInfo request;
3466 request.method = "GET";
3467 request.url = GURL("https://www.google.com/");
3468 request.load_flags = 0;
3469
3470 MockWrite data_writes[] = {
3471 MockWrite("GET / HTTP/1.1\r\n"
3472 "Host: www.google.com\r\n"
3473 "Connection: keep-alive\r\n\r\n"),
3474 MockWrite("GET / HTTP/1.1\r\n"
3475 "Host: www.google.com\r\n"
3476 "Connection: keep-alive\r\n\r\n"),
3477 };
3478
3479 MockRead data_reads[] = {
3480 MockRead("HTTP/1.1 200 OK\r\n"),
3481 MockRead("Content-Length: 11\r\n\r\n"),
3482 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3483 MockRead("hello world"),
3484 MockRead(true, 0, 0) // EOF
3485 };
3486
3487 SSLSocketDataProvider ssl(true, OK);
3488 SSLSocketDataProvider ssl2(true, OK);
3489 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
3490 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
3491
3492 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3493 data_writes, arraysize(data_writes));
3494 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
3495 data_writes, arraysize(data_writes));
3496 session_deps.socket_factory.AddSocketDataProvider(&data);
3497 session_deps.socket_factory.AddSocketDataProvider(&data2);
3498
[email protected]f1f3f0f82011-10-01 20:38:103499 TestOldCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:003500
3501 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
3502 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3503
3504 int rv = trans->Start(&request, &callback, BoundNetLog());
3505
3506 EXPECT_EQ(ERR_IO_PENDING, rv);
3507 EXPECT_EQ(OK, callback.WaitForResult());
3508
3509 const HttpResponseInfo* response = trans->GetResponseInfo();
3510 ASSERT_TRUE(response != NULL);
3511 ASSERT_TRUE(response->headers != NULL);
3512 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3513
[email protected]a42dbd142011-11-17 16:42:023514 EXPECT_EQ(0, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]76a505b2010-08-25 06:23:003515
3516 std::string response_data;
3517 rv = ReadTransaction(trans.get(), &response_data);
3518 EXPECT_EQ(OK, rv);
3519 EXPECT_EQ("hello world", response_data);
3520
3521 // Empty the current queue. This is necessary because idle sockets are
3522 // added to the connection pool asynchronously with a PostTask.
3523 MessageLoop::current()->RunAllPending();
3524
3525 // We now check to make sure the socket was added back to the pool.
[email protected]a42dbd142011-11-17 16:42:023526 EXPECT_EQ(1, session->GetSSLSocketPool()->IdleSocketCount());
[email protected]76a505b2010-08-25 06:23:003527
3528 // Now start the second transaction, which should reuse the previous socket.
3529
3530 trans.reset(new HttpNetworkTransaction(session));
3531
3532 rv = trans->Start(&request, &callback, BoundNetLog());
3533
3534 EXPECT_EQ(ERR_IO_PENDING, rv);
3535 EXPECT_EQ(OK, callback.WaitForResult());
3536
3537 response = trans->GetResponseInfo();
3538 ASSERT_TRUE(response != NULL);
3539 ASSERT_TRUE(response->headers != NULL);
3540 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3541
[email protected]a42dbd142011-11-17 16:42:023542 EXPECT_EQ(0, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]76a505b2010-08-25 06:23:003543
3544 rv = ReadTransaction(trans.get(), &response_data);
3545 EXPECT_EQ(OK, rv);
3546 EXPECT_EQ("hello world", response_data);
3547
3548 // Empty the current queue. This is necessary because idle sockets are
3549 // added to the connection pool asynchronously with a PostTask.
3550 MessageLoop::current()->RunAllPending();
3551
3552 // We now check to make sure the socket was added back to the pool.
[email protected]a42dbd142011-11-17 16:42:023553 EXPECT_EQ(1, session->GetSSLSocketPool()->IdleSocketCount());
[email protected]76a505b2010-08-25 06:23:003554}
3555
[email protected]b4404c02009-04-10 16:38:523556// Make sure that we recycle a socket after a zero-length response.
3557// http://crbug.com/9880
3558TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:423559 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:523560 request.method = "GET";
3561 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
3562 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
3563 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
3564 "rt=prt.2642,ol.2649,xjs.2951");
3565 request.load_flags = 0;
3566
[email protected]cb9bf6ca2011-01-28 13:15:273567 SessionDependencies session_deps;
3568 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
3569
3570 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3571
[email protected]b4404c02009-04-10 16:38:523572 MockRead data_reads[] = {
3573 MockRead("HTTP/1.1 204 No Content\r\n"
3574 "Content-Length: 0\r\n"
3575 "Content-Type: text/html\r\n\r\n"),
3576 MockRead("junk"), // Should not be read!!
[email protected]1c773ea12009-04-28 19:58:423577 MockRead(false, OK),
[email protected]b4404c02009-04-10 16:38:523578 };
3579
[email protected]31a2bfe2010-02-09 08:03:393580 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:593581 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:523582
[email protected]f1f3f0f82011-10-01 20:38:103583 TestOldCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:523584
[email protected]5a1d7ca2010-04-28 20:12:273585 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423586 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:523587
3588 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423589 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:523590
[email protected]1c773ea12009-04-28 19:58:423591 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503592 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:523593
3594 EXPECT_TRUE(response->headers != NULL);
3595 std::string status_line = response->headers->GetStatusLine();
3596 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
3597
[email protected]a42dbd142011-11-17 16:42:023598 EXPECT_EQ(0, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]b4404c02009-04-10 16:38:523599
3600 std::string response_data;
3601 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423602 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:523603 EXPECT_EQ("", response_data);
3604
3605 // Empty the current queue. This is necessary because idle sockets are
3606 // added to the connection pool asynchronously with a PostTask.
3607 MessageLoop::current()->RunAllPending();
3608
3609 // We now check to make sure the socket was added back to the pool.
[email protected]a42dbd142011-11-17 16:42:023610 EXPECT_EQ(1, session->GetTransportSocketPool()->IdleSocketCount());
[email protected]b4404c02009-04-10 16:38:523611}
3612
[email protected]372d34a2008-11-05 21:30:513613TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]1c773ea12009-04-28 19:58:423614 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:513615 // Transaction 1: a GET request that succeeds. The socket is recycled
3616 // after use.
3617 request[0].method = "GET";
3618 request[0].url = GURL("http://www.google.com/");
3619 request[0].load_flags = 0;
3620 // Transaction 2: a POST request. Reuses the socket kept alive from
3621 // transaction 1. The first attempts fails when writing the POST data.
3622 // This causes the transaction to retry with a new socket. The second
3623 // attempt succeeds.
3624 request[1].method = "POST";
3625 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]1c773ea12009-04-28 19:58:423626 request[1].upload_data = new UploadData;
[email protected]372d34a2008-11-05 21:30:513627 request[1].upload_data->AppendBytes("foo", 3);
3628 request[1].load_flags = 0;
3629
[email protected]228ff742009-06-05 01:19:593630 SessionDependencies session_deps;
[email protected]ad8e04a2010-11-01 04:16:273631 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]372d34a2008-11-05 21:30:513632
3633 // The first socket is used for transaction 1 and the first attempt of
3634 // transaction 2.
3635
3636 // The response of transaction 1.
3637 MockRead data_reads1[] = {
3638 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
3639 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:423640 MockRead(false, OK),
[email protected]372d34a2008-11-05 21:30:513641 };
3642 // The mock write results of transaction 1 and the first attempt of
3643 // transaction 2.
3644 MockWrite data_writes1[] = {
3645 MockWrite(false, 64), // GET
3646 MockWrite(false, 93), // POST
[email protected]1c773ea12009-04-28 19:58:423647 MockWrite(false, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:513648 };
[email protected]31a2bfe2010-02-09 08:03:393649 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3650 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:513651
3652 // The second socket is used for the second attempt of transaction 2.
3653
3654 // The response of transaction 2.
3655 MockRead data_reads2[] = {
3656 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
3657 MockRead("welcome"),
[email protected]1c773ea12009-04-28 19:58:423658 MockRead(false, OK),
[email protected]372d34a2008-11-05 21:30:513659 };
3660 // The mock write results of the second attempt of transaction 2.
3661 MockWrite data_writes2[] = {
3662 MockWrite(false, 93), // POST
3663 MockWrite(false, 3), // POST data
3664 };
[email protected]31a2bfe2010-02-09 08:03:393665 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3666 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:513667
[email protected]5ecc992a42009-11-11 01:41:593668 session_deps.socket_factory.AddSocketDataProvider(&data1);
3669 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:513670
3671 const char* kExpectedResponseData[] = {
3672 "hello world", "welcome"
3673 };
3674
3675 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:423676 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:433677 new HttpNetworkTransaction(session));
[email protected]372d34a2008-11-05 21:30:513678
[email protected]f1f3f0f82011-10-01 20:38:103679 TestOldCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:513680
[email protected]5a1d7ca2010-04-28 20:12:273681 int rv = trans->Start(&request[i], &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423682 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:513683
3684 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423685 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:513686
[email protected]1c773ea12009-04-28 19:58:423687 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503688 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:513689
3690 EXPECT_TRUE(response->headers != NULL);
3691 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3692
3693 std::string response_data;
3694 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423695 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:513696 EXPECT_EQ(kExpectedResponseData[i], response_data);
3697 }
3698}
[email protected]f9ee6b52008-11-08 06:46:233699
3700// Test the request-challenge-retry sequence for basic auth when there is
3701// an identity in the URL. The request should be sent as normal, but when
3702// it fails the identity from the URL is used to answer the challenge.
[email protected]ea9dc9a2009-09-05 00:43:323703TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:423704 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:233705 request.method = "GET";
3706 // Note: the URL has a username:password in it.
[email protected]a97cca42009-08-14 01:00:293707 request.url = GURL("http://foo:b@[email protected]/");
3708
[email protected]cb9bf6ca2011-01-28 13:15:273709 SessionDependencies session_deps;
3710 scoped_ptr<HttpTransaction> trans(
3711 new HttpNetworkTransaction(CreateSession(&session_deps)));
3712
[email protected]a97cca42009-08-14 01:00:293713 // The password contains an escaped character -- for this test to pass it
3714 // will need to be unescaped by HttpNetworkTransaction.
3715 EXPECT_EQ("b%40r", request.url.password());
3716
[email protected]ea9dc9a2009-09-05 00:43:323717 request.load_flags = LOAD_NORMAL;
[email protected]f9ee6b52008-11-08 06:46:233718
3719 MockWrite data_writes1[] = {
3720 MockWrite("GET / HTTP/1.1\r\n"
3721 "Host: www.google.com\r\n"
3722 "Connection: keep-alive\r\n\r\n"),
3723 };
3724
3725 MockRead data_reads1[] = {
3726 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3727 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3728 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:423729 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:233730 };
3731
3732 // After the challenge above, the transaction will be restarted using the
[email protected]ea9dc9a2009-09-05 00:43:323733 // identity from the url (foo, b@r) to answer the challenge.
[email protected]f9ee6b52008-11-08 06:46:233734 MockWrite data_writes2[] = {
3735 MockWrite("GET / HTTP/1.1\r\n"
3736 "Host: www.google.com\r\n"
3737 "Connection: keep-alive\r\n"
[email protected]a97cca42009-08-14 01:00:293738 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:233739 };
3740
3741 MockRead data_reads2[] = {
3742 MockRead("HTTP/1.0 200 OK\r\n"),
3743 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:423744 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:233745 };
3746
[email protected]31a2bfe2010-02-09 08:03:393747 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3748 data_writes1, arraysize(data_writes1));
3749 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3750 data_writes2, arraysize(data_writes2));
[email protected]5ecc992a42009-11-11 01:41:593751 session_deps.socket_factory.AddSocketDataProvider(&data1);
3752 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:233753
[email protected]f1f3f0f82011-10-01 20:38:103754 TestOldCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:233755
[email protected]5a1d7ca2010-04-28 20:12:273756 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423757 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:233758
3759 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423760 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:233761
[email protected]0757e7702009-03-27 04:00:223762 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]f1f3f0f82011-10-01 20:38:103763 TestOldCompletionCallback callback2;
[email protected]f3cf9802011-10-28 18:44:583764 rv = trans->RestartWithAuth(AuthCredentials(), &callback2);
[email protected]1c773ea12009-04-28 19:58:423765 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:223766 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423767 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:223768 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3769
[email protected]1c773ea12009-04-28 19:58:423770 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503771 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:233772
3773 // There is no challenge info, since the identity in URL worked.
3774 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3775
3776 EXPECT_EQ(100, response->headers->GetContentLength());
3777
3778 // Empty the current queue.
3779 MessageLoop::current()->RunAllPending();
3780}
3781
[email protected]ea9dc9a2009-09-05 00:43:323782// Test the request-challenge-retry sequence for basic auth when there is
3783// an incorrect identity in the URL. The identity from the URL should be used
3784// only once.
3785TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]ea9dc9a2009-09-05 00:43:323786 HttpRequestInfo request;
3787 request.method = "GET";
3788 // Note: the URL has a username:password in it. The password "baz" is
3789 // wrong (should be "bar").
3790 request.url = GURL("http://foo:[email protected]/");
3791
3792 request.load_flags = LOAD_NORMAL;
3793
[email protected]cb9bf6ca2011-01-28 13:15:273794 SessionDependencies session_deps;
3795 scoped_ptr<HttpTransaction> trans(
3796 new HttpNetworkTransaction(CreateSession(&session_deps)));
3797
[email protected]ea9dc9a2009-09-05 00:43:323798 MockWrite data_writes1[] = {
3799 MockWrite("GET / HTTP/1.1\r\n"
3800 "Host: www.google.com\r\n"
3801 "Connection: keep-alive\r\n\r\n"),
3802 };
3803
3804 MockRead data_reads1[] = {
3805 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3806 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3807 MockRead("Content-Length: 10\r\n\r\n"),
3808 MockRead(false, ERR_FAILED),
3809 };
3810
3811 // After the challenge above, the transaction will be restarted using the
3812 // identity from the url (foo, baz) to answer the challenge.
3813 MockWrite data_writes2[] = {
3814 MockWrite("GET / HTTP/1.1\r\n"
3815 "Host: www.google.com\r\n"
3816 "Connection: keep-alive\r\n"
3817 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3818 };
3819
3820 MockRead data_reads2[] = {
3821 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3822 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3823 MockRead("Content-Length: 10\r\n\r\n"),
3824 MockRead(false, ERR_FAILED),
3825 };
3826
3827 // After the challenge above, the transaction will be restarted using the
3828 // identity supplied by the user (foo, bar) to answer the challenge.
3829 MockWrite data_writes3[] = {
3830 MockWrite("GET / HTTP/1.1\r\n"
3831 "Host: www.google.com\r\n"
3832 "Connection: keep-alive\r\n"
3833 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3834 };
3835
3836 MockRead data_reads3[] = {
3837 MockRead("HTTP/1.0 200 OK\r\n"),
3838 MockRead("Content-Length: 100\r\n\r\n"),
3839 MockRead(false, OK),
3840 };
3841
[email protected]31a2bfe2010-02-09 08:03:393842 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3843 data_writes1, arraysize(data_writes1));
3844 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3845 data_writes2, arraysize(data_writes2));
3846 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3847 data_writes3, arraysize(data_writes3));
[email protected]5ecc992a42009-11-11 01:41:593848 session_deps.socket_factory.AddSocketDataProvider(&data1);
3849 session_deps.socket_factory.AddSocketDataProvider(&data2);
3850 session_deps.socket_factory.AddSocketDataProvider(&data3);
[email protected]ea9dc9a2009-09-05 00:43:323851
[email protected]f1f3f0f82011-10-01 20:38:103852 TestOldCompletionCallback callback1;
[email protected]ea9dc9a2009-09-05 00:43:323853
[email protected]5a1d7ca2010-04-28 20:12:273854 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]ea9dc9a2009-09-05 00:43:323855 EXPECT_EQ(ERR_IO_PENDING, rv);
3856
3857 rv = callback1.WaitForResult();
3858 EXPECT_EQ(OK, rv);
3859
3860 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]f1f3f0f82011-10-01 20:38:103861 TestOldCompletionCallback callback2;
[email protected]f3cf9802011-10-28 18:44:583862 rv = trans->RestartWithAuth(AuthCredentials(), &callback2);
[email protected]ea9dc9a2009-09-05 00:43:323863 EXPECT_EQ(ERR_IO_PENDING, rv);
3864 rv = callback2.WaitForResult();
3865 EXPECT_EQ(OK, rv);
3866 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3867
3868 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503869 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043870 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]ea9dc9a2009-09-05 00:43:323871
[email protected]f1f3f0f82011-10-01 20:38:103872 TestOldCompletionCallback callback3;
[email protected]f3cf9802011-10-28 18:44:583873 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback3);
[email protected]ea9dc9a2009-09-05 00:43:323874 EXPECT_EQ(ERR_IO_PENDING, rv);
3875 rv = callback3.WaitForResult();
3876 EXPECT_EQ(OK, rv);
3877 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3878
3879 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503880 ASSERT_TRUE(response != NULL);
[email protected]ea9dc9a2009-09-05 00:43:323881
3882 // There is no challenge info, since the identity worked.
3883 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3884
3885 EXPECT_EQ(100, response->headers->GetContentLength());
3886
3887 // Empty the current queue.
3888 MessageLoop::current()->RunAllPending();
3889}
3890
[email protected]f9ee6b52008-11-08 06:46:233891// Test that previously tried username/passwords for a realm get re-used.
3892TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]228ff742009-06-05 01:19:593893 SessionDependencies session_deps;
[email protected]ad8e04a2010-11-01 04:16:273894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]f9ee6b52008-11-08 06:46:233895
3896 // Transaction 1: authenticate (foo, bar) on MyRealm1
3897 {
[email protected]1c773ea12009-04-28 19:58:423898 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:233899 request.method = "GET";
3900 request.url = GURL("http://www.google.com/x/y/z");
3901 request.load_flags = 0;
3902
[email protected]cb9bf6ca2011-01-28 13:15:273903 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3904
[email protected]f9ee6b52008-11-08 06:46:233905 MockWrite data_writes1[] = {
3906 MockWrite("GET /x/y/z HTTP/1.1\r\n"
3907 "Host: www.google.com\r\n"
3908 "Connection: keep-alive\r\n\r\n"),
3909 };
3910
3911 MockRead data_reads1[] = {
3912 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3913 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3914 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:423915 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:233916 };
3917
3918 // Resend with authorization (username=foo, password=bar)
3919 MockWrite data_writes2[] = {
3920 MockWrite("GET /x/y/z HTTP/1.1\r\n"
3921 "Host: www.google.com\r\n"
3922 "Connection: keep-alive\r\n"
3923 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3924 };
3925
3926 // Sever accepts the authorization.
3927 MockRead data_reads2[] = {
3928 MockRead("HTTP/1.0 200 OK\r\n"),
3929 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:423930 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:233931 };
3932
[email protected]31a2bfe2010-02-09 08:03:393933 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3934 data_writes1, arraysize(data_writes1));
3935 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3936 data_writes2, arraysize(data_writes2));
[email protected]5ecc992a42009-11-11 01:41:593937 session_deps.socket_factory.AddSocketDataProvider(&data1);
3938 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:233939
[email protected]f1f3f0f82011-10-01 20:38:103940 TestOldCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:233941
[email protected]5a1d7ca2010-04-28 20:12:273942 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423943 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:233944
3945 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423946 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:233947
[email protected]1c773ea12009-04-28 19:58:423948 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503949 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043950 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:233951
[email protected]f1f3f0f82011-10-01 20:38:103952 TestOldCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:233953
[email protected]f3cf9802011-10-28 18:44:583954 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]1c773ea12009-04-28 19:58:423955 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:233956
3957 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423958 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:233959
3960 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503961 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:233962 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3963 EXPECT_EQ(100, response->headers->GetContentLength());
3964 }
3965
3966 // ------------------------------------------------------------------------
3967
3968 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
3969 {
[email protected]1c773ea12009-04-28 19:58:423970 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:233971 request.method = "GET";
3972 // Note that Transaction 1 was at /x/y/z, so this is in the same
3973 // protection space as MyRealm1.
3974 request.url = GURL("http://www.google.com/x/y/a/b");
3975 request.load_flags = 0;
3976
[email protected]cb9bf6ca2011-01-28 13:15:273977 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
3978
[email protected]f9ee6b52008-11-08 06:46:233979 MockWrite data_writes1[] = {
3980 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
3981 "Host: www.google.com\r\n"
3982 "Connection: keep-alive\r\n"
3983 // Send preemptive authorization for MyRealm1
3984 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3985 };
3986
3987 // The server didn't like the preemptive authorization, and
3988 // challenges us for a different realm (MyRealm2).
3989 MockRead data_reads1[] = {
3990 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3991 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
3992 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:423993 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:233994 };
3995
3996 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
3997 MockWrite data_writes2[] = {
3998 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
3999 "Host: www.google.com\r\n"
4000 "Connection: keep-alive\r\n"
4001 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4002 };
4003
4004 // Sever accepts the authorization.
4005 MockRead data_reads2[] = {
4006 MockRead("HTTP/1.0 200 OK\r\n"),
4007 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424008 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:234009 };
4010
[email protected]31a2bfe2010-02-09 08:03:394011 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4012 data_writes1, arraysize(data_writes1));
4013 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4014 data_writes2, arraysize(data_writes2));
[email protected]5ecc992a42009-11-11 01:41:594015 session_deps.socket_factory.AddSocketDataProvider(&data1);
4016 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234017
[email protected]f1f3f0f82011-10-01 20:38:104018 TestOldCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234019
[email protected]5a1d7ca2010-04-28 20:12:274020 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424021 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234022
4023 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424024 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234025
[email protected]1c773ea12009-04-28 19:58:424026 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504027 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044028 ASSERT_TRUE(response->auth_challenge.get());
4029 EXPECT_FALSE(response->auth_challenge->is_proxy);
4030 EXPECT_EQ("www.google.com:80",
4031 response->auth_challenge->challenger.ToString());
4032 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
4033 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:234034
[email protected]f1f3f0f82011-10-01 20:38:104035 TestOldCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234036
[email protected]f3cf9802011-10-28 18:44:584037 rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2), &callback2);
[email protected]1c773ea12009-04-28 19:58:424038 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234039
4040 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424041 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234042
4043 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504044 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234045 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4046 EXPECT_EQ(100, response->headers->GetContentLength());
4047 }
4048
4049 // ------------------------------------------------------------------------
4050
4051 // Transaction 3: Resend a request in MyRealm's protection space --
4052 // succeed with preemptive authorization.
4053 {
[email protected]1c773ea12009-04-28 19:58:424054 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234055 request.method = "GET";
4056 request.url = GURL("http://www.google.com/x/y/z2");
4057 request.load_flags = 0;
4058
[email protected]cb9bf6ca2011-01-28 13:15:274059 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
4060
[email protected]f9ee6b52008-11-08 06:46:234061 MockWrite data_writes1[] = {
4062 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
4063 "Host: www.google.com\r\n"
4064 "Connection: keep-alive\r\n"
4065 // The authorization for MyRealm1 gets sent preemptively
4066 // (since the url is in the same protection space)
4067 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4068 };
4069
4070 // Sever accepts the preemptive authorization
4071 MockRead data_reads1[] = {
4072 MockRead("HTTP/1.0 200 OK\r\n"),
4073 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424074 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:234075 };
4076
[email protected]31a2bfe2010-02-09 08:03:394077 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4078 data_writes1, arraysize(data_writes1));
[email protected]5ecc992a42009-11-11 01:41:594079 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:234080
[email protected]f1f3f0f82011-10-01 20:38:104081 TestOldCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234082
[email protected]5a1d7ca2010-04-28 20:12:274083 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424084 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234085
4086 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424087 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234088
[email protected]1c773ea12009-04-28 19:58:424089 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504090 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234091
4092 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4093 EXPECT_EQ(100, response->headers->GetContentLength());
4094 }
4095
4096 // ------------------------------------------------------------------------
4097
4098 // Transaction 4: request another URL in MyRealm (however the
4099 // url is not known to belong to the protection space, so no pre-auth).
4100 {
[email protected]1c773ea12009-04-28 19:58:424101 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234102 request.method = "GET";
4103 request.url = GURL("http://www.google.com/x/1");
4104 request.load_flags = 0;
4105
[email protected]cb9bf6ca2011-01-28 13:15:274106 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
4107
[email protected]f9ee6b52008-11-08 06:46:234108 MockWrite data_writes1[] = {
4109 MockWrite("GET /x/1 HTTP/1.1\r\n"
4110 "Host: www.google.com\r\n"
4111 "Connection: keep-alive\r\n\r\n"),
4112 };
4113
4114 MockRead data_reads1[] = {
4115 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4116 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4117 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424118 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234119 };
4120
4121 // Resend with authorization from MyRealm's cache.
4122 MockWrite data_writes2[] = {
4123 MockWrite("GET /x/1 HTTP/1.1\r\n"
4124 "Host: www.google.com\r\n"
4125 "Connection: keep-alive\r\n"
4126 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4127 };
4128
4129 // Sever accepts the authorization.
4130 MockRead data_reads2[] = {
4131 MockRead("HTTP/1.0 200 OK\r\n"),
4132 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424133 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:234134 };
4135
[email protected]31a2bfe2010-02-09 08:03:394136 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4137 data_writes1, arraysize(data_writes1));
4138 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4139 data_writes2, arraysize(data_writes2));
[email protected]5ecc992a42009-11-11 01:41:594140 session_deps.socket_factory.AddSocketDataProvider(&data1);
4141 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234142
[email protected]f1f3f0f82011-10-01 20:38:104143 TestOldCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234144
[email protected]5a1d7ca2010-04-28 20:12:274145 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424146 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234147
4148 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424149 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234150
[email protected]0757e7702009-03-27 04:00:224151 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]f1f3f0f82011-10-01 20:38:104152 TestOldCompletionCallback callback2;
[email protected]f3cf9802011-10-28 18:44:584153 rv = trans->RestartWithAuth(AuthCredentials(), &callback2);
[email protected]1c773ea12009-04-28 19:58:424154 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224155 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424156 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224157 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4158
[email protected]1c773ea12009-04-28 19:58:424159 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504160 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234161 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4162 EXPECT_EQ(100, response->headers->GetContentLength());
4163 }
4164
4165 // ------------------------------------------------------------------------
4166
4167 // Transaction 5: request a URL in MyRealm, but the server rejects the
4168 // cached identity. Should invalidate and re-prompt.
4169 {
[email protected]1c773ea12009-04-28 19:58:424170 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234171 request.method = "GET";
4172 request.url = GURL("http://www.google.com/p/q/t");
4173 request.load_flags = 0;
4174
[email protected]cb9bf6ca2011-01-28 13:15:274175 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
4176
[email protected]f9ee6b52008-11-08 06:46:234177 MockWrite data_writes1[] = {
4178 MockWrite("GET /p/q/t HTTP/1.1\r\n"
4179 "Host: www.google.com\r\n"
4180 "Connection: keep-alive\r\n\r\n"),
4181 };
4182
4183 MockRead data_reads1[] = {
4184 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4185 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4186 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424187 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234188 };
4189
4190 // Resend with authorization from cache for MyRealm.
4191 MockWrite data_writes2[] = {
4192 MockWrite("GET /p/q/t HTTP/1.1\r\n"
4193 "Host: www.google.com\r\n"
4194 "Connection: keep-alive\r\n"
4195 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4196 };
4197
4198 // Sever rejects the authorization.
4199 MockRead data_reads2[] = {
4200 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4201 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4202 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424203 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234204 };
4205
4206 // At this point we should prompt for new credentials for MyRealm.
4207 // Restart with username=foo3, password=foo4.
4208 MockWrite data_writes3[] = {
4209 MockWrite("GET /p/q/t HTTP/1.1\r\n"
4210 "Host: www.google.com\r\n"
4211 "Connection: keep-alive\r\n"
4212 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
4213 };
4214
4215 // Sever accepts the authorization.
4216 MockRead data_reads3[] = {
4217 MockRead("HTTP/1.0 200 OK\r\n"),
4218 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424219 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:234220 };
4221
[email protected]31a2bfe2010-02-09 08:03:394222 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4223 data_writes1, arraysize(data_writes1));
4224 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4225 data_writes2, arraysize(data_writes2));
4226 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4227 data_writes3, arraysize(data_writes3));
[email protected]5ecc992a42009-11-11 01:41:594228 session_deps.socket_factory.AddSocketDataProvider(&data1);
4229 session_deps.socket_factory.AddSocketDataProvider(&data2);
4230 session_deps.socket_factory.AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:234231
[email protected]f1f3f0f82011-10-01 20:38:104232 TestOldCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234233
[email protected]5a1d7ca2010-04-28 20:12:274234 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424235 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234236
4237 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424238 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234239
[email protected]0757e7702009-03-27 04:00:224240 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]f1f3f0f82011-10-01 20:38:104241 TestOldCompletionCallback callback2;
[email protected]f3cf9802011-10-28 18:44:584242 rv = trans->RestartWithAuth(AuthCredentials(), &callback2);
[email protected]1c773ea12009-04-28 19:58:424243 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224244 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424245 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224246 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4247
[email protected]1c773ea12009-04-28 19:58:424248 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504249 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044250 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:234251
[email protected]f1f3f0f82011-10-01 20:38:104252 TestOldCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:234253
[email protected]f3cf9802011-10-28 18:44:584254 rv = trans->RestartWithAuth(AuthCredentials(kFoo3, kBar3), &callback3);
[email protected]1c773ea12009-04-28 19:58:424255 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234256
[email protected]0757e7702009-03-27 04:00:224257 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424258 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234259
4260 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504261 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234262 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4263 EXPECT_EQ(100, response->headers->GetContentLength());
4264 }
4265}
[email protected]89ceba9a2009-03-21 03:46:064266
[email protected]3c32c5f2010-05-18 15:18:124267// Tests that nonce count increments when multiple auth attempts
4268// are started with the same nonce.
4269TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
4270 SessionDependencies session_deps;
[email protected]54fea2562010-11-17 14:40:444271 HttpAuthHandlerDigest::Factory* digest_factory =
4272 new HttpAuthHandlerDigest::Factory();
4273 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
4274 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
4275 digest_factory->set_nonce_generator(nonce_generator);
4276 session_deps.http_auth_handler_factory.reset(digest_factory);
[email protected]ad8e04a2010-11-01 04:16:274277 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]3c32c5f2010-05-18 15:18:124278
4279 // Transaction 1: authenticate (foo, bar) on MyRealm1
4280 {
[email protected]3c32c5f2010-05-18 15:18:124281 HttpRequestInfo request;
4282 request.method = "GET";
4283 request.url = GURL("http://www.google.com/x/y/z");
4284 request.load_flags = 0;
4285
[email protected]cb9bf6ca2011-01-28 13:15:274286 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
4287
[email protected]3c32c5f2010-05-18 15:18:124288 MockWrite data_writes1[] = {
4289 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4290 "Host: www.google.com\r\n"
4291 "Connection: keep-alive\r\n\r\n"),
4292 };
4293
4294 MockRead data_reads1[] = {
4295 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4296 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
4297 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
4298 MockRead(false, OK),
4299 };
4300
4301 // Resend with authorization (username=foo, password=bar)
4302 MockWrite data_writes2[] = {
4303 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4304 "Host: www.google.com\r\n"
4305 "Connection: keep-alive\r\n"
4306 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
4307 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
4308 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
4309 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
4310 };
4311
4312 // Sever accepts the authorization.
4313 MockRead data_reads2[] = {
4314 MockRead("HTTP/1.0 200 OK\r\n"),
4315 MockRead(false, OK),
4316 };
4317
4318 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4319 data_writes1, arraysize(data_writes1));
4320 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4321 data_writes2, arraysize(data_writes2));
4322 session_deps.socket_factory.AddSocketDataProvider(&data1);
4323 session_deps.socket_factory.AddSocketDataProvider(&data2);
4324
[email protected]f1f3f0f82011-10-01 20:38:104325 TestOldCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:124326
4327 int rv = trans->Start(&request, &callback1, BoundNetLog());
4328 EXPECT_EQ(ERR_IO_PENDING, rv);
4329
4330 rv = callback1.WaitForResult();
4331 EXPECT_EQ(OK, rv);
4332
4333 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504334 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044335 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:124336
[email protected]f1f3f0f82011-10-01 20:38:104337 TestOldCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:124338
[email protected]f3cf9802011-10-28 18:44:584339 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]3c32c5f2010-05-18 15:18:124340 EXPECT_EQ(ERR_IO_PENDING, rv);
4341
4342 rv = callback2.WaitForResult();
4343 EXPECT_EQ(OK, rv);
4344
4345 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504346 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:124347 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4348 }
4349
4350 // ------------------------------------------------------------------------
4351
4352 // Transaction 2: Request another resource in digestive's protection space.
4353 // This will preemptively add an Authorization header which should have an
4354 // "nc" value of 2 (as compared to 1 in the first use.
4355 {
[email protected]3c32c5f2010-05-18 15:18:124356 HttpRequestInfo request;
4357 request.method = "GET";
4358 // Note that Transaction 1 was at /x/y/z, so this is in the same
4359 // protection space as digest.
4360 request.url = GURL("http://www.google.com/x/y/a/b");
4361 request.load_flags = 0;
4362
[email protected]cb9bf6ca2011-01-28 13:15:274363 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
4364
[email protected]3c32c5f2010-05-18 15:18:124365 MockWrite data_writes1[] = {
4366 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4367 "Host: www.google.com\r\n"
4368 "Connection: keep-alive\r\n"
4369 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
4370 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
4371 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
4372 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
4373 };
4374
4375 // Sever accepts the authorization.
4376 MockRead data_reads1[] = {
4377 MockRead("HTTP/1.0 200 OK\r\n"),
4378 MockRead("Content-Length: 100\r\n\r\n"),
4379 MockRead(false, OK),
4380 };
4381
4382 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4383 data_writes1, arraysize(data_writes1));
4384 session_deps.socket_factory.AddSocketDataProvider(&data1);
4385
[email protected]f1f3f0f82011-10-01 20:38:104386 TestOldCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:124387
4388 int rv = trans->Start(&request, &callback1, BoundNetLog());
4389 EXPECT_EQ(ERR_IO_PENDING, rv);
4390
4391 rv = callback1.WaitForResult();
4392 EXPECT_EQ(OK, rv);
4393
4394 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504395 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:124396 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4397 }
4398}
4399
[email protected]89ceba9a2009-03-21 03:46:064400// Test the ResetStateForRestart() private method.
4401TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
4402 // Create a transaction (the dependencies aren't important).
[email protected]228ff742009-06-05 01:19:594403 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:404404 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:434405 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]89ceba9a2009-03-21 03:46:064406
4407 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:064408 trans->read_buf_ = new IOBuffer(15);
4409 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:204410 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:064411
4412 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:144413 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:574414 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:084415 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:574416 response->response_time = base::Time::Now();
4417 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:064418
4419 { // Setup state for response_.vary_data
4420 HttpRequestInfo request;
4421 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
4422 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:274423 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:434424 request.extra_headers.SetHeader("Foo", "1");
4425 request.extra_headers.SetHeader("bar", "23");
[email protected]0877e3d2009-10-17 22:29:574426 EXPECT_TRUE(response->vary_data.Init(request, *headers));
[email protected]89ceba9a2009-03-21 03:46:064427 }
4428
4429 // Cause the above state to be reset.
4430 trans->ResetStateForRestart();
4431
4432 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:074433 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:064434 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:204435 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:574436 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4437 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:044438 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:084439 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:574440 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:064441}
4442
[email protected]bacff652009-03-31 17:50:334443// Test HTTPS connections to a site with a bad certificate
4444TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:334445 HttpRequestInfo request;
4446 request.method = "GET";
4447 request.url = GURL("https://www.google.com/");
4448 request.load_flags = 0;
4449
[email protected]cb9bf6ca2011-01-28 13:15:274450 SessionDependencies session_deps;
4451 scoped_ptr<HttpTransaction> trans(
4452 new HttpNetworkTransaction(CreateSession(&session_deps)));
4453
[email protected]bacff652009-03-31 17:50:334454 MockWrite data_writes[] = {
4455 MockWrite("GET / HTTP/1.1\r\n"
4456 "Host: www.google.com\r\n"
4457 "Connection: keep-alive\r\n\r\n"),
4458 };
4459
4460 MockRead data_reads[] = {
4461 MockRead("HTTP/1.0 200 OK\r\n"),
4462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4463 MockRead("Content-Length: 100\r\n\r\n"),
4464 MockRead(false, OK),
4465 };
4466
[email protected]5ecc992a42009-11-11 01:41:594467 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:394468 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4469 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:594470 SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
4471 SSLSocketDataProvider ssl(true, OK);
[email protected]bacff652009-03-31 17:50:334472
[email protected]5ecc992a42009-11-11 01:41:594473 session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
4474 session_deps.socket_factory.AddSocketDataProvider(&data);
4475 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
4476 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:334477
[email protected]f1f3f0f82011-10-01 20:38:104478 TestOldCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:334479
[email protected]5a1d7ca2010-04-28 20:12:274480 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]bacff652009-03-31 17:50:334481 EXPECT_EQ(ERR_IO_PENDING, rv);
4482
4483 rv = callback.WaitForResult();
4484 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
4485
4486 rv = trans->RestartIgnoringLastError(&callback);
4487 EXPECT_EQ(ERR_IO_PENDING, rv);
4488
4489 rv = callback.WaitForResult();
4490 EXPECT_EQ(OK, rv);
4491
4492 const HttpResponseInfo* response = trans->GetResponseInfo();
4493
[email protected]fe2255a2011-09-20 19:37:504494 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:334495 EXPECT_EQ(100, response->headers->GetContentLength());
4496}
4497
4498// Test HTTPS connections to a site with a bad certificate, going through a
4499// proxy
4500TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]81cdfcd2010-10-16 00:49:004501 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:334502
4503 HttpRequestInfo request;
4504 request.method = "GET";
4505 request.url = GURL("https://www.google.com/");
4506 request.load_flags = 0;
4507
4508 MockWrite proxy_writes[] = {
4509 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454510 "Host: www.google.com\r\n"
4511 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:334512 };
4513
4514 MockRead proxy_reads[] = {
4515 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:424516 MockRead(false, OK)
[email protected]bacff652009-03-31 17:50:334517 };
4518
4519 MockWrite data_writes[] = {
4520 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454521 "Host: www.google.com\r\n"
4522 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:334523 MockWrite("GET / HTTP/1.1\r\n"
4524 "Host: www.google.com\r\n"
4525 "Connection: keep-alive\r\n\r\n"),
4526 };
4527
4528 MockRead data_reads[] = {
4529 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
4530 MockRead("HTTP/1.0 200 OK\r\n"),
4531 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4532 MockRead("Content-Length: 100\r\n\r\n"),
4533 MockRead(false, OK),
4534 };
4535
[email protected]31a2bfe2010-02-09 08:03:394536 StaticSocketDataProvider ssl_bad_certificate(
4537 proxy_reads, arraysize(proxy_reads),
4538 proxy_writes, arraysize(proxy_writes));
4539 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4540 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:594541 SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
4542 SSLSocketDataProvider ssl(true, OK);
[email protected]bacff652009-03-31 17:50:334543
[email protected]5ecc992a42009-11-11 01:41:594544 session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
4545 session_deps.socket_factory.AddSocketDataProvider(&data);
4546 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
4547 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:334548
[email protected]f1f3f0f82011-10-01 20:38:104549 TestOldCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:334550
4551 for (int i = 0; i < 2; i++) {
[email protected]228ff742009-06-05 01:19:594552 session_deps.socket_factory.ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:334553
[email protected]d207a5f2009-06-04 05:28:404554 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:434555 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]bacff652009-03-31 17:50:334556
[email protected]5a1d7ca2010-04-28 20:12:274557 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]bacff652009-03-31 17:50:334558 EXPECT_EQ(ERR_IO_PENDING, rv);
4559
4560 rv = callback.WaitForResult();
4561 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
4562
4563 rv = trans->RestartIgnoringLastError(&callback);
4564 EXPECT_EQ(ERR_IO_PENDING, rv);
4565
4566 rv = callback.WaitForResult();
4567 EXPECT_EQ(OK, rv);
4568
4569 const HttpResponseInfo* response = trans->GetResponseInfo();
4570
[email protected]fe2255a2011-09-20 19:37:504571 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:334572 EXPECT_EQ(100, response->headers->GetContentLength());
4573 }
4574}
4575
[email protected]2df19bb2010-08-25 20:13:464576
4577// Test HTTPS connections to a site, going through an HTTPS proxy
4578TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]3912662a32011-10-04 00:51:114579 SessionDependencies session_deps(ProxyService::CreateFixed(
4580 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:464581
4582 HttpRequestInfo request;
4583 request.method = "GET";
4584 request.url = GURL("https://www.google.com/");
4585 request.load_flags = 0;
4586
4587 MockWrite data_writes[] = {
4588 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4589 "Host: www.google.com\r\n"
4590 "Proxy-Connection: keep-alive\r\n\r\n"),
4591 MockWrite("GET / HTTP/1.1\r\n"
4592 "Host: www.google.com\r\n"
4593 "Connection: keep-alive\r\n\r\n"),
4594 };
4595
4596 MockRead data_reads[] = {
4597 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
4598 MockRead("HTTP/1.1 200 OK\r\n"),
4599 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4600 MockRead("Content-Length: 100\r\n\r\n"),
4601 MockRead(false, OK),
4602 };
4603
4604 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4605 data_writes, arraysize(data_writes));
4606 SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy
4607 SSLSocketDataProvider tunnel_ssl(true, OK); // SSL through the tunnel
4608
4609 session_deps.socket_factory.AddSocketDataProvider(&data);
4610 session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
4611 session_deps.socket_factory.AddSSLSocketDataProvider(&tunnel_ssl);
4612
[email protected]f1f3f0f82011-10-01 20:38:104613 TestOldCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:464614
4615 scoped_ptr<HttpTransaction> trans(
4616 new HttpNetworkTransaction(CreateSession(&session_deps)));
4617
4618 int rv = trans->Start(&request, &callback, BoundNetLog());
4619 EXPECT_EQ(ERR_IO_PENDING, rv);
4620
4621 rv = callback.WaitForResult();
4622 EXPECT_EQ(OK, rv);
4623 const HttpResponseInfo* response = trans->GetResponseInfo();
4624
[email protected]fe2255a2011-09-20 19:37:504625 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464626
4627 EXPECT_TRUE(response->headers->IsKeepAlive());
4628 EXPECT_EQ(200, response->headers->response_code());
4629 EXPECT_EQ(100, response->headers->GetContentLength());
4630 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4631}
4632
[email protected]511f6f52010-12-17 03:58:294633// Test an HTTPS Proxy's ability to redirect a CONNECT request
4634TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
4635 SessionDependencies session_deps(
4636 ProxyService::CreateFixed("https://proxy:70"));
4637
4638 HttpRequestInfo request;
4639 request.method = "GET";
4640 request.url = GURL("https://www.google.com/");
4641 request.load_flags = 0;
4642
4643 MockWrite data_writes[] = {
4644 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4645 "Host: www.google.com\r\n"
4646 "Proxy-Connection: keep-alive\r\n\r\n"),
4647 };
4648
4649 MockRead data_reads[] = {
4650 MockRead("HTTP/1.1 302 Redirect\r\n"),
4651 MockRead("Location: http://login.example.com/\r\n"),
4652 MockRead("Content-Length: 0\r\n\r\n"),
4653 MockRead(false, OK),
4654 };
4655
4656 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4657 data_writes, arraysize(data_writes));
4658 SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy
4659
4660 session_deps.socket_factory.AddSocketDataProvider(&data);
4661 session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
4662
[email protected]f1f3f0f82011-10-01 20:38:104663 TestOldCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:294664
4665 scoped_ptr<HttpTransaction> trans(
4666 new HttpNetworkTransaction(CreateSession(&session_deps)));
4667
4668 int rv = trans->Start(&request, &callback, BoundNetLog());
4669 EXPECT_EQ(ERR_IO_PENDING, rv);
4670
4671 rv = callback.WaitForResult();
4672 EXPECT_EQ(OK, rv);
4673 const HttpResponseInfo* response = trans->GetResponseInfo();
4674
[email protected]fe2255a2011-09-20 19:37:504675 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:294676
4677 EXPECT_EQ(302, response->headers->response_code());
4678 std::string url;
4679 EXPECT_TRUE(response->headers->IsRedirect(&url));
4680 EXPECT_EQ("http://login.example.com/", url);
4681}
4682
4683// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
4684TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
4685 SessionDependencies session_deps(
4686 ProxyService::CreateFixed("https://proxy:70"));
4687
4688 HttpRequestInfo request;
4689 request.method = "GET";
4690 request.url = GURL("https://www.google.com/");
4691 request.load_flags = 0;
4692
4693 scoped_ptr<spdy::SpdyFrame> conn(ConstructSpdyConnect(NULL, 0, 1));
4694 scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyRstStream(1, spdy::CANCEL));
4695 MockWrite data_writes[] = {
4696 CreateMockWrite(*conn.get(), 0, false),
4697 };
4698
4699 static const char* const kExtraHeaders[] = {
4700 "location",
4701 "http://login.example.com/",
4702 };
4703 scoped_ptr<spdy::SpdyFrame> resp(
4704 ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
4705 arraysize(kExtraHeaders)/2, 1));
4706 MockRead data_reads[] = {
4707 CreateMockRead(*resp.get(), 1, false),
4708 MockRead(true, 0, 2), // EOF
4709 };
4710
4711 scoped_refptr<DelayedSocketData> data(
4712 new DelayedSocketData(
4713 1, // wait for one write to finish before reading.
4714 data_reads, arraysize(data_reads),
4715 data_writes, arraysize(data_writes)));
4716 SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy
4717 proxy_ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
4718 proxy_ssl.next_proto = "spdy/2";
4719 proxy_ssl.was_npn_negotiated = true;
4720
4721 session_deps.socket_factory.AddSocketDataProvider(data.get());
4722 session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
4723
[email protected]f1f3f0f82011-10-01 20:38:104724 TestOldCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:294725
4726 scoped_ptr<HttpTransaction> trans(
4727 new HttpNetworkTransaction(CreateSession(&session_deps)));
4728
4729 int rv = trans->Start(&request, &callback, BoundNetLog());
4730 EXPECT_EQ(ERR_IO_PENDING, rv);
4731
4732 rv = callback.WaitForResult();
4733 EXPECT_EQ(OK, rv);
4734 const HttpResponseInfo* response = trans->GetResponseInfo();
4735
[email protected]fe2255a2011-09-20 19:37:504736 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:294737
4738 EXPECT_EQ(302, response->headers->response_code());
4739 std::string url;
4740 EXPECT_TRUE(response->headers->IsRedirect(&url));
4741 EXPECT_EQ("http://login.example.com/", url);
4742}
4743
4744// Test an HTTPS Proxy's ability to provide a response to a CONNECT request
4745TEST_F(HttpNetworkTransactionTest, ErrorResponseTofHttpsConnectViaHttpsProxy) {
4746 SessionDependencies session_deps(
4747 ProxyService::CreateFixed("https://proxy:70"));
4748
4749 HttpRequestInfo request;
4750 request.method = "GET";
4751 request.url = GURL("https://www.google.com/");
4752 request.load_flags = 0;
4753
4754 MockWrite data_writes[] = {
4755 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4756 "Host: www.google.com\r\n"
4757 "Proxy-Connection: keep-alive\r\n\r\n"),
4758 };
4759
4760 MockRead data_reads[] = {
4761 MockRead("HTTP/1.1 404 Not Found\r\n"),
4762 MockRead("Content-Length: 23\r\n\r\n"),
4763 MockRead("The host does not exist"),
4764 MockRead(false, OK),
4765 };
4766
4767 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4768 data_writes, arraysize(data_writes));
4769 SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy
4770
4771 session_deps.socket_factory.AddSocketDataProvider(&data);
4772 session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
4773
[email protected]f1f3f0f82011-10-01 20:38:104774 TestOldCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:294775
4776 scoped_ptr<HttpTransaction> trans(
4777 new HttpNetworkTransaction(CreateSession(&session_deps)));
4778
4779 int rv = trans->Start(&request, &callback, BoundNetLog());
4780 EXPECT_EQ(ERR_IO_PENDING, rv);
4781
4782 rv = callback.WaitForResult();
4783 EXPECT_EQ(OK, rv);
4784 const HttpResponseInfo* response = trans->GetResponseInfo();
4785
[email protected]fe2255a2011-09-20 19:37:504786 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:294787
4788 EXPECT_EQ(404, response->headers->response_code());
4789 EXPECT_EQ(23, response->headers->GetContentLength());
4790 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4791 EXPECT_FALSE(response->ssl_info.is_valid());
4792
4793 std::string response_data;
4794 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4795 EXPECT_EQ("The host does not exist", response_data);
4796}
4797
4798// Test an HTTPS (SPDY) Proxy's ability to provide a response to a CONNECT
4799// request
4800TEST_F(HttpNetworkTransactionTest, ErrorResponseTofHttpsConnectViaSpdyProxy) {
4801 SessionDependencies session_deps(
4802 ProxyService::CreateFixed("https://proxy:70"));
4803
4804 HttpRequestInfo request;
4805 request.method = "GET";
4806 request.url = GURL("https://www.google.com/");
4807 request.load_flags = 0;
4808
4809 scoped_ptr<spdy::SpdyFrame> conn(ConstructSpdyConnect(NULL, 0, 1));
4810 scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyRstStream(1, spdy::CANCEL));
4811 MockWrite data_writes[] = {
4812 CreateMockWrite(*conn.get(), 0, false),
4813 };
4814
4815 static const char* const kExtraHeaders[] = {
4816 "location",
4817 "http://login.example.com/",
4818 };
4819 scoped_ptr<spdy::SpdyFrame> resp(
4820 ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
4821 arraysize(kExtraHeaders)/2, 1));
4822 scoped_ptr<spdy::SpdyFrame> body(
4823 ConstructSpdyBodyFrame(1, "The host does not exist", 23, true));
4824 MockRead data_reads[] = {
4825 CreateMockRead(*resp.get(), 1, false),
4826 CreateMockRead(*body.get(), 2, false),
4827 MockRead(true, 0, 3), // EOF
4828 };
4829
4830 scoped_refptr<DelayedSocketData> data(
4831 new DelayedSocketData(
4832 1, // wait for one write to finish before reading.
4833 data_reads, arraysize(data_reads),
4834 data_writes, arraysize(data_writes)));
4835 SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy
4836 proxy_ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
4837 proxy_ssl.next_proto = "spdy/2";
4838 proxy_ssl.was_npn_negotiated = true;
4839
4840 session_deps.socket_factory.AddSocketDataProvider(data.get());
4841 session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
4842
[email protected]f1f3f0f82011-10-01 20:38:104843 TestOldCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:294844
4845 scoped_ptr<HttpTransaction> trans(
4846 new HttpNetworkTransaction(CreateSession(&session_deps)));
4847
4848 int rv = trans->Start(&request, &callback, BoundNetLog());
4849 EXPECT_EQ(ERR_IO_PENDING, rv);
4850
4851 rv = callback.WaitForResult();
4852 EXPECT_EQ(OK, rv);
4853 const HttpResponseInfo* response = trans->GetResponseInfo();
4854
[email protected]fe2255a2011-09-20 19:37:504855 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:294856
4857 EXPECT_EQ(404, response->headers->response_code());
4858 EXPECT_FALSE(response->ssl_info.is_valid());
4859
4860 std::string response_data;
4861 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4862 EXPECT_EQ("The host does not exist", response_data);
4863}
4864
[email protected]2df19bb2010-08-25 20:13:464865// Test HTTPS connections to a site with a bad certificate, going through an
4866// HTTPS proxy
4867TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]3912662a32011-10-04 00:51:114868 SessionDependencies session_deps(ProxyService::CreateFixed(
4869 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:464870
4871 HttpRequestInfo request;
4872 request.method = "GET";
4873 request.url = GURL("https://www.google.com/");
4874 request.load_flags = 0;
4875
4876 // Attempt to fetch the URL from a server with a bad cert
4877 MockWrite bad_cert_writes[] = {
4878 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4879 "Host: www.google.com\r\n"
4880 "Proxy-Connection: keep-alive\r\n\r\n"),
4881 };
4882
4883 MockRead bad_cert_reads[] = {
4884 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
4885 MockRead(false, OK)
4886 };
4887
4888 // Attempt to fetch the URL with a good cert
4889 MockWrite good_data_writes[] = {
4890 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4891 "Host: www.google.com\r\n"
4892 "Proxy-Connection: keep-alive\r\n\r\n"),
4893 MockWrite("GET / HTTP/1.1\r\n"
4894 "Host: www.google.com\r\n"
4895 "Connection: keep-alive\r\n\r\n"),
4896 };
4897
4898 MockRead good_cert_reads[] = {
4899 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
4900 MockRead("HTTP/1.0 200 OK\r\n"),
4901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4902 MockRead("Content-Length: 100\r\n\r\n"),
4903 MockRead(false, OK),
4904 };
4905
4906 StaticSocketDataProvider ssl_bad_certificate(
4907 bad_cert_reads, arraysize(bad_cert_reads),
4908 bad_cert_writes, arraysize(bad_cert_writes));
4909 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
4910 good_data_writes, arraysize(good_data_writes));
4911 SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
4912 SSLSocketDataProvider ssl(true, OK);
4913
4914 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
4915 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
4916 session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
4917 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
4918
4919 // SSL to the proxy, then CONNECT request, then valid SSL certificate
4920 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
4921 session_deps.socket_factory.AddSocketDataProvider(&data);
4922 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
4923
[email protected]f1f3f0f82011-10-01 20:38:104924 TestOldCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:464925
4926 scoped_ptr<HttpTransaction> trans(
4927 new HttpNetworkTransaction(CreateSession(&session_deps)));
4928
4929 int rv = trans->Start(&request, &callback, BoundNetLog());
4930 EXPECT_EQ(ERR_IO_PENDING, rv);
4931
4932 rv = callback.WaitForResult();
4933 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
4934
4935 rv = trans->RestartIgnoringLastError(&callback);
4936 EXPECT_EQ(ERR_IO_PENDING, rv);
4937
4938 rv = callback.WaitForResult();
4939 EXPECT_EQ(OK, rv);
4940
4941 const HttpResponseInfo* response = trans->GetResponseInfo();
4942
[email protected]fe2255a2011-09-20 19:37:504943 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464944 EXPECT_EQ(100, response->headers->GetContentLength());
4945}
4946
[email protected]1c773ea12009-04-28 19:58:424947TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:424948 HttpRequestInfo request;
4949 request.method = "GET";
4950 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:434951 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
4952 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:424953
[email protected]cb9bf6ca2011-01-28 13:15:274954 SessionDependencies session_deps;
4955 scoped_ptr<HttpTransaction> trans(
4956 new HttpNetworkTransaction(CreateSession(&session_deps)));
4957
[email protected]1c773ea12009-04-28 19:58:424958 MockWrite data_writes[] = {
4959 MockWrite("GET / HTTP/1.1\r\n"
4960 "Host: www.google.com\r\n"
4961 "Connection: keep-alive\r\n"
4962 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
4963 };
4964
4965 // Lastly, the server responds with the actual content.
4966 MockRead data_reads[] = {
4967 MockRead("HTTP/1.0 200 OK\r\n"),
4968 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4969 MockRead("Content-Length: 100\r\n\r\n"),
4970 MockRead(false, OK),
4971 };
4972
[email protected]31a2bfe2010-02-09 08:03:394973 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4974 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:594975 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:424976
[email protected]f1f3f0f82011-10-01 20:38:104977 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:424978
[email protected]5a1d7ca2010-04-28 20:12:274979 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424980 EXPECT_EQ(ERR_IO_PENDING, rv);
4981
4982 rv = callback.WaitForResult();
4983 EXPECT_EQ(OK, rv);
4984}
4985
[email protected]da81f132010-08-18 23:39:294986TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:294987 HttpRequestInfo request;
4988 request.method = "GET";
4989 request.url = GURL("https://www.google.com/");
4990 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
4991 "Chromium Ultra Awesome X Edition");
4992
[email protected]cb9bf6ca2011-01-28 13:15:274993 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
4994 scoped_ptr<HttpTransaction> trans(
4995 new HttpNetworkTransaction(CreateSession(&session_deps)));
4996
[email protected]da81f132010-08-18 23:39:294997 MockWrite data_writes[] = {
4998 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4999 "Host: www.google.com\r\n"
5000 "Proxy-Connection: keep-alive\r\n"
5001 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
5002 };
5003 MockRead data_reads[] = {
5004 // Return an error, so the transaction stops here (this test isn't
5005 // interested in the rest).
5006 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5007 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5008 MockRead("Proxy-Connection: close\r\n\r\n"),
5009 };
5010
5011 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5012 data_writes, arraysize(data_writes));
5013 session_deps.socket_factory.AddSocketDataProvider(&data);
5014
[email protected]f1f3f0f82011-10-01 20:38:105015 TestOldCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:295016
5017 int rv = trans->Start(&request, &callback, BoundNetLog());
5018 EXPECT_EQ(ERR_IO_PENDING, rv);
5019
5020 rv = callback.WaitForResult();
5021 EXPECT_EQ(OK, rv);
5022}
5023
[email protected]1c773ea12009-04-28 19:58:425024TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:425025 HttpRequestInfo request;
5026 request.method = "GET";
5027 request.url = GURL("http://www.google.com/");
5028 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:165029 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
5030 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:425031
[email protected]cb9bf6ca2011-01-28 13:15:275032 SessionDependencies session_deps;
5033 scoped_ptr<HttpTransaction> trans(
5034 new HttpNetworkTransaction(CreateSession(&session_deps)));
5035
[email protected]1c773ea12009-04-28 19:58:425036 MockWrite data_writes[] = {
5037 MockWrite("GET / HTTP/1.1\r\n"
5038 "Host: www.google.com\r\n"
5039 "Connection: keep-alive\r\n"
5040 "Referer: http://the.previous.site.com/\r\n\r\n"),
5041 };
5042
5043 // Lastly, the server responds with the actual content.
5044 MockRead data_reads[] = {
5045 MockRead("HTTP/1.0 200 OK\r\n"),
5046 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5047 MockRead("Content-Length: 100\r\n\r\n"),
5048 MockRead(false, OK),
5049 };
5050
[email protected]31a2bfe2010-02-09 08:03:395051 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5052 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595053 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:425054
[email protected]f1f3f0f82011-10-01 20:38:105055 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:425056
[email protected]5a1d7ca2010-04-28 20:12:275057 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425058 EXPECT_EQ(ERR_IO_PENDING, rv);
5059
5060 rv = callback.WaitForResult();
5061 EXPECT_EQ(OK, rv);
5062}
5063
5064TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:425065 HttpRequestInfo request;
5066 request.method = "POST";
5067 request.url = GURL("http://www.google.com/");
5068
[email protected]cb9bf6ca2011-01-28 13:15:275069 SessionDependencies session_deps;
5070 scoped_ptr<HttpTransaction> trans(
5071 new HttpNetworkTransaction(CreateSession(&session_deps)));
5072
[email protected]1c773ea12009-04-28 19:58:425073 MockWrite data_writes[] = {
5074 MockWrite("POST / HTTP/1.1\r\n"
5075 "Host: www.google.com\r\n"
5076 "Connection: keep-alive\r\n"
5077 "Content-Length: 0\r\n\r\n"),
5078 };
5079
5080 // Lastly, the server responds with the actual content.
5081 MockRead data_reads[] = {
5082 MockRead("HTTP/1.0 200 OK\r\n"),
5083 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5084 MockRead("Content-Length: 100\r\n\r\n"),
5085 MockRead(false, OK),
5086 };
5087
[email protected]31a2bfe2010-02-09 08:03:395088 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5089 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595090 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:425091
[email protected]f1f3f0f82011-10-01 20:38:105092 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:425093
[email protected]5a1d7ca2010-04-28 20:12:275094 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425095 EXPECT_EQ(ERR_IO_PENDING, rv);
5096
5097 rv = callback.WaitForResult();
5098 EXPECT_EQ(OK, rv);
5099}
5100
5101TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:425102 HttpRequestInfo request;
5103 request.method = "PUT";
5104 request.url = GURL("http://www.google.com/");
5105
[email protected]cb9bf6ca2011-01-28 13:15:275106 SessionDependencies session_deps;
5107 scoped_ptr<HttpTransaction> trans(
5108 new HttpNetworkTransaction(CreateSession(&session_deps)));
5109
[email protected]1c773ea12009-04-28 19:58:425110 MockWrite data_writes[] = {
5111 MockWrite("PUT / HTTP/1.1\r\n"
5112 "Host: www.google.com\r\n"
5113 "Connection: keep-alive\r\n"
5114 "Content-Length: 0\r\n\r\n"),
5115 };
5116
5117 // Lastly, the server responds with the actual content.
5118 MockRead data_reads[] = {
5119 MockRead("HTTP/1.0 200 OK\r\n"),
5120 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5121 MockRead("Content-Length: 100\r\n\r\n"),
5122 MockRead(false, OK),
5123 };
5124
[email protected]31a2bfe2010-02-09 08:03:395125 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5126 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595127 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:425128
[email protected]f1f3f0f82011-10-01 20:38:105129 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:425130
[email protected]5a1d7ca2010-04-28 20:12:275131 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425132 EXPECT_EQ(ERR_IO_PENDING, rv);
5133
5134 rv = callback.WaitForResult();
5135 EXPECT_EQ(OK, rv);
5136}
5137
5138TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:425139 HttpRequestInfo request;
5140 request.method = "HEAD";
5141 request.url = GURL("http://www.google.com/");
5142
[email protected]cb9bf6ca2011-01-28 13:15:275143 SessionDependencies session_deps;
5144 scoped_ptr<HttpTransaction> trans(
5145 new HttpNetworkTransaction(CreateSession(&session_deps)));
5146
[email protected]1c773ea12009-04-28 19:58:425147 MockWrite data_writes[] = {
5148 MockWrite("HEAD / HTTP/1.1\r\n"
5149 "Host: www.google.com\r\n"
5150 "Connection: keep-alive\r\n"
5151 "Content-Length: 0\r\n\r\n"),
5152 };
5153
5154 // Lastly, the server responds with the actual content.
5155 MockRead data_reads[] = {
5156 MockRead("HTTP/1.0 200 OK\r\n"),
5157 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5158 MockRead("Content-Length: 100\r\n\r\n"),
5159 MockRead(false, OK),
5160 };
5161
[email protected]31a2bfe2010-02-09 08:03:395162 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5163 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595164 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:425165
[email protected]f1f3f0f82011-10-01 20:38:105166 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:425167
[email protected]5a1d7ca2010-04-28 20:12:275168 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425169 EXPECT_EQ(ERR_IO_PENDING, rv);
5170
5171 rv = callback.WaitForResult();
5172 EXPECT_EQ(OK, rv);
5173}
5174
5175TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:425176 HttpRequestInfo request;
5177 request.method = "GET";
5178 request.url = GURL("http://www.google.com/");
5179 request.load_flags = LOAD_BYPASS_CACHE;
5180
[email protected]cb9bf6ca2011-01-28 13:15:275181 SessionDependencies session_deps;
5182 scoped_ptr<HttpTransaction> trans(
5183 new HttpNetworkTransaction(CreateSession(&session_deps)));
5184
[email protected]1c773ea12009-04-28 19:58:425185 MockWrite data_writes[] = {
5186 MockWrite("GET / HTTP/1.1\r\n"
5187 "Host: www.google.com\r\n"
5188 "Connection: keep-alive\r\n"
5189 "Pragma: no-cache\r\n"
5190 "Cache-Control: no-cache\r\n\r\n"),
5191 };
5192
5193 // Lastly, the server responds with the actual content.
5194 MockRead data_reads[] = {
5195 MockRead("HTTP/1.0 200 OK\r\n"),
5196 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5197 MockRead("Content-Length: 100\r\n\r\n"),
5198 MockRead(false, OK),
5199 };
5200
[email protected]31a2bfe2010-02-09 08:03:395201 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5202 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595203 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:425204
[email protected]f1f3f0f82011-10-01 20:38:105205 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:425206
[email protected]5a1d7ca2010-04-28 20:12:275207 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425208 EXPECT_EQ(ERR_IO_PENDING, rv);
5209
5210 rv = callback.WaitForResult();
5211 EXPECT_EQ(OK, rv);
5212}
5213
5214TEST_F(HttpNetworkTransactionTest,
5215 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:425216 HttpRequestInfo request;
5217 request.method = "GET";
5218 request.url = GURL("http://www.google.com/");
5219 request.load_flags = LOAD_VALIDATE_CACHE;
5220
[email protected]cb9bf6ca2011-01-28 13:15:275221 SessionDependencies session_deps;
5222 scoped_ptr<HttpTransaction> trans(
5223 new HttpNetworkTransaction(CreateSession(&session_deps)));
5224
[email protected]1c773ea12009-04-28 19:58:425225 MockWrite data_writes[] = {
5226 MockWrite("GET / HTTP/1.1\r\n"
5227 "Host: www.google.com\r\n"
5228 "Connection: keep-alive\r\n"
5229 "Cache-Control: max-age=0\r\n\r\n"),
5230 };
5231
5232 // Lastly, the server responds with the actual content.
5233 MockRead data_reads[] = {
5234 MockRead("HTTP/1.0 200 OK\r\n"),
5235 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5236 MockRead("Content-Length: 100\r\n\r\n"),
5237 MockRead(false, OK),
5238 };
5239
[email protected]31a2bfe2010-02-09 08:03:395240 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5241 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595242 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:425243
[email protected]f1f3f0f82011-10-01 20:38:105244 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:425245
[email protected]5a1d7ca2010-04-28 20:12:275246 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425247 EXPECT_EQ(ERR_IO_PENDING, rv);
5248
5249 rv = callback.WaitForResult();
5250 EXPECT_EQ(OK, rv);
5251}
5252
5253TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:425254 HttpRequestInfo request;
5255 request.method = "GET";
5256 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:435257 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:425258
[email protected]cb9bf6ca2011-01-28 13:15:275259 SessionDependencies session_deps;
5260 scoped_ptr<HttpTransaction> trans(
5261 new HttpNetworkTransaction(CreateSession(&session_deps)));
5262
[email protected]1c773ea12009-04-28 19:58:425263 MockWrite data_writes[] = {
5264 MockWrite("GET / HTTP/1.1\r\n"
5265 "Host: www.google.com\r\n"
5266 "Connection: keep-alive\r\n"
5267 "FooHeader: Bar\r\n\r\n"),
5268 };
5269
5270 // Lastly, the server responds with the actual content.
5271 MockRead data_reads[] = {
5272 MockRead("HTTP/1.0 200 OK\r\n"),
5273 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5274 MockRead("Content-Length: 100\r\n\r\n"),
5275 MockRead(false, OK),
5276 };
5277
[email protected]31a2bfe2010-02-09 08:03:395278 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5279 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595280 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:425281
[email protected]f1f3f0f82011-10-01 20:38:105282 TestOldCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:425283
[email protected]5a1d7ca2010-04-28 20:12:275284 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425285 EXPECT_EQ(ERR_IO_PENDING, rv);
5286
5287 rv = callback.WaitForResult();
5288 EXPECT_EQ(OK, rv);
5289}
5290
[email protected]270c6412010-03-29 22:02:475291TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:475292 HttpRequestInfo request;
5293 request.method = "GET";
5294 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:435295 request.extra_headers.SetHeader("referer", "www.foo.com");
5296 request.extra_headers.SetHeader("hEllo", "Kitty");
5297 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:475298
[email protected]cb9bf6ca2011-01-28 13:15:275299 SessionDependencies session_deps;
5300 scoped_ptr<HttpTransaction> trans(
5301 new HttpNetworkTransaction(CreateSession(&session_deps)));
5302
[email protected]270c6412010-03-29 22:02:475303 MockWrite data_writes[] = {
5304 MockWrite("GET / HTTP/1.1\r\n"
5305 "Host: www.google.com\r\n"
5306 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:165307 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:475308 "hEllo: Kitty\r\n"
5309 "FoO: bar\r\n\r\n"),
5310 };
5311
5312 // Lastly, the server responds with the actual content.
5313 MockRead data_reads[] = {
5314 MockRead("HTTP/1.0 200 OK\r\n"),
5315 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5316 MockRead("Content-Length: 100\r\n\r\n"),
5317 MockRead(false, OK),
5318 };
5319
5320 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5321 data_writes, arraysize(data_writes));
5322 session_deps.socket_factory.AddSocketDataProvider(&data);
5323
[email protected]f1f3f0f82011-10-01 20:38:105324 TestOldCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:475325
[email protected]5a1d7ca2010-04-28 20:12:275326 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]270c6412010-03-29 22:02:475327 EXPECT_EQ(ERR_IO_PENDING, rv);
5328
5329 rv = callback.WaitForResult();
5330 EXPECT_EQ(OK, rv);
5331}
5332
[email protected]3cd17242009-06-23 02:59:025333TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:275334 HttpRequestInfo request;
5335 request.method = "GET";
5336 request.url = GURL("http://www.google.com/");
5337 request.load_flags = 0;
5338
[email protected]80d6524d2009-08-18 03:58:095339 SessionDependencies session_deps(
[email protected]81cdfcd2010-10-16 00:49:005340 ProxyService::CreateFixed("socks4://myproxy:1080"));
[email protected]3cd17242009-06-23 02:59:025341
5342 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:435343 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]3cd17242009-06-23 02:59:025344
[email protected]3cd17242009-06-23 02:59:025345 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
5346 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
5347
5348 MockWrite data_writes[] = {
[email protected]e0c27be2009-07-15 13:09:355349 MockWrite(true, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:025350 MockWrite("GET / HTTP/1.1\r\n"
5351 "Host: www.google.com\r\n"
5352 "Connection: keep-alive\r\n\r\n")
5353 };
5354
5355 MockRead data_reads[] = {
[email protected]5ecc992a42009-11-11 01:41:595356 MockRead(true, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:025357 MockRead("HTTP/1.0 200 OK\r\n"),
5358 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
5359 MockRead("Payload"),
5360 MockRead(false, OK)
5361 };
5362
[email protected]31a2bfe2010-02-09 08:03:395363 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5364 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595365 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:025366
[email protected]f1f3f0f82011-10-01 20:38:105367 TestOldCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:025368
[email protected]5a1d7ca2010-04-28 20:12:275369 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]3cd17242009-06-23 02:59:025370 EXPECT_EQ(ERR_IO_PENDING, rv);
5371
5372 rv = callback.WaitForResult();
5373 EXPECT_EQ(OK, rv);
5374
5375 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505376 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:025377
5378 std::string response_text;
5379 rv = ReadTransaction(trans.get(), &response_text);
5380 EXPECT_EQ(OK, rv);
5381 EXPECT_EQ("Payload", response_text);
5382}
5383
5384TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:275385 HttpRequestInfo request;
5386 request.method = "GET";
5387 request.url = GURL("https://www.google.com/");
5388 request.load_flags = 0;
5389
[email protected]80d6524d2009-08-18 03:58:095390 SessionDependencies session_deps(
[email protected]81cdfcd2010-10-16 00:49:005391 ProxyService::CreateFixed("socks4://myproxy:1080"));
[email protected]3cd17242009-06-23 02:59:025392
5393 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:435394 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]3cd17242009-06-23 02:59:025395
[email protected]3cd17242009-06-23 02:59:025396 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
5397 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
5398
5399 MockWrite data_writes[] = {
[email protected]e0c27be2009-07-15 13:09:355400 MockWrite(true, reinterpret_cast<char*>(write_buffer),
5401 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:025402 MockWrite("GET / HTTP/1.1\r\n"
5403 "Host: www.google.com\r\n"
5404 "Connection: keep-alive\r\n\r\n")
5405 };
5406
5407 MockRead data_reads[] = {
[email protected]e0c27be2009-07-15 13:09:355408 MockWrite(true, reinterpret_cast<char*>(read_buffer),
5409 arraysize(read_buffer)),
5410 MockRead("HTTP/1.0 200 OK\r\n"),
5411 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
5412 MockRead("Payload"),
5413 MockRead(false, OK)
5414 };
5415
[email protected]31a2bfe2010-02-09 08:03:395416 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5417 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595418 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:355419
[email protected]5ecc992a42009-11-11 01:41:595420 SSLSocketDataProvider ssl(true, OK);
5421 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:355422
[email protected]f1f3f0f82011-10-01 20:38:105423 TestOldCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:355424
[email protected]5a1d7ca2010-04-28 20:12:275425 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:355426 EXPECT_EQ(ERR_IO_PENDING, rv);
5427
5428 rv = callback.WaitForResult();
5429 EXPECT_EQ(OK, rv);
5430
5431 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505432 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:355433
5434 std::string response_text;
5435 rv = ReadTransaction(trans.get(), &response_text);
5436 EXPECT_EQ(OK, rv);
5437 EXPECT_EQ("Payload", response_text);
5438}
5439
5440TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:275441 HttpRequestInfo request;
5442 request.method = "GET";
5443 request.url = GURL("http://www.google.com/");
5444 request.load_flags = 0;
5445
[email protected]80d6524d2009-08-18 03:58:095446 SessionDependencies session_deps(
[email protected]81cdfcd2010-10-16 00:49:005447 ProxyService::CreateFixed("socks5://myproxy:1080"));
[email protected]e0c27be2009-07-15 13:09:355448
5449 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:435450 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]e0c27be2009-07-15 13:09:355451
[email protected]e0c27be2009-07-15 13:09:355452 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
5453 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:375454 const char kSOCKS5OkRequest[] = {
5455 0x05, // Version
5456 0x01, // Command (CONNECT)
5457 0x00, // Reserved.
5458 0x03, // Address type (DOMAINNAME).
5459 0x0E, // Length of domain (14)
5460 // Domain string:
5461 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
5462 0x00, 0x50, // 16-bit port (80)
5463 };
[email protected]e0c27be2009-07-15 13:09:355464 const char kSOCKS5OkResponse[] =
5465 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
5466
5467 MockWrite data_writes[] = {
5468 MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
5469 MockWrite(true, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
5470 MockWrite("GET / HTTP/1.1\r\n"
5471 "Host: www.google.com\r\n"
5472 "Connection: keep-alive\r\n\r\n")
5473 };
5474
5475 MockRead data_reads[] = {
5476 MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
5477 MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
5478 MockRead("HTTP/1.0 200 OK\r\n"),
5479 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
5480 MockRead("Payload"),
5481 MockRead(false, OK)
5482 };
5483
[email protected]31a2bfe2010-02-09 08:03:395484 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5485 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595486 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:355487
[email protected]f1f3f0f82011-10-01 20:38:105488 TestOldCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:355489
[email protected]5a1d7ca2010-04-28 20:12:275490 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:355491 EXPECT_EQ(ERR_IO_PENDING, rv);
5492
5493 rv = callback.WaitForResult();
5494 EXPECT_EQ(OK, rv);
5495
5496 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505497 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:355498
5499 std::string response_text;
5500 rv = ReadTransaction(trans.get(), &response_text);
5501 EXPECT_EQ(OK, rv);
5502 EXPECT_EQ("Payload", response_text);
5503}
5504
5505TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:275506 HttpRequestInfo request;
5507 request.method = "GET";
5508 request.url = GURL("https://www.google.com/");
5509 request.load_flags = 0;
5510
[email protected]80d6524d2009-08-18 03:58:095511 SessionDependencies session_deps(
[email protected]81cdfcd2010-10-16 00:49:005512 ProxyService::CreateFixed("socks5://myproxy:1080"));
[email protected]e0c27be2009-07-15 13:09:355513
5514 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:435515 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]e0c27be2009-07-15 13:09:355516
[email protected]e0c27be2009-07-15 13:09:355517 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
5518 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:375519 const unsigned char kSOCKS5OkRequest[] = {
5520 0x05, // Version
5521 0x01, // Command (CONNECT)
5522 0x00, // Reserved.
5523 0x03, // Address type (DOMAINNAME).
5524 0x0E, // Length of domain (14)
5525 // Domain string:
5526 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
5527 0x01, 0xBB, // 16-bit port (443)
5528 };
5529
[email protected]e0c27be2009-07-15 13:09:355530 const char kSOCKS5OkResponse[] =
5531 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
5532
5533 MockWrite data_writes[] = {
5534 MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
5535 MockWrite(true, reinterpret_cast<const char*>(kSOCKS5OkRequest),
5536 arraysize(kSOCKS5OkRequest)),
5537 MockWrite("GET / HTTP/1.1\r\n"
5538 "Host: www.google.com\r\n"
5539 "Connection: keep-alive\r\n\r\n")
5540 };
5541
5542 MockRead data_reads[] = {
5543 MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
5544 MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:025545 MockRead("HTTP/1.0 200 OK\r\n"),
5546 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
5547 MockRead("Payload"),
5548 MockRead(false, OK)
5549 };
5550
[email protected]31a2bfe2010-02-09 08:03:395551 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5552 data_writes, arraysize(data_writes));
[email protected]5ecc992a42009-11-11 01:41:595553 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:025554
[email protected]5ecc992a42009-11-11 01:41:595555 SSLSocketDataProvider ssl(true, OK);
5556 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:025557
[email protected]f1f3f0f82011-10-01 20:38:105558 TestOldCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:025559
[email protected]5a1d7ca2010-04-28 20:12:275560 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]3cd17242009-06-23 02:59:025561 EXPECT_EQ(ERR_IO_PENDING, rv);
5562
5563 rv = callback.WaitForResult();
5564 EXPECT_EQ(OK, rv);
5565
5566 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505567 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:025568
5569 std::string response_text;
5570 rv = ReadTransaction(trans.get(), &response_text);
5571 EXPECT_EQ(OK, rv);
5572 EXPECT_EQ("Payload", response_text);
5573}
5574
[email protected]04e5be32009-06-26 20:00:315575// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:065576
5577struct GroupNameTest {
5578 std::string proxy_server;
5579 std::string url;
5580 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:185581 bool ssl;
[email protected]2d731a32010-04-29 01:04:065582};
5583
5584scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8b114dd72011-03-25 05:33:025585 SessionDependencies* session_deps) {
5586 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps));
[email protected]2d731a32010-04-29 01:04:065587
[email protected]17291a022011-10-10 07:32:535588 HttpServerProperties* http_server_properties =
5589 session->http_server_properties();
5590 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:065591 HostPortPair("host.with.alternate", 80), 443,
[email protected]17291a022011-10-10 07:32:535592 NPN_SPDY_2);
[email protected]2d731a32010-04-29 01:04:065593
5594 return session;
5595}
5596
5597int GroupNameTransactionHelper(
5598 const std::string& url,
5599 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:065600 HttpRequestInfo request;
5601 request.method = "GET";
5602 request.url = GURL(url);
5603 request.load_flags = 0;
5604
[email protected]cb9bf6ca2011-01-28 13:15:275605 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
5606
[email protected]f1f3f0f82011-10-01 20:38:105607 TestOldCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:065608
5609 // We do not complete this request, the dtor will clean the transaction up.
5610 return trans->Start(&request, &callback, BoundNetLog());
5611}
5612
5613TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
5614 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:315615 {
[email protected]2d731a32010-04-29 01:04:065616 "", // unused
[email protected]04e5be32009-06-26 20:00:315617 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:545618 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:185619 false,
[email protected]2ff8b312010-04-26 22:20:545620 },
5621 {
[email protected]2d731a32010-04-29 01:04:065622 "", // unused
[email protected]2ff8b312010-04-26 22:20:545623 "http://[2001:1418:13:1::25]/direct",
5624 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:185625 false,
[email protected]04e5be32009-06-26 20:00:315626 },
[email protected]04e5be32009-06-26 20:00:315627
5628 // SSL Tests
5629 {
[email protected]2d731a32010-04-29 01:04:065630 "", // unused
[email protected]04e5be32009-06-26 20:00:315631 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:025632 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:185633 true,
[email protected]04e5be32009-06-26 20:00:315634 },
5635 {
[email protected]2d731a32010-04-29 01:04:065636 "", // unused
5637 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:025638 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:185639 true,
[email protected]04e5be32009-06-26 20:00:315640 },
5641 {
[email protected]2d731a32010-04-29 01:04:065642 "", // unused
[email protected]2ff8b312010-04-26 22:20:545643 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:025644 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:185645 true,
[email protected]2ff8b312010-04-26 22:20:545646 },
[email protected]2d731a32010-04-29 01:04:065647 };
[email protected]2ff8b312010-04-26 22:20:545648
[email protected]8e6441ca2010-08-19 05:56:385649 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:065650
5651 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]8b114dd72011-03-25 05:33:025652 SessionDependencies session_deps(
5653 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:065654 scoped_refptr<HttpNetworkSession> session(
[email protected]8b114dd72011-03-25 05:33:025655 SetupSessionForGroupNameTests(&session_deps));
[email protected]2d731a32010-04-29 01:04:065656
5657 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:285658 CaptureGroupNameTransportSocketPool* transport_conn_pool =
5659 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:135660 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:345661 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:025662 MockClientSocketPoolManager* mock_pool_manager =
5663 new MockClientSocketPoolManager;
5664 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
5665 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
5666 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:065667
5668 EXPECT_EQ(ERR_IO_PENDING,
5669 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:185670 if (tests[i].ssl)
5671 EXPECT_EQ(tests[i].expected_group_name,
5672 ssl_conn_pool->last_group_name_received());
5673 else
5674 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:285675 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:065676 }
5677
[email protected]8e6441ca2010-08-19 05:56:385678 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]2d731a32010-04-29 01:04:065679}
5680
5681TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
5682 const GroupNameTest tests[] = {
5683 {
5684 "http_proxy",
5685 "http://www.google.com/http_proxy_normal",
5686 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:185687 false,
[email protected]2d731a32010-04-29 01:04:065688 },
5689
5690 // SSL Tests
5691 {
5692 "http_proxy",
5693 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:025694 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:185695 true,
[email protected]2d731a32010-04-29 01:04:065696 },
[email protected]af3490e2010-10-16 21:02:295697
[email protected]9faeded92010-04-29 20:03:055698 {
5699 "http_proxy",
5700 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:025701 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:185702 true,
[email protected]9faeded92010-04-29 20:03:055703 },
[email protected]2d731a32010-04-29 01:04:065704 };
5705
[email protected]8e6441ca2010-08-19 05:56:385706 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:065707
5708 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]8b114dd72011-03-25 05:33:025709 SessionDependencies session_deps(
5710 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:065711 scoped_refptr<HttpNetworkSession> session(
[email protected]8b114dd72011-03-25 05:33:025712 SetupSessionForGroupNameTests(&session_deps));
[email protected]2d731a32010-04-29 01:04:065713
5714 HttpNetworkSessionPeer peer(session);
5715
[email protected]e60e47a2010-07-14 03:37:185716 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:135717 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:345718 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:135719 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:345720 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:025721
5722 MockClientSocketPoolManager* mock_pool_manager =
5723 new MockClientSocketPoolManager;
5724 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
5725 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
5726 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:065727
5728 EXPECT_EQ(ERR_IO_PENDING,
5729 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:185730 if (tests[i].ssl)
5731 EXPECT_EQ(tests[i].expected_group_name,
5732 ssl_conn_pool->last_group_name_received());
5733 else
5734 EXPECT_EQ(tests[i].expected_group_name,
5735 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:065736 }
5737
[email protected]8e6441ca2010-08-19 05:56:385738 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]2d731a32010-04-29 01:04:065739}
5740
5741TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
5742 const GroupNameTest tests[] = {
5743 {
5744 "socks4://socks_proxy:1080",
5745 "http://www.google.com/socks4_direct",
5746 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:185747 false,
[email protected]2d731a32010-04-29 01:04:065748 },
5749 {
5750 "socks5://socks_proxy:1080",
5751 "http://www.google.com/socks5_direct",
5752 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:185753 false,
[email protected]2d731a32010-04-29 01:04:065754 },
5755
5756 // SSL Tests
5757 {
5758 "socks4://socks_proxy:1080",
5759 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:025760 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:185761 true,
[email protected]2d731a32010-04-29 01:04:065762 },
5763 {
5764 "socks5://socks_proxy:1080",
5765 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:025766 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:185767 true,
[email protected]2d731a32010-04-29 01:04:065768 },
[email protected]af3490e2010-10-16 21:02:295769
[email protected]9faeded92010-04-29 20:03:055770 {
5771 "socks4://socks_proxy:1080",
5772 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:025773 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:185774 true,
[email protected]9faeded92010-04-29 20:03:055775 },
[email protected]04e5be32009-06-26 20:00:315776 };
5777
[email protected]8e6441ca2010-08-19 05:56:385778 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:545779
[email protected]04e5be32009-06-26 20:00:315780 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]8b114dd72011-03-25 05:33:025781 SessionDependencies session_deps(
5782 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:065783 scoped_refptr<HttpNetworkSession> session(
[email protected]8b114dd72011-03-25 05:33:025784 SetupSessionForGroupNameTests(&session_deps));
5785
[email protected]2d731a32010-04-29 01:04:065786 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:315787
[email protected]e60e47a2010-07-14 03:37:185788 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:135789 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:345790 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:135791 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:345792 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:025793
5794 MockClientSocketPoolManager* mock_pool_manager =
5795 new MockClientSocketPoolManager;
5796 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
5797 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
5798 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]04e5be32009-06-26 20:00:315799
[email protected]5695b8c2009-09-30 21:36:435800 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]04e5be32009-06-26 20:00:315801
[email protected]2d731a32010-04-29 01:04:065802 EXPECT_EQ(ERR_IO_PENDING,
5803 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:185804 if (tests[i].ssl)
5805 EXPECT_EQ(tests[i].expected_group_name,
5806 ssl_conn_pool->last_group_name_received());
5807 else
5808 EXPECT_EQ(tests[i].expected_group_name,
5809 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:315810 }
[email protected]2ff8b312010-04-26 22:20:545811
[email protected]8e6441ca2010-08-19 05:56:385812 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]04e5be32009-06-26 20:00:315813}
5814
[email protected]9172a982009-06-06 00:30:255815TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:275816 HttpRequestInfo request;
5817 request.method = "GET";
5818 request.url = GURL("http://www.google.com/");
5819
[email protected]5c6a17e2009-06-10 00:54:545820 SessionDependencies session_deps(
[email protected]81cdfcd2010-10-16 00:49:005821 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:325822
[email protected]69719062010-01-05 20:09:215823 // This simulates failure resolving all hostnames; that means we will fail
5824 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]b59ff372009-07-15 22:04:325825 session_deps.host_resolver->rules()->AddSimulatedFailure("*");
5826
[email protected]9172a982009-06-06 00:30:255827 scoped_ptr<HttpTransaction> trans(
[email protected]5695b8c2009-09-30 21:36:435828 new HttpNetworkTransaction(CreateSession(&session_deps)));
[email protected]9172a982009-06-06 00:30:255829
[email protected]f1f3f0f82011-10-01 20:38:105830 TestOldCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:255831
[email protected]5a1d7ca2010-04-28 20:12:275832 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]9172a982009-06-06 00:30:255833 EXPECT_EQ(ERR_IO_PENDING, rv);
5834
[email protected]9172a982009-06-06 00:30:255835 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:015836 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:255837}
5838
[email protected]685af592010-05-11 19:31:245839// Base test to make sure that when the load flags for a request specify to
5840// bypass the cache, the DNS cache is not used.
5841void BypassHostCacheOnRefreshHelper(int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:275842 // Issue a request, asking to bypass the cache(s).
5843 HttpRequestInfo request;
5844 request.method = "GET";
5845 request.load_flags = load_flags;
5846 request.url = GURL("http://www.google.com/");
5847
[email protected]3b9cca42009-06-16 01:08:285848 SessionDependencies session_deps;
[email protected]b59ff372009-07-15 22:04:325849
[email protected]a2c2fb92009-07-18 07:31:045850 // Select a host resolver that does caching.
[email protected]73c45322010-10-01 23:57:545851 session_deps.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:325852
[email protected]3b9cca42009-06-16 01:08:285853 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]5695b8c2009-09-30 21:36:435854 CreateSession(&session_deps)));
[email protected]3b9cca42009-06-16 01:08:285855
[email protected]6e78dfb2011-07-28 21:34:475856 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:285857 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:295858 TestCompletionCallback callback;
5859 TestOldCompletionCallback old_callback;
[email protected]94a0d3d92009-06-27 01:50:145860 int rv = session_deps.host_resolver->Resolve(
[email protected]930cc742010-09-15 22:54:105861 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
[email protected]aa22b242011-11-16 18:58:295862 callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:475863 EXPECT_EQ(ERR_IO_PENDING, rv);
5864 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:285865 EXPECT_EQ(OK, rv);
5866
5867 // Verify that it was added to host cache, by doing a subsequent async lookup
5868 // and confirming it completes synchronously.
[email protected]684970b2009-08-14 04:54:465869 rv = session_deps.host_resolver->Resolve(
[email protected]930cc742010-09-15 22:54:105870 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
[email protected]aa22b242011-11-16 18:58:295871 callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:325872 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:285873
5874 // Inject a failure the next time that "www.google.com" is resolved. This way
5875 // we can tell if the next lookup hit the cache, or the "network".
5876 // (cache --> success, "network" --> failure).
[email protected]b59ff372009-07-15 22:04:325877 session_deps.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:285878
5879 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
5880 // first read -- this won't be reached as the host resolution will fail first.
5881 MockRead data_reads[] = { MockRead(false, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:395882 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:595883 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:285884
[email protected]3b9cca42009-06-16 01:08:285885 // Run the request.
[email protected]aa22b242011-11-16 18:58:295886 rv = trans->Start(&request, &old_callback, BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:285887 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]aa22b242011-11-16 18:58:295888 rv = old_callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:285889
5890 // If we bypassed the cache, we would have gotten a failure while resolving
5891 // "www.google.com".
5892 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
5893}
5894
[email protected]685af592010-05-11 19:31:245895// There are multiple load flags that should trigger the host cache bypass.
5896// Test each in isolation:
5897TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
5898 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
5899}
5900
5901TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
5902 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
5903}
5904
5905TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
5906 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
5907}
5908
[email protected]0877e3d2009-10-17 22:29:575909// Make sure we can handle an error when writing the request.
5910TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
5911 SessionDependencies session_deps;
[email protected]ad8e04a2010-11-01 04:16:275912 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]0877e3d2009-10-17 22:29:575913
5914 HttpRequestInfo request;
5915 request.method = "GET";
5916 request.url = GURL("http://www.foo.com/");
5917 request.load_flags = 0;
5918
5919 MockWrite write_failure[] = {
5920 MockWrite(true, ERR_CONNECTION_RESET),
5921 };
[email protected]31a2bfe2010-02-09 08:03:395922 StaticSocketDataProvider data(NULL, 0,
5923 write_failure, arraysize(write_failure));
[email protected]5ecc992a42009-11-11 01:41:595924 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:575925
[email protected]f1f3f0f82011-10-01 20:38:105926 TestOldCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:575927
5928 scoped_ptr<HttpTransaction> trans(
5929 new HttpNetworkTransaction(CreateSession(&session_deps)));
5930
[email protected]5a1d7ca2010-04-28 20:12:275931 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:575932 EXPECT_EQ(ERR_IO_PENDING, rv);
5933
5934 rv = callback.WaitForResult();
5935 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
5936}
5937
5938// Check that a connection closed after the start of the headers finishes ok.
5939TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
5940 SessionDependencies session_deps;
[email protected]ad8e04a2010-11-01 04:16:275941 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]0877e3d2009-10-17 22:29:575942
5943 HttpRequestInfo request;
5944 request.method = "GET";
5945 request.url = GURL("http://www.foo.com/");
5946 request.load_flags = 0;
5947
5948 MockRead data_reads[] = {
5949 MockRead("HTTP/1."),
5950 MockRead(false, OK),
5951 };
5952
[email protected]31a2bfe2010-02-09 08:03:395953 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:595954 session_deps.socket_factory.AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:575955
[email protected]f1f3f0f82011-10-01 20:38:105956 TestOldCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:575957
5958 scoped_ptr<HttpTransaction> trans(
5959 new HttpNetworkTransaction(CreateSession(&session_deps)));
5960
[email protected]5a1d7ca2010-04-28 20:12:275961 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:575962 EXPECT_EQ(ERR_IO_PENDING, rv);
5963
5964 rv = callback.WaitForResult();
5965 EXPECT_EQ(OK, rv);
5966
5967 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505968 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:575969
5970 EXPECT_TRUE(response->headers != NULL);
5971 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
5972
5973 std::string response_data;
5974 rv = ReadTransaction(trans.get(), &response_data);
5975 EXPECT_EQ(OK, rv);
5976 EXPECT_EQ("", response_data);
5977}
5978
5979// Make sure that a dropped connection while draining the body for auth
5980// restart does the right thing.
5981TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
5982 SessionDependencies session_deps;
[email protected]ad8e04a2010-11-01 04:16:275983 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]0877e3d2009-10-17 22:29:575984
5985 HttpRequestInfo request;
5986 request.method = "GET";
5987 request.url = GURL("http://www.google.com/");
5988 request.load_flags = 0;
5989
5990 MockWrite data_writes1[] = {
5991 MockWrite("GET / HTTP/1.1\r\n"
5992 "Host: www.google.com\r\n"
5993 "Connection: keep-alive\r\n\r\n"),
5994 };
5995
5996 MockRead data_reads1[] = {
5997 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
5998 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5999 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6000 MockRead("Content-Length: 14\r\n\r\n"),
6001 MockRead("Unauth"),
6002 MockRead(true, ERR_CONNECTION_RESET),
6003 };
6004
[email protected]31a2bfe2010-02-09 08:03:396005 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6006 data_writes1, arraysize(data_writes1));
[email protected]5ecc992a42009-11-11 01:41:596007 session_deps.socket_factory.AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:576008
6009 // After calling trans->RestartWithAuth(), this is the request we should
6010 // be issuing -- the final header line contains the credentials.
6011 MockWrite data_writes2[] = {
6012 MockWrite("GET / HTTP/1.1\r\n"
6013 "Host: www.google.com\r\n"
6014 "Connection: keep-alive\r\n"
6015 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
6016 };
6017
6018 // Lastly, the server responds with the actual content.
6019 MockRead data_reads2[] = {
6020 MockRead("HTTP/1.1 200 OK\r\n"),
6021 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6022 MockRead("Content-Length: 100\r\n\r\n"),
6023 MockRead(false, OK),
6024 };
6025
[email protected]31a2bfe2010-02-09 08:03:396026 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6027 data_writes2, arraysize(data_writes2));
[email protected]5ecc992a42009-11-11 01:41:596028 session_deps.socket_factory.AddSocketDataProvider(&data2);
[email protected]0877e3d2009-10-17 22:29:576029
[email protected]f1f3f0f82011-10-01 20:38:106030 TestOldCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:576031
[email protected]0b0bf032010-09-21 18:08:506032 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
6033
[email protected]5a1d7ca2010-04-28 20:12:276034 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:576035 EXPECT_EQ(ERR_IO_PENDING, rv);
6036
6037 rv = callback1.WaitForResult();
6038 EXPECT_EQ(OK, rv);
6039
6040 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506041 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046042 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:576043
[email protected]f1f3f0f82011-10-01 20:38:106044 TestOldCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:576045
[email protected]f3cf9802011-10-28 18:44:586046 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]0877e3d2009-10-17 22:29:576047 EXPECT_EQ(ERR_IO_PENDING, rv);
6048
6049 rv = callback2.WaitForResult();
6050 EXPECT_EQ(OK, rv);
6051
6052 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506053 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:576054 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6055 EXPECT_EQ(100, response->headers->GetContentLength());
6056}
6057
6058// Test HTTPS connections going through a proxy that sends extra data.
6059TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]81cdfcd2010-10-16 00:49:006060 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:576061
6062 HttpRequestInfo request;
6063 request.method = "GET";
6064 request.url = GURL("https://www.google.com/");
6065 request.load_flags = 0;
6066
6067 MockRead proxy_reads[] = {
6068 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
6069 MockRead(false, OK)
6070 };
6071
[email protected]31a2bfe2010-02-09 08:03:396072 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]5ecc992a42009-11-11 01:41:596073 SSLSocketDataProvider ssl(true, OK);
[email protected]0877e3d2009-10-17 22:29:576074
[email protected]5ecc992a42009-11-11 01:41:596075 session_deps.socket_factory.AddSocketDataProvider(&data);
6076 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:576077
[email protected]f1f3f0f82011-10-01 20:38:106078 TestOldCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:576079
6080 session_deps.socket_factory.ResetNextMockIndexes();
6081
6082 scoped_ptr<HttpTransaction> trans(
6083 new HttpNetworkTransaction(CreateSession(&session_deps)));
6084
[email protected]5a1d7ca2010-04-28 20:12:276085 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:576086 EXPECT_EQ(ERR_IO_PENDING, rv);
6087
6088 rv = callback.WaitForResult();
6089 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6090}
6091
[email protected]e22e1362009-11-23 21:31:126092TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:466093 HttpRequestInfo request;
6094 request.method = "GET";
6095 request.url = GURL("http://www.google.com/");
6096 request.load_flags = 0;
6097
[email protected]cb9bf6ca2011-01-28 13:15:276098 SessionDependencies session_deps;
6099 scoped_ptr<HttpTransaction> trans(
6100 new HttpNetworkTransaction(CreateSession(&session_deps)));
6101
[email protected]e22e1362009-11-23 21:31:126102 MockRead data_reads[] = {
6103 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
6104 MockRead(false, OK),
6105 };
[email protected]9492e4a2010-02-24 00:58:466106
6107 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6108 session_deps.socket_factory.AddSocketDataProvider(&data);
6109
[email protected]f1f3f0f82011-10-01 20:38:106110 TestOldCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:466111
[email protected]5a1d7ca2010-04-28 20:12:276112 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:466113 EXPECT_EQ(ERR_IO_PENDING, rv);
6114
6115 EXPECT_EQ(OK, callback.WaitForResult());
6116
6117 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506118 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:466119
6120 EXPECT_TRUE(response->headers != NULL);
6121 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
6122
6123 std::string response_data;
6124 rv = ReadTransaction(trans.get(), &response_data);
[email protected]f001bd6a2011-12-08 04:31:376125 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
[email protected]e22e1362009-11-23 21:31:126126}
6127
[email protected]95d88ffe2010-02-04 21:25:336128TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]95d88ffe2010-02-04 21:25:336129 HttpRequestInfo request;
6130 request.method = "POST";
6131 request.url = GURL("http://www.google.com/upload");
6132 request.upload_data = new UploadData;
6133 request.load_flags = 0;
6134
[email protected]cb9bf6ca2011-01-28 13:15:276135 SessionDependencies session_deps;
6136 scoped_ptr<HttpTransaction> trans(
6137 new HttpNetworkTransaction(CreateSession(&session_deps)));
6138
[email protected]95d88ffe2010-02-04 21:25:336139 FilePath temp_file_path;
6140 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
6141 const uint64 kFakeSize = 100000; // file is actually blank
6142
6143 std::vector<UploadData::Element> elements;
6144 UploadData::Element element;
6145 element.SetToFilePath(temp_file_path);
6146 element.SetContentLength(kFakeSize);
6147 elements.push_back(element);
[email protected]9349cfb2010-08-31 18:00:536148 request.upload_data->SetElements(elements);
[email protected]95d88ffe2010-02-04 21:25:336149 EXPECT_EQ(kFakeSize, request.upload_data->GetContentLength());
6150
6151 MockRead data_reads[] = {
6152 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
6153 MockRead("hello world"),
6154 MockRead(false, OK),
6155 };
[email protected]31a2bfe2010-02-09 08:03:396156 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]95d88ffe2010-02-04 21:25:336157 session_deps.socket_factory.AddSocketDataProvider(&data);
6158
[email protected]f1f3f0f82011-10-01 20:38:106159 TestOldCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:336160
[email protected]5a1d7ca2010-04-28 20:12:276161 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:336162 EXPECT_EQ(ERR_IO_PENDING, rv);
6163
6164 rv = callback.WaitForResult();
6165 EXPECT_EQ(OK, rv);
6166
6167 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506168 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:336169
6170 EXPECT_TRUE(response->headers != NULL);
6171 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
6172
6173 std::string response_data;
6174 rv = ReadTransaction(trans.get(), &response_data);
6175 EXPECT_EQ(OK, rv);
6176 EXPECT_EQ("hello world", response_data);
6177
6178 file_util::Delete(temp_file_path, false);
6179}
6180
[email protected]6624b4622010-03-29 19:58:366181TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]cb9bf6ca2011-01-28 13:15:276182 HttpRequestInfo request;
6183 request.method = "POST";
6184 request.url = GURL("http://www.google.com/upload");
6185 request.upload_data = new UploadData;
6186 request.load_flags = 0;
6187
[email protected]6624b4622010-03-29 19:58:366188 // If we try to upload an unreadable file, the network stack should report
6189 // the file size as zero and upload zero bytes for that file.
6190 SessionDependencies session_deps;
6191 scoped_ptr<HttpTransaction> trans(
6192 new HttpNetworkTransaction(CreateSession(&session_deps)));
6193
6194 FilePath temp_file;
6195 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
6196 std::string temp_file_content("Unreadable file.");
6197 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
6198 temp_file_content.length()));
6199 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
6200
[email protected]6624b4622010-03-29 19:58:366201 std::vector<UploadData::Element> elements;
6202 UploadData::Element element;
6203 element.SetToFilePath(temp_file);
6204 elements.push_back(element);
[email protected]9349cfb2010-08-31 18:00:536205 request.upload_data->SetElements(elements);
[email protected]6624b4622010-03-29 19:58:366206
6207 MockRead data_reads[] = {
6208 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
6209 MockRead(false, OK),
6210 };
6211 MockWrite data_writes[] = {
6212 MockWrite("POST /upload HTTP/1.1\r\n"
6213 "Host: www.google.com\r\n"
6214 "Connection: keep-alive\r\n"
6215 "Content-Length: 0\r\n\r\n"),
6216 MockWrite(false, OK),
6217 };
6218 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6219 arraysize(data_writes));
6220 session_deps.socket_factory.AddSocketDataProvider(&data);
6221
[email protected]f1f3f0f82011-10-01 20:38:106222 TestOldCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:366223
[email protected]5a1d7ca2010-04-28 20:12:276224 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]6624b4622010-03-29 19:58:366225 EXPECT_EQ(ERR_IO_PENDING, rv);
6226
6227 rv = callback.WaitForResult();
6228 EXPECT_EQ(OK, rv);
6229
6230 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506231 ASSERT_TRUE(response != NULL);
[email protected]6624b4622010-03-29 19:58:366232 EXPECT_TRUE(response->headers != NULL);
6233 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
6234
6235 file_util::Delete(temp_file, false);
6236}
6237
6238TEST_F(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
[email protected]cb9bf6ca2011-01-28 13:15:276239 HttpRequestInfo request;
6240 request.method = "POST";
6241 request.url = GURL("http://www.google.com/upload");
6242 request.upload_data = new UploadData;
6243 request.load_flags = 0;
6244
[email protected]6624b4622010-03-29 19:58:366245 SessionDependencies session_deps;
6246 scoped_ptr<HttpTransaction> trans(
6247 new HttpNetworkTransaction(CreateSession(&session_deps)));
6248
6249 FilePath temp_file;
6250 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
6251 std::string temp_file_contents("Unreadable file.");
6252 std::string unreadable_contents(temp_file_contents.length(), '\0');
6253 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
6254 temp_file_contents.length()));
6255
[email protected]6624b4622010-03-29 19:58:366256 std::vector<UploadData::Element> elements;
6257 UploadData::Element element;
6258 element.SetToFilePath(temp_file);
6259 elements.push_back(element);
[email protected]9349cfb2010-08-31 18:00:536260 request.upload_data->SetElements(elements);
[email protected]6624b4622010-03-29 19:58:366261
6262 MockRead data_reads[] = {
6263 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
6264 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6265 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
6266
6267 MockRead("HTTP/1.1 200 OK\r\n"),
6268 MockRead("Content-Length: 0\r\n\r\n"),
6269 MockRead(false, OK),
6270 };
6271 MockWrite data_writes[] = {
6272 MockWrite("POST /upload HTTP/1.1\r\n"
6273 "Host: www.google.com\r\n"
6274 "Connection: keep-alive\r\n"
6275 "Content-Length: 16\r\n\r\n"),
6276 MockWrite(false, temp_file_contents.c_str()),
6277
6278 MockWrite("POST /upload HTTP/1.1\r\n"
6279 "Host: www.google.com\r\n"
6280 "Connection: keep-alive\r\n"
6281 "Content-Length: 16\r\n"
6282 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
6283 MockWrite(false, unreadable_contents.c_str(), temp_file_contents.length()),
6284 MockWrite(false, OK),
6285 };
6286 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6287 arraysize(data_writes));
6288 session_deps.socket_factory.AddSocketDataProvider(&data);
6289
[email protected]f1f3f0f82011-10-01 20:38:106290 TestOldCompletionCallback callback1;
[email protected]6624b4622010-03-29 19:58:366291
[email protected]5a1d7ca2010-04-28 20:12:276292 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]6624b4622010-03-29 19:58:366293 EXPECT_EQ(ERR_IO_PENDING, rv);
6294
6295 rv = callback1.WaitForResult();
6296 EXPECT_EQ(OK, rv);
6297
6298 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:046299 ASSERT_TRUE(response != NULL);
6300 ASSERT_TRUE(response->headers != NULL);
[email protected]6624b4622010-03-29 19:58:366301 EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
[email protected]79cb5c12011-09-12 13:12:046302 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]6624b4622010-03-29 19:58:366303
6304 // Now make the file unreadable and try again.
6305 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
6306
[email protected]f1f3f0f82011-10-01 20:38:106307 TestOldCompletionCallback callback2;
[email protected]6624b4622010-03-29 19:58:366308
[email protected]f3cf9802011-10-28 18:44:586309 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback2);
[email protected]6624b4622010-03-29 19:58:366310 EXPECT_EQ(ERR_IO_PENDING, rv);
6311
6312 rv = callback2.WaitForResult();
6313 EXPECT_EQ(OK, rv);
6314
6315 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506316 ASSERT_TRUE(response != NULL);
[email protected]6624b4622010-03-29 19:58:366317 EXPECT_TRUE(response->headers != NULL);
6318 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6319 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6320
6321 file_util::Delete(temp_file, false);
6322}
6323
[email protected]aeefc9e82010-02-19 16:18:276324// Tests that changes to Auth realms are treated like auth rejections.
6325TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
6326 SessionDependencies session_deps;
[email protected]aeefc9e82010-02-19 16:18:276327
6328 HttpRequestInfo request;
6329 request.method = "GET";
6330 request.url = GURL("http://www.google.com/");
6331 request.load_flags = 0;
6332
6333 // First transaction will request a resource and receive a Basic challenge
6334 // with realm="first_realm".
6335 MockWrite data_writes1[] = {
6336 MockWrite("GET / HTTP/1.1\r\n"
6337 "Host: www.google.com\r\n"
6338 "Connection: keep-alive\r\n"
6339 "\r\n"),
6340 };
6341 MockRead data_reads1[] = {
6342 MockRead("HTTP/1.1 401 Unauthorized\r\n"
6343 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
6344 "\r\n"),
6345 };
6346
6347 // After calling trans->RestartWithAuth(), provide an Authentication header
6348 // for first_realm. The server will reject and provide a challenge with
6349 // second_realm.
6350 MockWrite data_writes2[] = {
6351 MockWrite("GET / HTTP/1.1\r\n"
6352 "Host: www.google.com\r\n"
6353 "Connection: keep-alive\r\n"
6354 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
6355 "\r\n"),
6356 };
6357 MockRead data_reads2[] = {
6358 MockRead("HTTP/1.1 401 Unauthorized\r\n"
6359 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
6360 "\r\n"),
6361 };
6362
6363 // This again fails, and goes back to first_realm. Make sure that the
6364 // entry is removed from cache.
6365 MockWrite data_writes3[] = {
6366 MockWrite("GET / HTTP/1.1\r\n"
6367 "Host: www.google.com\r\n"
6368 "Connection: keep-alive\r\n"
6369 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
6370 "\r\n"),
6371 };
6372 MockRead data_reads3[] = {
6373 MockRead("HTTP/1.1 401 Unauthorized\r\n"
6374 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
6375 "\r\n"),
6376 };
6377
6378 // Try one last time (with the correct password) and get the resource.
6379 MockWrite data_writes4[] = {
6380 MockWrite("GET / HTTP/1.1\r\n"
6381 "Host: www.google.com\r\n"
6382 "Connection: keep-alive\r\n"
6383 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
6384 "\r\n"),
6385 };
6386 MockRead data_reads4[] = {
6387 MockRead("HTTP/1.1 200 OK\r\n"
6388 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:506389 "Content-Length: 5\r\n"
6390 "\r\n"
6391 "hello"),
[email protected]aeefc9e82010-02-19 16:18:276392 };
6393
6394 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6395 data_writes1, arraysize(data_writes1));
6396 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6397 data_writes2, arraysize(data_writes2));
6398 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6399 data_writes3, arraysize(data_writes3));
6400 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
6401 data_writes4, arraysize(data_writes4));
6402 session_deps.socket_factory.AddSocketDataProvider(&data1);
6403 session_deps.socket_factory.AddSocketDataProvider(&data2);
6404 session_deps.socket_factory.AddSocketDataProvider(&data3);
6405 session_deps.socket_factory.AddSocketDataProvider(&data4);
6406
[email protected]f1f3f0f82011-10-01 20:38:106407 TestOldCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:276408
[email protected]0b0bf032010-09-21 18:08:506409 scoped_ptr<HttpTransaction> trans(
6410 new HttpNetworkTransaction(CreateSession(&session_deps)));
6411
[email protected]aeefc9e82010-02-19 16:18:276412 // Issue the first request with Authorize headers. There should be a
6413 // password prompt for first_realm waiting to be filled in after the
6414 // transaction completes.
[email protected]5a1d7ca2010-04-28 20:12:276415 int rv = trans->Start(&request, &callback1, BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:276416 EXPECT_EQ(ERR_IO_PENDING, rv);
6417 rv = callback1.WaitForResult();
6418 EXPECT_EQ(OK, rv);
6419 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506420 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046421 const AuthChallengeInfo* challenge = response->auth_challenge.get();
6422 ASSERT_FALSE(challenge == NULL);
6423 EXPECT_FALSE(challenge->is_proxy);
6424 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
6425 EXPECT_EQ("first_realm", challenge->realm);
6426 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:276427
6428 // Issue the second request with an incorrect password. There should be a
6429 // password prompt for second_realm waiting to be filled in after the
6430 // transaction completes.
[email protected]f1f3f0f82011-10-01 20:38:106431 TestOldCompletionCallback callback2;
[email protected]f3cf9802011-10-28 18:44:586432 rv = trans->RestartWithAuth(AuthCredentials(kFirst, kBaz), &callback2);
[email protected]aeefc9e82010-02-19 16:18:276433 EXPECT_EQ(ERR_IO_PENDING, rv);
6434 rv = callback2.WaitForResult();
6435 EXPECT_EQ(OK, rv);
6436 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506437 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046438 challenge = response->auth_challenge.get();
6439 ASSERT_FALSE(challenge == NULL);
6440 EXPECT_FALSE(challenge->is_proxy);
6441 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
6442 EXPECT_EQ("second_realm", challenge->realm);
6443 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:276444
6445 // Issue the third request with another incorrect password. There should be
6446 // a password prompt for first_realm waiting to be filled in. If the password
6447 // prompt is not present, it indicates that the HttpAuthCacheEntry for
6448 // first_realm was not correctly removed.
[email protected]f1f3f0f82011-10-01 20:38:106449 TestOldCompletionCallback callback3;
[email protected]f3cf9802011-10-28 18:44:586450 rv = trans->RestartWithAuth(AuthCredentials(kSecond, kFou), &callback3);
[email protected]aeefc9e82010-02-19 16:18:276451 EXPECT_EQ(ERR_IO_PENDING, rv);
6452 rv = callback3.WaitForResult();
6453 EXPECT_EQ(OK, rv);
6454 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506455 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046456 challenge = response->auth_challenge.get();
6457 ASSERT_FALSE(challenge == NULL);
6458 EXPECT_FALSE(challenge->is_proxy);
6459 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
6460 EXPECT_EQ("first_realm", challenge->realm);
6461 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:276462
6463 // Issue the fourth request with the correct password and username.
[email protected]f1f3f0f82011-10-01 20:38:106464 TestOldCompletionCallback callback4;
[email protected]f3cf9802011-10-28 18:44:586465 rv = trans->RestartWithAuth(AuthCredentials(kFirst, kBar), &callback4);
[email protected]aeefc9e82010-02-19 16:18:276466 EXPECT_EQ(ERR_IO_PENDING, rv);
6467 rv = callback4.WaitForResult();
6468 EXPECT_EQ(OK, rv);
6469 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506470 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:276471 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6472}
6473
[email protected]564b4912010-03-09 16:30:426474TEST_F(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]5285d972011-10-18 18:56:346475 HttpStreamFactory::set_next_protos(MakeNextProtos("foo", "bar", NULL));
[email protected]8e6441ca2010-08-19 05:56:386476 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:426477
[email protected]564b4912010-03-09 16:30:426478 SessionDependencies session_deps;
6479
6480 MockRead data_reads[] = {
6481 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]dae22c52010-07-30 02:16:356482 MockRead(kAlternateProtocolHttpHeader),
[email protected]564b4912010-03-09 16:30:426483 MockRead("hello world"),
6484 MockRead(false, OK),
6485 };
6486
6487 HttpRequestInfo request;
6488 request.method = "GET";
6489 request.url = GURL("http://www.google.com/");
6490 request.load_flags = 0;
6491
6492 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6493
6494 session_deps.socket_factory.AddSocketDataProvider(&data);
6495
[email protected]f1f3f0f82011-10-01 20:38:106496 TestOldCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:426497
6498 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
6499 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
6500
[email protected]5a1d7ca2010-04-28 20:12:276501 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]564b4912010-03-09 16:30:426502 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:536503
[email protected]2fbaecf22010-07-22 22:20:356504 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]17291a022011-10-10 07:32:536505 const HttpServerProperties& http_server_properties =
6506 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:426507 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:536508 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:426509
6510 EXPECT_EQ(OK, callback.WaitForResult());
6511
6512 const HttpResponseInfo* response = trans->GetResponseInfo();
6513 ASSERT_TRUE(response != NULL);
6514 ASSERT_TRUE(response->headers != NULL);
6515 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:536516 EXPECT_FALSE(response->was_fetched_via_spdy);
6517 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:426518
6519 std::string response_data;
6520 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
6521 EXPECT_EQ("hello world", response_data);
6522
[email protected]17291a022011-10-10 07:32:536523 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
6524 const PortAlternateProtocolPair alternate =
6525 http_server_properties.GetAlternateProtocol(http_host_port_pair);
6526 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:426527 expected_alternate.port = 443;
[email protected]17291a022011-10-10 07:32:536528 expected_alternate.protocol = NPN_SPDY_2;
[email protected]564b4912010-03-09 16:30:426529 EXPECT_TRUE(expected_alternate.Equals(alternate));
[email protected]a2cb8122010-03-10 17:22:426530
[email protected]8e6441ca2010-08-19 05:56:386531 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]5285d972011-10-18 18:56:346532 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]564b4912010-03-09 16:30:426533}
6534
[email protected]8b95ed62011-03-18 18:12:036535TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:386536 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:426537 SessionDependencies session_deps;
6538
6539 HttpRequestInfo request;
6540 request.method = "GET";
6541 request.url = GURL("http://www.google.com/");
6542 request.load_flags = 0;
6543
6544 MockConnect mock_connect(true, ERR_CONNECTION_REFUSED);
6545 StaticSocketDataProvider first_data;
6546 first_data.set_connect_data(mock_connect);
6547 session_deps.socket_factory.AddSocketDataProvider(&first_data);
6548
6549 MockRead data_reads[] = {
6550 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
6551 MockRead("hello world"),
6552 MockRead(true, OK),
6553 };
6554 StaticSocketDataProvider second_data(
6555 data_reads, arraysize(data_reads), NULL, 0);
6556 session_deps.socket_factory.AddSocketDataProvider(&second_data);
6557
[email protected]564b4912010-03-09 16:30:426558 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
6559
[email protected]17291a022011-10-10 07:32:536560 HttpServerProperties* http_server_properties =
6561 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:116562 // Port must be < 1024, or the header will be ignored (since initial port was
6563 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:536564 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:116565 HostPortPair::FromURL(request.url),
6566 666 /* port is ignored by MockConnect anyway */,
[email protected]17291a022011-10-10 07:32:536567 NPN_SPDY_2);
[email protected]564b4912010-03-09 16:30:426568
6569 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]3912662a32011-10-04 00:51:116570 TestOldCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:426571
[email protected]5a1d7ca2010-04-28 20:12:276572 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]564b4912010-03-09 16:30:426573 EXPECT_EQ(ERR_IO_PENDING, rv);
6574 EXPECT_EQ(OK, callback.WaitForResult());
6575
6576 const HttpResponseInfo* response = trans->GetResponseInfo();
6577 ASSERT_TRUE(response != NULL);
6578 ASSERT_TRUE(response->headers != NULL);
6579 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6580
6581 std::string response_data;
6582 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
6583 EXPECT_EQ("hello world", response_data);
6584
[email protected]17291a022011-10-10 07:32:536585 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:116586 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:536587 const PortAlternateProtocolPair alternate =
6588 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:116589 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:536590 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]8e6441ca2010-08-19 05:56:386591 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]564b4912010-03-09 16:30:426592}
6593
[email protected]3912662a32011-10-04 00:51:116594TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
6595 // Ensure that we're not allowed to redirect traffic via an alternate
6596 // protocol to an unrestricted (port >= 1024) when the original traffic was
6597 // on a restricted port (port < 1024). Ensure that we can redirect in all
6598 // other cases.
6599 HttpStreamFactory::set_use_alternate_protocols(true);
6600 SessionDependencies session_deps;
6601
6602 HttpRequestInfo restricted_port_request;
6603 restricted_port_request.method = "GET";
6604 restricted_port_request.url = GURL("http://www.google.com:1023/");
6605 restricted_port_request.load_flags = 0;
6606
6607 MockConnect mock_connect(true, ERR_CONNECTION_REFUSED);
6608 StaticSocketDataProvider first_data;
6609 first_data.set_connect_data(mock_connect);
6610 session_deps.socket_factory.AddSocketDataProvider(&first_data);
6611
6612 MockRead data_reads[] = {
6613 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
6614 MockRead("hello world"),
6615 MockRead(true, OK),
6616 };
6617 StaticSocketDataProvider second_data(
6618 data_reads, arraysize(data_reads), NULL, 0);
6619 session_deps.socket_factory.AddSocketDataProvider(&second_data);
6620
6621 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
6622
[email protected]17291a022011-10-10 07:32:536623 HttpServerProperties* http_server_properties =
6624 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:116625 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:536626 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:116627 HostPortPair::FromURL(restricted_port_request.url),
6628 kUnrestrictedAlternatePort,
[email protected]17291a022011-10-10 07:32:536629 NPN_SPDY_2);
[email protected]3912662a32011-10-04 00:51:116630
6631 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
6632 TestOldCompletionCallback callback;
6633
6634 int rv = trans->Start(&restricted_port_request, &callback, BoundNetLog());
6635 EXPECT_EQ(ERR_IO_PENDING, rv);
6636 // Invalid change to unrestricted port should fail.
6637 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
6638
6639 HttpStreamFactory::set_use_alternate_protocols(false);
6640}
6641
6642TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
6643 // Ensure that we're not allowed to redirect traffic via an alternate
6644 // protocol to an unrestricted (port >= 1024) when the original traffic was
6645 // on a restricted port (port < 1024). Ensure that we can redirect in all
6646 // other cases.
6647 HttpStreamFactory::set_use_alternate_protocols(true);
6648 SessionDependencies session_deps;
6649
6650 HttpRequestInfo restricted_port_request;
6651 restricted_port_request.method = "GET";
6652 restricted_port_request.url = GURL("http://www.google.com:1023/");
6653 restricted_port_request.load_flags = 0;
6654
6655 MockConnect mock_connect(true, ERR_CONNECTION_REFUSED);
6656 StaticSocketDataProvider first_data;
6657 first_data.set_connect_data(mock_connect);
6658 session_deps.socket_factory.AddSocketDataProvider(&first_data);
6659
6660 MockRead data_reads[] = {
6661 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
6662 MockRead("hello world"),
6663 MockRead(true, OK),
6664 };
6665 StaticSocketDataProvider second_data(
6666 data_reads, arraysize(data_reads), NULL, 0);
6667 session_deps.socket_factory.AddSocketDataProvider(&second_data);
6668
6669 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
6670
[email protected]17291a022011-10-10 07:32:536671 HttpServerProperties* http_server_properties =
6672 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:116673 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:536674 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:116675 HostPortPair::FromURL(restricted_port_request.url),
6676 kRestrictedAlternatePort,
[email protected]17291a022011-10-10 07:32:536677 NPN_SPDY_2);
[email protected]3912662a32011-10-04 00:51:116678
6679 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
6680 TestOldCompletionCallback callback;
6681
6682 int rv = trans->Start(&restricted_port_request, &callback, BoundNetLog());
6683 EXPECT_EQ(ERR_IO_PENDING, rv);
6684 // Valid change to restricted port should pass.
6685 EXPECT_EQ(OK, callback.WaitForResult());
6686
6687 HttpStreamFactory::set_use_alternate_protocols(false);
6688}
6689
6690TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
6691 // Ensure that we're not allowed to redirect traffic via an alternate
6692 // protocol to an unrestricted (port >= 1024) when the original traffic was
6693 // on a restricted port (port < 1024). Ensure that we can redirect in all
6694 // other cases.
6695 HttpStreamFactory::set_use_alternate_protocols(true);
6696 SessionDependencies session_deps;
6697
6698 HttpRequestInfo unrestricted_port_request;
6699 unrestricted_port_request.method = "GET";
6700 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
6701 unrestricted_port_request.load_flags = 0;
6702
6703 MockConnect mock_connect(true, ERR_CONNECTION_REFUSED);
6704 StaticSocketDataProvider first_data;
6705 first_data.set_connect_data(mock_connect);
6706 session_deps.socket_factory.AddSocketDataProvider(&first_data);
6707
6708 MockRead data_reads[] = {
6709 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
6710 MockRead("hello world"),
6711 MockRead(true, OK),
6712 };
6713 StaticSocketDataProvider second_data(
6714 data_reads, arraysize(data_reads), NULL, 0);
6715 session_deps.socket_factory.AddSocketDataProvider(&second_data);
6716
6717 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
6718
[email protected]17291a022011-10-10 07:32:536719 HttpServerProperties* http_server_properties =
6720 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:116721 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:536722 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:116723 HostPortPair::FromURL(unrestricted_port_request.url),
6724 kRestrictedAlternatePort,
[email protected]17291a022011-10-10 07:32:536725 NPN_SPDY_2);
[email protected]3912662a32011-10-04 00:51:116726
6727 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
6728 TestOldCompletionCallback callback;
6729
6730 int rv = trans->Start(&unrestricted_port_request, &callback, BoundNetLog());
6731 EXPECT_EQ(ERR_IO_PENDING, rv);
6732 // Valid change to restricted port should pass.
6733 EXPECT_EQ(OK, callback.WaitForResult());
6734
6735 HttpStreamFactory::set_use_alternate_protocols(false);
6736}
6737
6738TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
6739 // Ensure that we're not allowed to redirect traffic via an alternate
6740 // protocol to an unrestricted (port >= 1024) when the original traffic was
6741 // on a restricted port (port < 1024). Ensure that we can redirect in all
6742 // other cases.
6743 HttpStreamFactory::set_use_alternate_protocols(true);
6744 SessionDependencies session_deps;
6745
6746 HttpRequestInfo unrestricted_port_request;
6747 unrestricted_port_request.method = "GET";
6748 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
6749 unrestricted_port_request.load_flags = 0;
6750
6751 MockConnect mock_connect(true, ERR_CONNECTION_REFUSED);
6752 StaticSocketDataProvider first_data;
6753 first_data.set_connect_data(mock_connect);
6754 session_deps.socket_factory.AddSocketDataProvider(&first_data);
6755
6756 MockRead data_reads[] = {
6757 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
6758 MockRead("hello world"),
6759 MockRead(true, OK),
6760 };
6761 StaticSocketDataProvider second_data(
6762 data_reads, arraysize(data_reads), NULL, 0);
6763 session_deps.socket_factory.AddSocketDataProvider(&second_data);
6764
6765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
6766
[email protected]17291a022011-10-10 07:32:536767 HttpServerProperties* http_server_properties =
6768 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:116769 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:536770 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:116771 HostPortPair::FromURL(unrestricted_port_request.url),
6772 kUnrestrictedAlternatePort,
[email protected]17291a022011-10-10 07:32:536773 NPN_SPDY_2);
[email protected]3912662a32011-10-04 00:51:116774
6775 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
6776 TestOldCompletionCallback callback;
6777
6778 int rv = trans->Start(&unrestricted_port_request, &callback, BoundNetLog());
6779 EXPECT_EQ(ERR_IO_PENDING, rv);
6780 // Valid change to an unrestricted port should pass.
6781 EXPECT_EQ(OK, callback.WaitForResult());
6782
6783 HttpStreamFactory::set_use_alternate_protocols(false);
6784}
6785
[email protected]2ff8b312010-04-26 22:20:546786TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:386787 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:346788 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:546789 SessionDependencies session_deps;
6790
6791 HttpRequestInfo request;
6792 request.method = "GET";
6793 request.url = GURL("http://www.google.com/");
6794 request.load_flags = 0;
6795
6796 MockRead data_reads[] = {
6797 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]dae22c52010-07-30 02:16:356798 MockRead(kAlternateProtocolHttpHeader),
[email protected]2ff8b312010-04-26 22:20:546799 MockRead("hello world"),
6800 MockRead(true, OK),
6801 };
6802
6803 StaticSocketDataProvider first_transaction(
6804 data_reads, arraysize(data_reads), NULL, 0);
6805 session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
6806
6807 SSLSocketDataProvider ssl(true, OK);
6808 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
[email protected]dae22c52010-07-30 02:16:356809 ssl.next_proto = "spdy/2";
[email protected]65041fa2010-05-21 06:56:536810 ssl.was_npn_negotiated = true;
[email protected]2ff8b312010-04-26 22:20:546811 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
6812
[email protected]2bd93022010-07-17 00:58:446813 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
[email protected]e7f75092010-07-01 22:39:136814 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:546815
[email protected]2bd93022010-07-17 00:58:446816 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
6817 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:546818 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:136819 CreateMockRead(*resp),
6820 CreateMockRead(*data),
[email protected]2ff8b312010-04-26 22:20:546821 MockRead(true, 0, 0),
6822 };
6823
6824 scoped_refptr<DelayedSocketData> spdy_data(
6825 new DelayedSocketData(
6826 1, // wait for one write to finish before reading.
6827 spdy_reads, arraysize(spdy_reads),
6828 spdy_writes, arraysize(spdy_writes)));
6829 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
6830
[email protected]2d6728692011-03-12 01:39:556831 MockConnect never_finishing_connect(false, ERR_IO_PENDING);
6832 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
6833 NULL, 0, NULL, 0);
6834 hanging_non_alternate_protocol_socket.set_connect_data(
6835 never_finishing_connect);
6836 session_deps.socket_factory.AddSocketDataProvider(
6837 &hanging_non_alternate_protocol_socket);
6838
[email protected]f1f3f0f82011-10-01 20:38:106839 TestOldCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:546840
6841 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
6842 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
6843
[email protected]5a1d7ca2010-04-28 20:12:276844 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:546845 EXPECT_EQ(ERR_IO_PENDING, rv);
6846 EXPECT_EQ(OK, callback.WaitForResult());
6847
6848 const HttpResponseInfo* response = trans->GetResponseInfo();
6849 ASSERT_TRUE(response != NULL);
6850 ASSERT_TRUE(response->headers != NULL);
6851 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6852
6853 std::string response_data;
6854 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
6855 EXPECT_EQ("hello world", response_data);
6856
6857 trans.reset(new HttpNetworkTransaction(session));
6858
[email protected]5a1d7ca2010-04-28 20:12:276859 rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:546860 EXPECT_EQ(ERR_IO_PENDING, rv);
6861 EXPECT_EQ(OK, callback.WaitForResult());
6862
6863 response = trans->GetResponseInfo();
6864 ASSERT_TRUE(response != NULL);
6865 ASSERT_TRUE(response->headers != NULL);
6866 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:536867 EXPECT_TRUE(response->was_fetched_via_spdy);
6868 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:546869
6870 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
6871 EXPECT_EQ("hello!", response_data);
6872
[email protected]5285d972011-10-18 18:56:346873 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]8e6441ca2010-08-19 05:56:386874 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]2ff8b312010-04-26 22:20:546875}
6876
[email protected]2d6728692011-03-12 01:39:556877TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
6878 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:346879 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:556880 SessionDependencies session_deps;
6881
6882 HttpRequestInfo request;
6883 request.method = "GET";
6884 request.url = GURL("http://www.google.com/");
6885 request.load_flags = 0;
6886
6887 MockRead data_reads[] = {
6888 MockRead("HTTP/1.1 200 OK\r\n"),
6889 MockRead(kAlternateProtocolHttpHeader),
6890 MockRead("hello world"),
6891 MockRead(true, OK),
6892 };
6893
6894 StaticSocketDataProvider first_transaction(
6895 data_reads, arraysize(data_reads), NULL, 0);
6896 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
6897 session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
6898
6899 MockConnect never_finishing_connect(false, ERR_IO_PENDING);
6900 StaticSocketDataProvider hanging_socket(
6901 NULL, 0, NULL, 0);
6902 hanging_socket.set_connect_data(never_finishing_connect);
6903 // Socket 2 and 3 are the hanging Alternate-Protocol and
6904 // non-Alternate-Protocol jobs from the 2nd transaction.
6905 session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
6906 session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
6907
6908 SSLSocketDataProvider ssl(true, OK);
6909 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
6910 ssl.next_proto = "spdy/2";
6911 ssl.was_npn_negotiated = true;
6912 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
6913
6914 scoped_ptr<spdy::SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
6915 scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
6916 MockWrite spdy_writes[] = {
6917 CreateMockWrite(*req1),
6918 CreateMockWrite(*req2),
6919 };
6920 scoped_ptr<spdy::SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
6921 scoped_ptr<spdy::SpdyFrame> data1(ConstructSpdyBodyFrame(1, true));
6922 scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
6923 scoped_ptr<spdy::SpdyFrame> data2(ConstructSpdyBodyFrame(3, true));
6924 MockRead spdy_reads[] = {
6925 CreateMockRead(*resp1),
6926 CreateMockRead(*data1),
6927 CreateMockRead(*resp2),
6928 CreateMockRead(*data2),
6929 MockRead(true, 0, 0),
6930 };
6931
6932 scoped_refptr<DelayedSocketData> spdy_data(
6933 new DelayedSocketData(
6934 2, // wait for writes to finish before reading.
6935 spdy_reads, arraysize(spdy_reads),
6936 spdy_writes, arraysize(spdy_writes)));
6937 // Socket 4 is the successful Alternate-Protocol for transaction 3.
6938 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
6939
6940 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
6941 session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
6942
6943 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]f1f3f0f82011-10-01 20:38:106944 TestOldCompletionCallback callback1;
[email protected]2d6728692011-03-12 01:39:556945 HttpNetworkTransaction trans1(session);
6946
6947 int rv = trans1.Start(&request, &callback1, BoundNetLog());
6948 EXPECT_EQ(ERR_IO_PENDING, rv);
6949 EXPECT_EQ(OK, callback1.WaitForResult());
6950
6951 const HttpResponseInfo* response = trans1.GetResponseInfo();
6952 ASSERT_TRUE(response != NULL);
6953 ASSERT_TRUE(response->headers != NULL);
6954 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6955
6956 std::string response_data;
6957 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
6958 EXPECT_EQ("hello world", response_data);
6959
[email protected]f1f3f0f82011-10-01 20:38:106960 TestOldCompletionCallback callback2;
[email protected]2d6728692011-03-12 01:39:556961 HttpNetworkTransaction trans2(session);
6962 rv = trans2.Start(&request, &callback2, BoundNetLog());
6963 EXPECT_EQ(ERR_IO_PENDING, rv);
6964
[email protected]f1f3f0f82011-10-01 20:38:106965 TestOldCompletionCallback callback3;
[email protected]2d6728692011-03-12 01:39:556966 HttpNetworkTransaction trans3(session);
6967 rv = trans3.Start(&request, &callback3, BoundNetLog());
6968 EXPECT_EQ(ERR_IO_PENDING, rv);
6969
6970 EXPECT_EQ(OK, callback2.WaitForResult());
6971 EXPECT_EQ(OK, callback3.WaitForResult());
6972
6973 response = trans2.GetResponseInfo();
6974 ASSERT_TRUE(response != NULL);
6975 ASSERT_TRUE(response->headers != NULL);
6976 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6977 EXPECT_TRUE(response->was_fetched_via_spdy);
6978 EXPECT_TRUE(response->was_npn_negotiated);
6979 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
6980 EXPECT_EQ("hello!", response_data);
6981
6982 response = trans3.GetResponseInfo();
6983 ASSERT_TRUE(response != NULL);
6984 ASSERT_TRUE(response->headers != NULL);
6985 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6986 EXPECT_TRUE(response->was_fetched_via_spdy);
6987 EXPECT_TRUE(response->was_npn_negotiated);
6988 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
6989 EXPECT_EQ("hello!", response_data);
6990
[email protected]5285d972011-10-18 18:56:346991 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]2d6728692011-03-12 01:39:556992 HttpStreamFactory::set_use_alternate_protocols(false);
6993}
6994
6995TEST_F(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
6996 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:346997 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:556998 SessionDependencies session_deps;
6999
7000 HttpRequestInfo request;
7001 request.method = "GET";
7002 request.url = GURL("http://www.google.com/");
7003 request.load_flags = 0;
7004
7005 MockRead data_reads[] = {
7006 MockRead("HTTP/1.1 200 OK\r\n"),
7007 MockRead(kAlternateProtocolHttpHeader),
7008 MockRead("hello world"),
7009 MockRead(true, OK),
7010 };
7011
7012 StaticSocketDataProvider first_transaction(
7013 data_reads, arraysize(data_reads), NULL, 0);
7014 session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
7015
7016 SSLSocketDataProvider ssl(true, OK);
7017 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
7018 ssl.next_proto = "spdy/2";
7019 ssl.was_npn_negotiated = true;
7020 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
7021
7022 MockConnect never_finishing_connect(false, ERR_IO_PENDING);
7023 StaticSocketDataProvider hanging_alternate_protocol_socket(
7024 NULL, 0, NULL, 0);
7025 hanging_alternate_protocol_socket.set_connect_data(
7026 never_finishing_connect);
7027 session_deps.socket_factory.AddSocketDataProvider(
7028 &hanging_alternate_protocol_socket);
7029
7030 // 2nd request is just a copy of the first one, over HTTP again.
7031 session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
7032
[email protected]f1f3f0f82011-10-01 20:38:107033 TestOldCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:557034
7035 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
7036 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
7037
7038 int rv = trans->Start(&request, &callback, BoundNetLog());
7039 EXPECT_EQ(ERR_IO_PENDING, rv);
7040 EXPECT_EQ(OK, callback.WaitForResult());
7041
7042 const HttpResponseInfo* response = trans->GetResponseInfo();
7043 ASSERT_TRUE(response != NULL);
7044 ASSERT_TRUE(response->headers != NULL);
7045 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7046
7047 std::string response_data;
7048 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7049 EXPECT_EQ("hello world", response_data);
7050
7051 trans.reset(new HttpNetworkTransaction(session));
7052
7053 rv = trans->Start(&request, &callback, BoundNetLog());
7054 EXPECT_EQ(ERR_IO_PENDING, rv);
7055 EXPECT_EQ(OK, callback.WaitForResult());
7056
7057 response = trans->GetResponseInfo();
7058 ASSERT_TRUE(response != NULL);
7059 ASSERT_TRUE(response->headers != NULL);
7060 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7061 EXPECT_FALSE(response->was_fetched_via_spdy);
7062 EXPECT_FALSE(response->was_npn_negotiated);
7063
7064 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7065 EXPECT_EQ("hello world", response_data);
7066
[email protected]5285d972011-10-18 18:56:347067 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]2d6728692011-03-12 01:39:557068 HttpStreamFactory::set_use_alternate_protocols(false);
7069}
7070
[email protected]631f1322010-04-30 17:59:117071class CapturingProxyResolver : public ProxyResolver {
7072 public:
7073 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
7074 virtual ~CapturingProxyResolver() {}
7075
7076 virtual int GetProxyForURL(const GURL& url,
7077 ProxyInfo* results,
[email protected]f1f3f0f82011-10-01 20:38:107078 OldCompletionCallback* callback,
[email protected]631f1322010-04-30 17:59:117079 RequestHandle* request,
7080 const BoundNetLog& net_log) {
[email protected]fae7669f2010-08-02 21:49:407081 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
7082 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:427083 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:117084 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:427085 return OK;
[email protected]631f1322010-04-30 17:59:117086 }
7087
7088 virtual void CancelRequest(RequestHandle request) {
7089 NOTREACHED();
7090 }
7091
[email protected]f2c971f2011-11-08 00:33:177092 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
7093 NOTREACHED();
7094 return LOAD_STATE_IDLE;
7095 }
7096
7097 virtual LoadState GetLoadStateThreadSafe(
7098 RequestHandle request) const OVERRIDE {
7099 NOTREACHED();
7100 return LOAD_STATE_IDLE;
7101 }
7102
[email protected]1e605472010-12-16 21:41:407103 virtual void CancelSetPacScript() {
7104 NOTREACHED();
7105 }
7106
[email protected]24476402010-07-20 20:55:177107 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]f1f3f0f82011-10-01 20:38:107108 OldCompletionCallback* /*callback*/) {
[email protected]d911f1b2010-05-05 22:39:427109 return OK;
[email protected]631f1322010-04-30 17:59:117110 }
7111
[email protected]24476402010-07-20 20:55:177112 const std::vector<GURL>& resolved() const { return resolved_; }
7113
7114 private:
[email protected]631f1322010-04-30 17:59:117115 std::vector<GURL> resolved_;
7116
7117 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
7118};
7119
[email protected]631f1322010-04-30 17:59:117120TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:387121 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:347122 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:117123
7124 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:427125 proxy_config.set_auto_detect(true);
7126 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:117127
[email protected]631f1322010-04-30 17:59:117128 CapturingProxyResolver* capturing_proxy_resolver =
7129 new CapturingProxyResolver();
[email protected]66761b952010-06-25 21:30:387130 SessionDependencies session_deps(new ProxyService(
7131 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
7132 NULL));
[email protected]631f1322010-04-30 17:59:117133
7134 HttpRequestInfo request;
7135 request.method = "GET";
7136 request.url = GURL("http://www.google.com/");
7137 request.load_flags = 0;
7138
7139 MockRead data_reads[] = {
7140 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]dae22c52010-07-30 02:16:357141 MockRead(kAlternateProtocolHttpHeader),
[email protected]631f1322010-04-30 17:59:117142 MockRead("hello world"),
7143 MockRead(true, OK),
7144 };
7145
7146 StaticSocketDataProvider first_transaction(
7147 data_reads, arraysize(data_reads), NULL, 0);
7148 session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
7149
7150 SSLSocketDataProvider ssl(true, OK);
7151 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
[email protected]dae22c52010-07-30 02:16:357152 ssl.next_proto = "spdy/2";
[email protected]65041fa2010-05-21 06:56:537153 ssl.was_npn_negotiated = true;
[email protected]631f1322010-04-30 17:59:117154 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
7155
[email protected]2bd93022010-07-17 00:58:447156 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
[email protected]631f1322010-04-30 17:59:117157 MockWrite spdy_writes[] = {
7158 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
7159 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:427160 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]e7f75092010-07-01 22:39:137161 CreateMockWrite(*req) // 3
[email protected]631f1322010-04-30 17:59:117162 };
7163
[email protected]d911f1b2010-05-05 22:39:427164 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
7165
[email protected]2bd93022010-07-17 00:58:447166 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
7167 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:117168 MockRead spdy_reads[] = {
[email protected]d911f1b2010-05-05 22:39:427169 MockRead(true, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:137170 CreateMockRead(*resp.get(), 4), // 2, 4
7171 CreateMockRead(*data.get(), 4), // 5
[email protected]d911f1b2010-05-05 22:39:427172 MockRead(true, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:117173 };
7174
[email protected]d911f1b2010-05-05 22:39:427175 scoped_refptr<OrderedSocketData> spdy_data(
7176 new OrderedSocketData(
[email protected]631f1322010-04-30 17:59:117177 spdy_reads, arraysize(spdy_reads),
7178 spdy_writes, arraysize(spdy_writes)));
7179 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
7180
[email protected]2d6728692011-03-12 01:39:557181 MockConnect never_finishing_connect(false, ERR_IO_PENDING);
7182 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
7183 NULL, 0, NULL, 0);
7184 hanging_non_alternate_protocol_socket.set_connect_data(
7185 never_finishing_connect);
7186 session_deps.socket_factory.AddSocketDataProvider(
7187 &hanging_non_alternate_protocol_socket);
7188
[email protected]f1f3f0f82011-10-01 20:38:107189 TestOldCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:117190
7191 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
7192 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
7193
7194 int rv = trans->Start(&request, &callback, BoundNetLog());
7195 EXPECT_EQ(ERR_IO_PENDING, rv);
7196 EXPECT_EQ(OK, callback.WaitForResult());
7197
7198 const HttpResponseInfo* response = trans->GetResponseInfo();
7199 ASSERT_TRUE(response != NULL);
7200 ASSERT_TRUE(response->headers != NULL);
7201 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:537202 EXPECT_FALSE(response->was_fetched_via_spdy);
7203 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:117204
7205 std::string response_data;
7206 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7207 EXPECT_EQ("hello world", response_data);
7208
7209 trans.reset(new HttpNetworkTransaction(session));
7210
7211 rv = trans->Start(&request, &callback, BoundNetLog());
7212 EXPECT_EQ(ERR_IO_PENDING, rv);
7213 EXPECT_EQ(OK, callback.WaitForResult());
7214
7215 response = trans->GetResponseInfo();
7216 ASSERT_TRUE(response != NULL);
7217 ASSERT_TRUE(response->headers != NULL);
7218 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:537219 EXPECT_TRUE(response->was_fetched_via_spdy);
7220 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:117221
7222 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7223 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:557224 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:427225 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:117226 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:427227 EXPECT_EQ("https://www.google.com/",
7228 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:117229
[email protected]5285d972011-10-18 18:56:347230 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]8e6441ca2010-08-19 05:56:387231 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]631f1322010-04-30 17:59:117232}
[email protected]631f1322010-04-30 17:59:117233
[email protected]2ff8b312010-04-26 22:20:547234TEST_F(HttpNetworkTransactionTest,
7235 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:387236 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:347237 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:547238 SessionDependencies session_deps;
7239
7240 HttpRequestInfo request;
7241 request.method = "GET";
7242 request.url = GURL("http://www.google.com/");
7243 request.load_flags = 0;
7244
7245 MockRead data_reads[] = {
7246 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]dae22c52010-07-30 02:16:357247 MockRead(kAlternateProtocolHttpHeader),
[email protected]2ff8b312010-04-26 22:20:547248 MockRead("hello world"),
7249 MockRead(true, OK),
7250 };
7251
7252 StaticSocketDataProvider first_transaction(
7253 data_reads, arraysize(data_reads), NULL, 0);
7254 session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
7255
7256 SSLSocketDataProvider ssl(true, OK);
7257 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
[email protected]dae22c52010-07-30 02:16:357258 ssl.next_proto = "spdy/2";
[email protected]65041fa2010-05-21 06:56:537259 ssl.was_npn_negotiated = true;
[email protected]2ff8b312010-04-26 22:20:547260 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:537261 // Make sure we use ssl for spdy here.
7262 SpdySession::SetSSLMode(true);
[email protected]2ff8b312010-04-26 22:20:547263
[email protected]2bd93022010-07-17 00:58:447264 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
[email protected]e7f75092010-07-01 22:39:137265 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:547266
[email protected]2bd93022010-07-17 00:58:447267 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
7268 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:547269 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:137270 CreateMockRead(*resp),
7271 CreateMockRead(*data),
[email protected]2ff8b312010-04-26 22:20:547272 MockRead(true, 0, 0),
7273 };
7274
7275 scoped_refptr<DelayedSocketData> spdy_data(
7276 new DelayedSocketData(
7277 1, // wait for one write to finish before reading.
7278 spdy_reads, arraysize(spdy_reads),
7279 spdy_writes, arraysize(spdy_writes)));
7280 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
7281
[email protected]83039bb2011-12-09 18:43:557282 TestOldCompletionCallback callback_old;
7283 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:547284
7285 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
7286
7287 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
7288
[email protected]83039bb2011-12-09 18:43:557289 int rv = trans->Start(&request, &callback_old, BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:547290 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]83039bb2011-12-09 18:43:557291 EXPECT_EQ(OK, callback_old.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:547292
7293 const HttpResponseInfo* response = trans->GetResponseInfo();
7294 ASSERT_TRUE(response != NULL);
7295 ASSERT_TRUE(response->headers != NULL);
7296 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7297
7298 std::string response_data;
7299 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7300 EXPECT_EQ("hello world", response_data);
7301
7302 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:387303 HostPortPair host_port_pair("www.google.com", 443);
7304 HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
[email protected]2ff8b312010-04-26 22:20:547305 scoped_refptr<SpdySession> spdy_session =
[email protected]102e27c2011-02-23 01:01:317306 session->spdy_session_pool()->Get(pair, BoundNetLog());
[email protected]ab739042011-04-07 15:22:287307 scoped_refptr<TransportSocketParams> transport_params(
[email protected]acdda412011-11-15 21:21:297308 new TransportSocketParams(host_port_pair, MEDIUM, false, false));
[email protected]02b0c342010-09-25 21:09:387309
7310 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
7311 EXPECT_EQ(ERR_IO_PENDING,
[email protected]ab739042011-04-07 15:22:287312 connection->Init(host_port_pair.ToString(),
7313 transport_params,
7314 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:527315 callback.callback(),
[email protected]a42dbd142011-11-17 16:42:027316 session->GetTransportSocketPool(),
[email protected]02b0c342010-09-25 21:09:387317 BoundNetLog()));
[email protected]6ecf2b92011-12-15 01:14:527318 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]02b0c342010-09-25 21:09:387319
7320 SSLConfig ssl_config;
7321 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]9e1bdd32011-02-03 21:48:347322 scoped_ptr<ClientSocketHandle> ssl_connection(new ClientSocketHandle);
[email protected]feb79bcd2011-07-21 16:55:177323 SSLClientSocketContext context;
7324 context.cert_verifier = session_deps.cert_verifier.get();
[email protected]9e1bdd32011-02-03 21:48:347325 ssl_connection->set_socket(session_deps.socket_factory.CreateSSLClientSocket(
7326 connection.release(), HostPortPair("" , 443), ssl_config,
[email protected]feb79bcd2011-07-21 16:55:177327 NULL /* ssl_host_info */, context));
[email protected]83039bb2011-12-09 18:43:557328 EXPECT_EQ(ERR_IO_PENDING,
7329 ssl_connection->socket()->Connect(callback.callback()));
[email protected]02b0c342010-09-25 21:09:387330 EXPECT_EQ(OK, callback.WaitForResult());
7331
[email protected]9e1bdd32011-02-03 21:48:347332 EXPECT_EQ(OK, spdy_session->InitializeWithSocket(ssl_connection.release(),
[email protected]02b0c342010-09-25 21:09:387333 true, OK));
7334
[email protected]2ff8b312010-04-26 22:20:547335 trans.reset(new HttpNetworkTransaction(session));
7336
[email protected]83039bb2011-12-09 18:43:557337 rv = trans->Start(&request, &callback_old, BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:547338 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]83039bb2011-12-09 18:43:557339 EXPECT_EQ(OK, callback_old.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:547340
7341 response = trans->GetResponseInfo();
7342 ASSERT_TRUE(response != NULL);
7343 ASSERT_TRUE(response->headers != NULL);
7344 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:537345 EXPECT_TRUE(response->was_fetched_via_spdy);
7346 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:547347
7348 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7349 EXPECT_EQ("hello!", response_data);
7350
[email protected]5285d972011-10-18 18:56:347351 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]8e6441ca2010-08-19 05:56:387352 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]564b4912010-03-09 16:30:427353}
7354
[email protected]044de0642010-06-17 10:42:157355// GenerateAuthToken is a mighty big test.
7356// It tests all permutation of GenerateAuthToken behavior:
7357// - Synchronous and Asynchronous completion.
7358// - OK or error on completion.
7359// - Direct connection, non-authenticating proxy, and authenticating proxy.
7360// - HTTP or HTTPS backend (to include proxy tunneling).
7361// - Non-authenticating and authenticating backend.
7362//
[email protected]767257802011-12-14 17:33:187363// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:157364// problems generating an auth token for an authenticating proxy, we don't
7365// need to test all permutations of the backend server).
7366//
7367// The test proceeds by going over each of the configuration cases, and
7368// potentially running up to three rounds in each of the tests. The TestConfig
7369// specifies both the configuration for the test as well as the expectations
7370// for the results.
7371TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:507372 static const char kServer[] = "http://www.example.com";
7373 static const char kSecureServer[] = "https://www.example.com";
7374 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:157375 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
7376
7377 enum AuthTiming {
7378 AUTH_NONE,
7379 AUTH_SYNC,
7380 AUTH_ASYNC,
7381 };
7382
7383 const MockWrite kGet(
7384 "GET / HTTP/1.1\r\n"
7385 "Host: www.example.com\r\n"
7386 "Connection: keep-alive\r\n\r\n");
7387 const MockWrite kGetProxy(
7388 "GET http://www.example.com/ HTTP/1.1\r\n"
7389 "Host: www.example.com\r\n"
7390 "Proxy-Connection: keep-alive\r\n\r\n");
7391 const MockWrite kGetAuth(
7392 "GET / HTTP/1.1\r\n"
7393 "Host: www.example.com\r\n"
7394 "Connection: keep-alive\r\n"
7395 "Authorization: auth_token\r\n\r\n");
7396 const MockWrite kGetProxyAuth(
7397 "GET http://www.example.com/ HTTP/1.1\r\n"
7398 "Host: www.example.com\r\n"
7399 "Proxy-Connection: keep-alive\r\n"
7400 "Proxy-Authorization: auth_token\r\n\r\n");
7401 const MockWrite kGetAuthThroughProxy(
7402 "GET http://www.example.com/ HTTP/1.1\r\n"
7403 "Host: www.example.com\r\n"
7404 "Proxy-Connection: keep-alive\r\n"
7405 "Authorization: auth_token\r\n\r\n");
7406 const MockWrite kGetAuthWithProxyAuth(
7407 "GET http://www.example.com/ HTTP/1.1\r\n"
7408 "Host: www.example.com\r\n"
7409 "Proxy-Connection: keep-alive\r\n"
7410 "Proxy-Authorization: auth_token\r\n"
7411 "Authorization: auth_token\r\n\r\n");
7412 const MockWrite kConnect(
7413 "CONNECT www.example.com:443 HTTP/1.1\r\n"
7414 "Host: www.example.com\r\n"
7415 "Proxy-Connection: keep-alive\r\n\r\n");
7416 const MockWrite kConnectProxyAuth(
7417 "CONNECT www.example.com:443 HTTP/1.1\r\n"
7418 "Host: www.example.com\r\n"
7419 "Proxy-Connection: keep-alive\r\n"
7420 "Proxy-Authorization: auth_token\r\n\r\n");
7421
7422 const MockRead kSuccess(
7423 "HTTP/1.1 200 OK\r\n"
7424 "Content-Type: text/html; charset=iso-8859-1\r\n"
7425 "Content-Length: 3\r\n\r\n"
7426 "Yes");
7427 const MockRead kFailure(
7428 "Should not be called.");
7429 const MockRead kServerChallenge(
7430 "HTTP/1.1 401 Unauthorized\r\n"
7431 "WWW-Authenticate: Mock realm=server\r\n"
7432 "Content-Type: text/html; charset=iso-8859-1\r\n"
7433 "Content-Length: 14\r\n\r\n"
7434 "Unauthorized\r\n");
7435 const MockRead kProxyChallenge(
7436 "HTTP/1.1 407 Unauthorized\r\n"
7437 "Proxy-Authenticate: Mock realm=proxy\r\n"
7438 "Proxy-Connection: close\r\n"
7439 "Content-Type: text/html; charset=iso-8859-1\r\n"
7440 "Content-Length: 14\r\n\r\n"
7441 "Unauthorized\r\n");
7442 const MockRead kProxyConnected(
7443 "HTTP/1.1 200 Connection Established\r\n\r\n");
7444
7445 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
7446 // no constructors, but the C++ compiler on Windows warns about
7447 // unspecified data in compound literals. So, moved to using constructors,
7448 // and TestRound's created with the default constructor should not be used.
7449 struct TestRound {
7450 TestRound()
7451 : expected_rv(ERR_UNEXPECTED),
7452 extra_write(NULL),
7453 extra_read(NULL) {
7454 }
7455 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
7456 int expected_rv_arg)
7457 : write(write_arg),
7458 read(read_arg),
7459 expected_rv(expected_rv_arg),
7460 extra_write(NULL),
7461 extra_read(NULL) {
7462 }
7463 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
7464 int expected_rv_arg, const MockWrite* extra_write_arg,
7465 const MockWrite* extra_read_arg)
7466 : write(write_arg),
7467 read(read_arg),
7468 expected_rv(expected_rv_arg),
7469 extra_write(extra_write_arg),
7470 extra_read(extra_read_arg) {
7471 }
7472 MockWrite write;
7473 MockRead read;
7474 int expected_rv;
7475 const MockWrite* extra_write;
7476 const MockRead* extra_read;
7477 };
7478
7479 static const int kNoSSL = 500;
7480
7481 struct TestConfig {
7482 const char* proxy_url;
7483 AuthTiming proxy_auth_timing;
7484 int proxy_auth_rv;
7485 const char* server_url;
7486 AuthTiming server_auth_timing;
7487 int server_auth_rv;
7488 int num_auth_rounds;
7489 int first_ssl_round;
7490 TestRound rounds[3];
7491 } test_configs[] = {
7492 // Non-authenticating HTTP server with a direct connection.
7493 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
7494 { TestRound(kGet, kSuccess, OK)}},
7495 // Authenticating HTTP server with a direct connection.
7496 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
7497 { TestRound(kGet, kServerChallenge, OK),
7498 TestRound(kGetAuth, kSuccess, OK)}},
7499 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
7500 { TestRound(kGet, kServerChallenge, OK),
7501 TestRound(kGetAuth, kFailure, kAuthErr)}},
7502 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
7503 { TestRound(kGet, kServerChallenge, OK),
7504 TestRound(kGetAuth, kSuccess, OK)}},
7505 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
7506 { TestRound(kGet, kServerChallenge, OK),
7507 TestRound(kGetAuth, kFailure, kAuthErr)}},
7508 // Non-authenticating HTTP server through a non-authenticating proxy.
7509 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
7510 { TestRound(kGetProxy, kSuccess, OK)}},
7511 // Authenticating HTTP server through a non-authenticating proxy.
7512 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
7513 { TestRound(kGetProxy, kServerChallenge, OK),
7514 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
7515 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
7516 { TestRound(kGetProxy, kServerChallenge, OK),
7517 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
7518 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
7519 { TestRound(kGetProxy, kServerChallenge, OK),
7520 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
7521 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
7522 { TestRound(kGetProxy, kServerChallenge, OK),
7523 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
7524 // Non-authenticating HTTP server through an authenticating proxy.
7525 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
7526 { TestRound(kGetProxy, kProxyChallenge, OK),
7527 TestRound(kGetProxyAuth, kSuccess, OK)}},
7528 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
7529 { TestRound(kGetProxy, kProxyChallenge, OK),
7530 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
7531 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
7532 { TestRound(kGetProxy, kProxyChallenge, OK),
7533 TestRound(kGetProxyAuth, kSuccess, OK)}},
7534 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
7535 { TestRound(kGetProxy, kProxyChallenge, OK),
7536 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
7537 // Authenticating HTTP server through an authenticating proxy.
7538 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
7539 { TestRound(kGetProxy, kProxyChallenge, OK),
7540 TestRound(kGetProxyAuth, kServerChallenge, OK),
7541 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
7542 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
7543 { TestRound(kGetProxy, kProxyChallenge, OK),
7544 TestRound(kGetProxyAuth, kServerChallenge, OK),
7545 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
7546 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
7547 { TestRound(kGetProxy, kProxyChallenge, OK),
7548 TestRound(kGetProxyAuth, kServerChallenge, OK),
7549 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
7550 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
7551 { TestRound(kGetProxy, kProxyChallenge, OK),
7552 TestRound(kGetProxyAuth, kServerChallenge, OK),
7553 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
7554 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
7555 { TestRound(kGetProxy, kProxyChallenge, OK),
7556 TestRound(kGetProxyAuth, kServerChallenge, OK),
7557 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
7558 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
7559 { TestRound(kGetProxy, kProxyChallenge, OK),
7560 TestRound(kGetProxyAuth, kServerChallenge, OK),
7561 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
7562 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
7563 { TestRound(kGetProxy, kProxyChallenge, OK),
7564 TestRound(kGetProxyAuth, kServerChallenge, OK),
7565 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
7566 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
7567 { TestRound(kGetProxy, kProxyChallenge, OK),
7568 TestRound(kGetProxyAuth, kServerChallenge, OK),
7569 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
7570 // Non-authenticating HTTPS server with a direct connection.
7571 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
7572 { TestRound(kGet, kSuccess, OK)}},
7573 // Authenticating HTTPS server with a direct connection.
7574 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
7575 { TestRound(kGet, kServerChallenge, OK),
7576 TestRound(kGetAuth, kSuccess, OK)}},
7577 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
7578 { TestRound(kGet, kServerChallenge, OK),
7579 TestRound(kGetAuth, kFailure, kAuthErr)}},
7580 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
7581 { TestRound(kGet, kServerChallenge, OK),
7582 TestRound(kGetAuth, kSuccess, OK)}},
7583 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
7584 { TestRound(kGet, kServerChallenge, OK),
7585 TestRound(kGetAuth, kFailure, kAuthErr)}},
7586 // Non-authenticating HTTPS server with a non-authenticating proxy.
7587 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
7588 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
7589 // Authenticating HTTPS server through a non-authenticating proxy.
7590 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
7591 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
7592 TestRound(kGetAuth, kSuccess, OK)}},
7593 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
7594 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
7595 TestRound(kGetAuth, kFailure, kAuthErr)}},
7596 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
7597 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
7598 TestRound(kGetAuth, kSuccess, OK)}},
7599 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
7600 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
7601 TestRound(kGetAuth, kFailure, kAuthErr)}},
7602 // Non-Authenticating HTTPS server through an authenticating proxy.
7603 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
7604 { TestRound(kConnect, kProxyChallenge, OK),
7605 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
7606 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
7607 { TestRound(kConnect, kProxyChallenge, OK),
7608 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
7609 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
7610 { TestRound(kConnect, kProxyChallenge, OK),
7611 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
7612 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
7613 { TestRound(kConnect, kProxyChallenge, OK),
7614 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
7615 // Authenticating HTTPS server through an authenticating proxy.
7616 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
7617 { TestRound(kConnect, kProxyChallenge, OK),
7618 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7619 &kGet, &kServerChallenge),
7620 TestRound(kGetAuth, kSuccess, OK)}},
7621 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
7622 { TestRound(kConnect, kProxyChallenge, OK),
7623 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7624 &kGet, &kServerChallenge),
7625 TestRound(kGetAuth, kFailure, kAuthErr)}},
7626 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
7627 { TestRound(kConnect, kProxyChallenge, OK),
7628 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7629 &kGet, &kServerChallenge),
7630 TestRound(kGetAuth, kSuccess, OK)}},
7631 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
7632 { TestRound(kConnect, kProxyChallenge, OK),
7633 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7634 &kGet, &kServerChallenge),
7635 TestRound(kGetAuth, kFailure, kAuthErr)}},
7636 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
7637 { TestRound(kConnect, kProxyChallenge, OK),
7638 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7639 &kGet, &kServerChallenge),
7640 TestRound(kGetAuth, kSuccess, OK)}},
7641 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
7642 { TestRound(kConnect, kProxyChallenge, OK),
7643 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7644 &kGet, &kServerChallenge),
7645 TestRound(kGetAuth, kFailure, kAuthErr)}},
7646 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
7647 { TestRound(kConnect, kProxyChallenge, OK),
7648 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7649 &kGet, &kServerChallenge),
7650 TestRound(kGetAuth, kSuccess, OK)}},
7651 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
7652 { TestRound(kConnect, kProxyChallenge, OK),
7653 TestRound(kConnectProxyAuth, kProxyConnected, OK,
7654 &kGet, &kServerChallenge),
7655 TestRound(kGetAuth, kFailure, kAuthErr)}},
7656 };
7657
7658 SessionDependencies session_deps;
[email protected]044de0642010-06-17 10:42:157659 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:087660 HttpAuthHandlerMock::Factory* auth_factory(
7661 new HttpAuthHandlerMock::Factory());
7662 session_deps.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:157663 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:267664
7665 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:157666 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:087667 for (int n = 0; n < 2; n++) {
7668 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
7669 std::string auth_challenge = "Mock realm=proxy";
7670 GURL origin(test_config.proxy_url);
7671 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
7672 auth_challenge.end());
7673 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
7674 origin, BoundNetLog());
7675 auth_handler->SetGenerateExpectation(
7676 test_config.proxy_auth_timing == AUTH_ASYNC,
7677 test_config.proxy_auth_rv);
7678 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
7679 }
[email protected]044de0642010-06-17 10:42:157680 }
7681 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:007682 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:157683 std::string auth_challenge = "Mock realm=server";
7684 GURL origin(test_config.server_url);
7685 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
7686 auth_challenge.end());
7687 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
7688 origin, BoundNetLog());
7689 auth_handler->SetGenerateExpectation(
7690 test_config.server_auth_timing == AUTH_ASYNC,
7691 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:087692 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:157693 }
7694 if (test_config.proxy_url) {
[email protected]6104ea5d2011-04-27 21:37:127695 session_deps.proxy_service.reset(
7696 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:157697 } else {
[email protected]6104ea5d2011-04-27 21:37:127698 session_deps.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:157699 }
7700
7701 HttpRequestInfo request;
7702 request.method = "GET";
7703 request.url = GURL(test_config.server_url);
7704 request.load_flags = 0;
7705
[email protected]0b0bf032010-09-21 18:08:507706 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
7707 HttpNetworkTransaction trans(CreateSession(&session_deps));
[email protected]044de0642010-06-17 10:42:157708
7709 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
7710 const TestRound& read_write_round = test_config.rounds[round];
7711
7712 // Set up expected reads and writes.
7713 MockRead reads[2];
7714 reads[0] = read_write_round.read;
7715 size_t length_reads = 1;
7716 if (read_write_round.extra_read) {
7717 reads[1] = *read_write_round.extra_read;
7718 length_reads = 2;
7719 }
7720
7721 MockWrite writes[2];
7722 writes[0] = read_write_round.write;
7723 size_t length_writes = 1;
7724 if (read_write_round.extra_write) {
7725 writes[1] = *read_write_round.extra_write;
7726 length_writes = 2;
7727 }
7728 StaticSocketDataProvider data_provider(
7729 reads, length_reads, writes, length_writes);
7730 session_deps.socket_factory.AddSocketDataProvider(&data_provider);
7731
7732 // Add an SSL sequence if necessary.
7733 SSLSocketDataProvider ssl_socket_data_provider(false, OK);
7734 if (round >= test_config.first_ssl_round)
7735 session_deps.socket_factory.AddSSLSocketDataProvider(
7736 &ssl_socket_data_provider);
7737
7738 // Start or restart the transaction.
[email protected]f1f3f0f82011-10-01 20:38:107739 TestOldCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:157740 int rv;
7741 if (round == 0) {
[email protected]0b0bf032010-09-21 18:08:507742 rv = trans.Start(&request, &callback, BoundNetLog());
[email protected]044de0642010-06-17 10:42:157743 } else {
[email protected]f3cf9802011-10-28 18:44:587744 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), &callback);
[email protected]044de0642010-06-17 10:42:157745 }
7746 if (rv == ERR_IO_PENDING)
7747 rv = callback.WaitForResult();
7748
7749 // Compare results with expected data.
7750 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:507751 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:157752 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:507753 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:157754 } else {
7755 EXPECT_TRUE(response == NULL);
7756 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
7757 continue;
7758 }
7759 if (round + 1 < test_config.num_auth_rounds) {
7760 EXPECT_FALSE(response->auth_challenge.get() == NULL);
7761 } else {
7762 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7763 }
7764 }
[email protected]e5ae96a2010-04-14 20:12:457765 }
7766}
7767
[email protected]c871bce92010-07-15 21:51:147768TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
7769 // Do multi-round authentication and make sure it works correctly.
7770 SessionDependencies session_deps;
7771 HttpAuthHandlerMock::Factory* auth_factory(
7772 new HttpAuthHandlerMock::Factory());
7773 session_deps.http_auth_handler_factory.reset(auth_factory);
[email protected]6104ea5d2011-04-27 21:37:127774 session_deps.proxy_service.reset(ProxyService::CreateDirect());
[email protected]c871bce92010-07-15 21:51:147775 session_deps.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
7776 session_deps.host_resolver->set_synchronous_mode(true);
7777
7778 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
7779 auth_handler->set_connection_based(true);
7780 std::string auth_challenge = "Mock realm=server";
7781 GURL origin("http://www.example.com");
7782 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
7783 auth_challenge.end());
7784 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
7785 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:087786 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:147787
[email protected]c871bce92010-07-15 21:51:147788 int rv = OK;
7789 const HttpResponseInfo* response = NULL;
7790 HttpRequestInfo request;
7791 request.method = "GET";
7792 request.url = origin;
7793 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:277794
7795 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]7ef4cbbb2011-02-06 11:19:107796
7797 // Use a TCP Socket Pool with only one connection per group. This is used
7798 // to validate that the TCP socket is not released to the pool between
7799 // each round of multi-round authentication.
7800 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:287801 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
7802 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:107803 50, // Max sockets for pool
7804 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:287805 &transport_pool_histograms,
[email protected]7ef4cbbb2011-02-06 11:19:107806 session_deps.host_resolver.get(),
7807 &session_deps.socket_factory,
7808 session_deps.net_log);
[email protected]a42dbd142011-11-17 16:42:027809 MockClientSocketPoolManager* mock_pool_manager =
7810 new MockClientSocketPoolManager;
7811 mock_pool_manager->SetTransportSocketPool(transport_pool);
7812 session_peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]7ef4cbbb2011-02-06 11:19:107813
[email protected]cb9bf6ca2011-01-28 13:15:277814 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]f1f3f0f82011-10-01 20:38:107815 TestOldCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:147816
7817 const MockWrite kGet(
7818 "GET / HTTP/1.1\r\n"
7819 "Host: www.example.com\r\n"
7820 "Connection: keep-alive\r\n\r\n");
7821 const MockWrite kGetAuth(
7822 "GET / HTTP/1.1\r\n"
7823 "Host: www.example.com\r\n"
7824 "Connection: keep-alive\r\n"
7825 "Authorization: auth_token\r\n\r\n");
7826
7827 const MockRead kServerChallenge(
7828 "HTTP/1.1 401 Unauthorized\r\n"
7829 "WWW-Authenticate: Mock realm=server\r\n"
7830 "Content-Type: text/html; charset=iso-8859-1\r\n"
7831 "Content-Length: 14\r\n\r\n"
7832 "Unauthorized\r\n");
7833 const MockRead kSuccess(
7834 "HTTP/1.1 200 OK\r\n"
7835 "Content-Type: text/html; charset=iso-8859-1\r\n"
7836 "Content-Length: 3\r\n\r\n"
7837 "Yes");
7838
7839 MockWrite writes[] = {
7840 // First round
7841 kGet,
7842 // Second round
7843 kGetAuth,
7844 // Third round
7845 kGetAuth,
[email protected]eca50e122010-09-11 14:03:307846 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:107847 kGetAuth,
7848 // Competing request
7849 kGet,
[email protected]c871bce92010-07-15 21:51:147850 };
7851 MockRead reads[] = {
7852 // First round
7853 kServerChallenge,
7854 // Second round
7855 kServerChallenge,
7856 // Third round
[email protected]eca50e122010-09-11 14:03:307857 kServerChallenge,
7858 // Fourth round
[email protected]c871bce92010-07-15 21:51:147859 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:107860 // Competing response
7861 kSuccess,
[email protected]c871bce92010-07-15 21:51:147862 };
7863 StaticSocketDataProvider data_provider(reads, arraysize(reads),
7864 writes, arraysize(writes));
7865 session_deps.socket_factory.AddSocketDataProvider(&data_provider);
7866
[email protected]7ef4cbbb2011-02-06 11:19:107867 const char* const kSocketGroup = "www.example.com:80";
7868
7869 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:147870 auth_handler->SetGenerateExpectation(false, OK);
7871 rv = trans->Start(&request, &callback, BoundNetLog());
7872 if (rv == ERR_IO_PENDING)
7873 rv = callback.WaitForResult();
7874 EXPECT_EQ(OK, rv);
7875 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507876 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:147877 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:287878 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:147879
[email protected]7ef4cbbb2011-02-06 11:19:107880 // In between rounds, another request comes in for the same domain.
7881 // It should not be able to grab the TCP socket that trans has already
7882 // claimed.
7883 scoped_ptr<HttpTransaction> trans_compete(
7884 new HttpNetworkTransaction(session));
[email protected]f1f3f0f82011-10-01 20:38:107885 TestOldCompletionCallback callback_compete;
[email protected]7ef4cbbb2011-02-06 11:19:107886 rv = trans_compete->Start(&request, &callback_compete, BoundNetLog());
7887 EXPECT_EQ(ERR_IO_PENDING, rv);
7888 // callback_compete.WaitForResult at this point would stall forever,
7889 // since the HttpNetworkTransaction does not release the request back to
7890 // the pool until after authentication completes.
7891
7892 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:147893 auth_handler->SetGenerateExpectation(false, OK);
[email protected]f3cf9802011-10-28 18:44:587894 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback);
[email protected]c871bce92010-07-15 21:51:147895 if (rv == ERR_IO_PENDING)
7896 rv = callback.WaitForResult();
7897 EXPECT_EQ(OK, rv);
7898 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507899 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:147900 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:287901 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:147902
[email protected]7ef4cbbb2011-02-06 11:19:107903 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:147904 auth_handler->SetGenerateExpectation(false, OK);
[email protected]f3cf9802011-10-28 18:44:587905 rv = trans->RestartWithAuth(AuthCredentials(), &callback);
[email protected]c871bce92010-07-15 21:51:147906 if (rv == ERR_IO_PENDING)
7907 rv = callback.WaitForResult();
7908 EXPECT_EQ(OK, rv);
7909 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507910 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:147911 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:287912 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:307913
[email protected]7ef4cbbb2011-02-06 11:19:107914 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:307915 auth_handler->SetGenerateExpectation(false, OK);
[email protected]f3cf9802011-10-28 18:44:587916 rv = trans->RestartWithAuth(AuthCredentials(), &callback);
[email protected]eca50e122010-09-11 14:03:307917 if (rv == ERR_IO_PENDING)
7918 rv = callback.WaitForResult();
7919 EXPECT_EQ(OK, rv);
7920 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507921 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:307922 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:287923 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:107924
7925 // Read the body since the fourth round was successful. This will also
7926 // release the socket back to the pool.
7927 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
7928 rv = trans->Read(io_buf, io_buf->size(), &callback);
7929 if (rv == ERR_IO_PENDING)
7930 rv = callback.WaitForResult();
7931 EXPECT_EQ(3, rv);
7932 rv = trans->Read(io_buf, io_buf->size(), &callback);
7933 EXPECT_EQ(0, rv);
7934 // There are still 0 idle sockets, since the trans_compete transaction
7935 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:287936 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:107937
7938 // The competing request can now finish. Wait for the headers and then
7939 // read the body.
7940 rv = callback_compete.WaitForResult();
7941 EXPECT_EQ(OK, rv);
7942 rv = trans_compete->Read(io_buf, io_buf->size(), &callback);
7943 if (rv == ERR_IO_PENDING)
7944 rv = callback.WaitForResult();
7945 EXPECT_EQ(3, rv);
7946 rv = trans_compete->Read(io_buf, io_buf->size(), &callback);
7947 EXPECT_EQ(0, rv);
7948
7949 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:287950 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:147951}
7952
[email protected]aeaca1f2010-04-20 22:05:217953class TLSDecompressionFailureSocketDataProvider : public SocketDataProvider {
7954 public:
[email protected]06650c52010-06-03 00:49:177955 explicit TLSDecompressionFailureSocketDataProvider(bool fail_all)
[email protected]aeaca1f2010-04-20 22:05:217956 : fail_all_(fail_all) {
7957 }
7958
7959 virtual MockRead GetNextRead() {
7960 if (fail_all_)
7961 return MockRead(false /* async */, ERR_SSL_DECOMPRESSION_FAILURE_ALERT);
7962
7963 return MockRead(false /* async */,
7964 "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nok.\r\n");
7965 }
7966
7967 virtual MockWriteResult OnWrite(const std::string& data) {
7968 return MockWriteResult(false /* async */, data.size());
7969 }
7970
7971 void Reset() {
7972 }
7973
7974 private:
7975 const bool fail_all_;
7976};
7977
7978// Test that we restart a connection when we see a decompression failure from
7979// the peer during the handshake. (In the real world we'll restart with SSLv3
7980// and we won't offer DEFLATE in that case.)
7981TEST_F(HttpNetworkTransactionTest, RestartAfterTLSDecompressionFailure) {
7982 HttpRequestInfo request;
7983 request.method = "GET";
7984 request.url = GURL("https://tlsdecompressionfailure.example.com/");
7985 request.load_flags = 0;
7986
7987 SessionDependencies session_deps;
7988 TLSDecompressionFailureSocketDataProvider socket_data_provider1(
7989 false /* fail all reads */);
7990 TLSDecompressionFailureSocketDataProvider socket_data_provider2(false);
7991 SSLSocketDataProvider ssl_socket_data_provider1(
[email protected]2227c692010-05-04 15:36:117992 false, ERR_SSL_DECOMPRESSION_FAILURE_ALERT);
[email protected]aeaca1f2010-04-20 22:05:217993 SSLSocketDataProvider ssl_socket_data_provider2(false, OK);
7994 session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1);
7995 session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2);
7996 session_deps.socket_factory.AddSSLSocketDataProvider(
7997 &ssl_socket_data_provider1);
7998 session_deps.socket_factory.AddSSLSocketDataProvider(
7999 &ssl_socket_data_provider2);
8000
[email protected]e60e47a2010-07-14 03:37:188001 // Work around http://crbug.com/37454
8002 StaticSocketDataProvider bug37454_connection;
8003 bug37454_connection.set_connect_data(MockConnect(true, ERR_UNEXPECTED));
8004 session_deps.socket_factory.AddSocketDataProvider(&bug37454_connection);
8005
[email protected]aeaca1f2010-04-20 22:05:218006 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8007 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]f1f3f0f82011-10-01 20:38:108008 TestOldCompletionCallback callback;
[email protected]aeaca1f2010-04-20 22:05:218009
[email protected]5a1d7ca2010-04-28 20:12:278010 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]aeaca1f2010-04-20 22:05:218011 EXPECT_EQ(ERR_IO_PENDING, rv);
8012 EXPECT_EQ(OK, callback.WaitForResult());
8013
8014 const HttpResponseInfo* response = trans->GetResponseInfo();
8015 ASSERT_TRUE(response != NULL);
8016 ASSERT_TRUE(response->headers != NULL);
8017 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8018
8019 std::string response_data;
8020 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8021 EXPECT_EQ("ok.", response_data);
8022}
8023
8024// Test that we restart a connection if we get a decompression failure from the
8025// peer while reading the first bytes from the connection. This occurs when the
8026// peer cannot handle DEFLATE but we're using False Start, so we don't notice
8027// in the handshake.
8028TEST_F(HttpNetworkTransactionTest,
8029 RestartAfterTLSDecompressionFailureWithFalseStart) {
8030 HttpRequestInfo request;
8031 request.method = "GET";
8032 request.url = GURL("https://tlsdecompressionfailure2.example.com/");
8033 request.load_flags = 0;
8034
8035 SessionDependencies session_deps;
8036 TLSDecompressionFailureSocketDataProvider socket_data_provider1(
8037 true /* fail all reads */);
8038 TLSDecompressionFailureSocketDataProvider socket_data_provider2(false);
8039 SSLSocketDataProvider ssl_socket_data_provider1(false, OK);
8040 SSLSocketDataProvider ssl_socket_data_provider2(false, OK);
8041 session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1);
8042 session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2);
8043 session_deps.socket_factory.AddSSLSocketDataProvider(
8044 &ssl_socket_data_provider1);
8045 session_deps.socket_factory.AddSSLSocketDataProvider(
8046 &ssl_socket_data_provider2);
8047
8048 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8049 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
[email protected]f1f3f0f82011-10-01 20:38:108050 TestOldCompletionCallback callback;
[email protected]aeaca1f2010-04-20 22:05:218051
[email protected]5a1d7ca2010-04-28 20:12:278052 int rv = trans->Start(&request, &callback, BoundNetLog());
[email protected]aeaca1f2010-04-20 22:05:218053 EXPECT_EQ(ERR_IO_PENDING, rv);
8054 EXPECT_EQ(OK, callback.WaitForResult());
8055
8056 const HttpResponseInfo* response = trans->GetResponseInfo();
8057 ASSERT_TRUE(response != NULL);
8058 ASSERT_TRUE(response->headers != NULL);
8059 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8060
8061 std::string response_data;
8062 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8063 EXPECT_EQ("ok.", response_data);
8064}
8065
[email protected]65041fa2010-05-21 06:56:538066// This tests the case that a request is issued via http instead of spdy after
8067// npn is negotiated.
8068TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:388069 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:348070 HttpStreamFactory::set_next_protos(
8071 MakeNextProtos("http/1.1", "http1.1", NULL));
[email protected]65041fa2010-05-21 06:56:538072 SessionDependencies session_deps;
8073 HttpRequestInfo request;
8074 request.method = "GET";
8075 request.url = GURL("https://www.google.com/");
8076 request.load_flags = 0;
8077
8078 MockWrite data_writes[] = {
8079 MockWrite("GET / HTTP/1.1\r\n"
8080 "Host: www.google.com\r\n"
8081 "Connection: keep-alive\r\n\r\n"),
8082 };
8083
8084 MockRead data_reads[] = {
8085 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]dae22c52010-07-30 02:16:358086 MockRead(kAlternateProtocolHttpHeader),
[email protected]65041fa2010-05-21 06:56:538087 MockRead("hello world"),
8088 MockRead(false, OK),
8089 };
8090
8091 SSLSocketDataProvider ssl(true, OK);
8092 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
8093 ssl.next_proto = "http/1.1";
8094
8095 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
8096
8097 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8098 data_writes, arraysize(data_writes));
8099 session_deps.socket_factory.AddSocketDataProvider(&data);
8100
[email protected]f1f3f0f82011-10-01 20:38:108101 TestOldCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:538102
8103 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8104 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
8105
8106 int rv = trans->Start(&request, &callback, BoundNetLog());
8107
8108 EXPECT_EQ(ERR_IO_PENDING, rv);
8109 EXPECT_EQ(OK, callback.WaitForResult());
8110
8111 const HttpResponseInfo* response = trans->GetResponseInfo();
8112 ASSERT_TRUE(response != NULL);
8113 ASSERT_TRUE(response->headers != NULL);
8114 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8115
8116 std::string response_data;
8117 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8118 EXPECT_EQ("hello world", response_data);
8119
8120 EXPECT_FALSE(response->was_fetched_via_spdy);
8121 EXPECT_TRUE(response->was_npn_negotiated);
8122
[email protected]5285d972011-10-18 18:56:348123 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]8e6441ca2010-08-19 05:56:388124 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]65041fa2010-05-21 06:56:538125}
[email protected]26ef6582010-06-24 02:30:478126
8127TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
8128 // Simulate the SSL handshake completing with an NPN negotiation
8129 // followed by an immediate server closing of the socket.
8130 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:388131 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:348132 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:478133 SessionDependencies session_deps;
8134
8135 HttpRequestInfo request;
8136 request.method = "GET";
8137 request.url = GURL("https://www.google.com/");
8138 request.load_flags = 0;
8139
8140 SSLSocketDataProvider ssl(true, OK);
8141 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
[email protected]dae22c52010-07-30 02:16:358142 ssl.next_proto = "spdy/2";
[email protected]26ef6582010-06-24 02:30:478143 ssl.was_npn_negotiated = true;
8144 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
8145
[email protected]2bd93022010-07-17 00:58:448146 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
[email protected]e7f75092010-07-01 22:39:138147 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:478148
8149 MockRead spdy_reads[] = {
8150 MockRead(false, 0, 0) // Not async - return 0 immediately.
8151 };
8152
8153 scoped_refptr<DelayedSocketData> spdy_data(
8154 new DelayedSocketData(
8155 0, // don't wait in this case, immediate hangup.
8156 spdy_reads, arraysize(spdy_reads),
8157 spdy_writes, arraysize(spdy_writes)));
8158 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
8159
[email protected]f1f3f0f82011-10-01 20:38:108160 TestOldCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:478161
8162 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8163 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
8164
8165 int rv = trans->Start(&request, &callback, BoundNetLog());
8166 EXPECT_EQ(ERR_IO_PENDING, rv);
8167 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
8168
[email protected]5285d972011-10-18 18:56:348169 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]8e6441ca2010-08-19 05:56:388170 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]26ef6582010-06-24 02:30:478171}
[email protected]65d34382010-07-01 18:12:268172
[email protected]f45c1ee2010-08-03 00:54:308173TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
8174 // This test ensures that the URL passed into the proxy is upgraded
8175 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:388176 HttpStreamFactory::set_use_alternate_protocols(true);
8177 HttpStreamFactory::set_next_protos(
[email protected]42baef7a2011-12-10 04:52:108178 MakeNextProtos(
8179 "http/1.1", "http1.1", "spdy/2.1", "spdy/2", "spdy", NULL));
[email protected]f45c1ee2010-08-03 00:54:308180
[email protected]81cdfcd2010-10-16 00:49:008181 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]f45c1ee2010-08-03 00:54:308182 HttpAuthHandlerMock::Factory* auth_factory =
8183 new HttpAuthHandlerMock::Factory();
[email protected]767257802011-12-14 17:33:188184 HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock();
8185 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
[email protected]f45c1ee2010-08-03 00:54:308186 auth_factory->set_do_init_from_challenge(true);
8187 session_deps.http_auth_handler_factory.reset(auth_factory);
8188
8189 HttpRequestInfo request;
8190 request.method = "GET";
8191 request.url = GURL("http://www.google.com");
8192 request.load_flags = 0;
8193
8194 // First round goes unauthenticated through the proxy.
8195 MockWrite data_writes_1[] = {
8196 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
8197 "Host: www.google.com\r\n"
8198 "Proxy-Connection: keep-alive\r\n"
8199 "\r\n"),
8200 };
8201 MockRead data_reads_1[] = {
[email protected]394816e92010-08-03 07:38:598202 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:308203 MockRead("HTTP/1.1 200 OK\r\n"
8204 "Alternate-Protocol: 443:npn-spdy/2\r\n"
8205 "Proxy-Connection: close\r\n"
8206 "\r\n"),
8207 };
8208 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
8209 data_writes_1, arraysize(data_writes_1));
8210
8211 // Second round tries to tunnel to www.google.com due to the
8212 // Alternate-Protocol announcement in the first round. It fails due
8213 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:598214 // After the failure, a tunnel is established to www.google.com using
8215 // Proxy-Authorization headers. There is then a SPDY request round.
8216 //
[email protected]767257802011-12-14 17:33:188217 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
8218 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
8219 // does a Disconnect and Connect on the same socket, rather than trying
8220 // to obtain a new one.
8221 //
[email protected]394816e92010-08-03 07:38:598222 // NOTE: Originally, the proxy response to the second CONNECT request
8223 // simply returned another 407 so the unit test could skip the SSL connection
8224 // establishment and SPDY framing issues. Alas, the
8225 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:308226 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:598227
[email protected]f45c1ee2010-08-03 00:54:308228 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
8229 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
8230 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
8231
[email protected]394816e92010-08-03 07:38:598232 MockWrite data_writes_2[] = {
8233 // First connection attempt without Proxy-Authorization.
8234 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8235 "Host: www.google.com\r\n"
8236 "Proxy-Connection: keep-alive\r\n"
8237 "\r\n"),
8238
8239 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:308240 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8241 "Host: www.google.com\r\n"
8242 "Proxy-Connection: keep-alive\r\n"
8243 "Proxy-Authorization: auth_token\r\n"
8244 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:308245
[email protected]394816e92010-08-03 07:38:598246 // SPDY request
8247 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:308248 };
[email protected]394816e92010-08-03 07:38:598249 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
8250 "Proxy-Authenticate: Mock\r\n"
8251 "Proxy-Connection: close\r\n"
8252 "\r\n");
8253 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8254 MockRead data_reads_2[] = {
8255 // First connection attempt fails
8256 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
8257 MockRead(true, kRejectConnectResponse,
8258 arraysize(kRejectConnectResponse) - 1, 1),
8259
8260 // Second connection attempt passes
8261 MockRead(true, kAcceptConnectResponse,
[email protected]767257802011-12-14 17:33:188262 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:598263
8264 // SPDY response
[email protected]767257802011-12-14 17:33:188265 CreateMockRead(*resp.get(), 6),
8266 CreateMockRead(*data.get(), 6),
8267 MockRead(true, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:598268 };
8269 scoped_refptr<OrderedSocketData> data_2(
8270 new OrderedSocketData(data_reads_2, arraysize(data_reads_2),
8271 data_writes_2, arraysize(data_writes_2)));
[email protected]f45c1ee2010-08-03 00:54:308272
8273 SSLSocketDataProvider ssl(true, OK);
8274 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
8275 ssl.next_proto = "spdy/2";
8276 ssl.was_npn_negotiated = true;
8277
[email protected]2d6728692011-03-12 01:39:558278 MockConnect never_finishing_connect(false, ERR_IO_PENDING);
8279 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8280 NULL, 0, NULL, 0);
8281 hanging_non_alternate_protocol_socket.set_connect_data(
8282 never_finishing_connect);
8283
[email protected]f45c1ee2010-08-03 00:54:308284 session_deps.socket_factory.AddSocketDataProvider(&data_1);
[email protected]394816e92010-08-03 07:38:598285 session_deps.socket_factory.AddSocketDataProvider(data_2.get());
[email protected]f45c1ee2010-08-03 00:54:308286 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558287 session_deps.socket_factory.AddSocketDataProvider(
8288 &hanging_non_alternate_protocol_socket);
[email protected]f45c1ee2010-08-03 00:54:308289 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8290
8291 // First round should work and provide the Alternate-Protocol state.
[email protected]f1f3f0f82011-10-01 20:38:108292 TestOldCompletionCallback callback_1;
[email protected]f45c1ee2010-08-03 00:54:308293 scoped_ptr<HttpTransaction> trans_1(new HttpNetworkTransaction(session));
8294 int rv = trans_1->Start(&request, &callback_1, BoundNetLog());
8295 EXPECT_EQ(ERR_IO_PENDING, rv);
8296 EXPECT_EQ(OK, callback_1.WaitForResult());
8297
8298 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]f1f3f0f82011-10-01 20:38:108299 TestOldCompletionCallback callback_2;
[email protected]f45c1ee2010-08-03 00:54:308300 scoped_ptr<HttpTransaction> trans_2(new HttpNetworkTransaction(session));
8301 rv = trans_2->Start(&request, &callback_2, BoundNetLog());
8302 EXPECT_EQ(ERR_IO_PENDING, rv);
8303 EXPECT_EQ(OK, callback_2.WaitForResult());
8304 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508305 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:308306 ASSERT_FALSE(response->auth_challenge.get() == NULL);
8307
8308 // Restart with auth. Tunnel should work and response received.
[email protected]f1f3f0f82011-10-01 20:38:108309 TestOldCompletionCallback callback_3;
[email protected]f3cf9802011-10-28 18:44:588310 rv = trans_2->RestartWithAuth(AuthCredentials(kFoo, kBar), &callback_3);
[email protected]f45c1ee2010-08-03 00:54:308311 EXPECT_EQ(ERR_IO_PENDING, rv);
8312 EXPECT_EQ(OK, callback_3.WaitForResult());
8313
8314 // After all that work, these two lines (or actually, just the scheme) are
8315 // what this test is all about. Make sure it happens correctly.
[email protected]767257802011-12-14 17:33:188316 const GURL& request_url = auth_handler->request_url();
[email protected]f45c1ee2010-08-03 00:54:308317 EXPECT_EQ("https", request_url.scheme());
8318 EXPECT_EQ("www.google.com", request_url.host());
8319
[email protected]5285d972011-10-18 18:56:348320 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]8e6441ca2010-08-19 05:56:388321 HttpStreamFactory::set_use_alternate_protocols(false);
8322}
8323
8324// Test that if we cancel the transaction as the connection is completing, that
8325// everything tears down correctly.
8326TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
8327 // Setup everything about the connection to complete synchronously, so that
8328 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
8329 // for is the callback from the HttpStreamRequest.
8330 // Then cancel the transaction.
8331 // Verify that we don't crash.
8332 MockConnect mock_connect(false, OK);
8333 MockRead data_reads[] = {
8334 MockRead(false, "HTTP/1.0 200 OK\r\n\r\n"),
8335 MockRead(false, "hello world"),
8336 MockRead(false, OK),
8337 };
8338
[email protected]8e6441ca2010-08-19 05:56:388339 HttpRequestInfo request;
8340 request.method = "GET";
8341 request.url = GURL("http://www.google.com/");
8342 request.load_flags = 0;
8343
[email protected]cb9bf6ca2011-01-28 13:15:278344 SessionDependencies session_deps;
8345 session_deps.host_resolver->set_synchronous_mode(true);
8346 scoped_ptr<HttpTransaction> trans(
8347 new HttpNetworkTransaction(CreateSession(&session_deps)));
8348
[email protected]8e6441ca2010-08-19 05:56:388349 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8350 data.set_connect_data(mock_connect);
8351 session_deps.socket_factory.AddSocketDataProvider(&data);
8352
[email protected]f1f3f0f82011-10-01 20:38:108353 TestOldCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:388354
8355 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
8356 int rv = trans->Start(&request, &callback, log.bound());
8357 EXPECT_EQ(ERR_IO_PENDING, rv);
8358 trans.reset(); // Cancel the transaction here.
8359
8360 MessageLoop::current()->RunAllPending();
[email protected]f45c1ee2010-08-03 00:54:308361}
8362
[email protected]76a505b2010-08-25 06:23:008363// Test a basic GET request through a proxy.
8364TEST_F(HttpNetworkTransactionTest, ProxyGet) {
[email protected]81cdfcd2010-10-16 00:49:008365 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]76a505b2010-08-25 06:23:008366 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
8367 session_deps.net_log = log.bound().net_log();
8368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8369
[email protected]76a505b2010-08-25 06:23:008370 HttpRequestInfo request;
8371 request.method = "GET";
8372 request.url = GURL("http://www.google.com/");
8373
8374 MockWrite data_writes1[] = {
8375 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
8376 "Host: www.google.com\r\n"
8377 "Proxy-Connection: keep-alive\r\n\r\n"),
8378 };
8379
8380 MockRead data_reads1[] = {
8381 MockRead("HTTP/1.1 200 OK\r\n"),
8382 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8383 MockRead("Content-Length: 100\r\n\r\n"),
8384 MockRead(false, OK),
8385 };
8386
8387 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8388 data_writes1, arraysize(data_writes1));
8389 session_deps.socket_factory.AddSocketDataProvider(&data1);
8390
[email protected]f1f3f0f82011-10-01 20:38:108391 TestOldCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:008392
[email protected]0b0bf032010-09-21 18:08:508393 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
8394
[email protected]76a505b2010-08-25 06:23:008395 int rv = trans->Start(&request, &callback1, log.bound());
8396 EXPECT_EQ(ERR_IO_PENDING, rv);
8397
8398 rv = callback1.WaitForResult();
8399 EXPECT_EQ(OK, rv);
8400
8401 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508402 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:008403
8404 EXPECT_TRUE(response->headers->IsKeepAlive());
8405 EXPECT_EQ(200, response->headers->response_code());
8406 EXPECT_EQ(100, response->headers->GetContentLength());
8407 EXPECT_TRUE(response->was_fetched_via_proxy);
8408 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8409}
8410
8411// Test a basic HTTPS GET request through a proxy.
8412TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]81cdfcd2010-10-16 00:49:008413 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]76a505b2010-08-25 06:23:008414 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
8415 session_deps.net_log = log.bound().net_log();
8416 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8417
[email protected]76a505b2010-08-25 06:23:008418 HttpRequestInfo request;
8419 request.method = "GET";
8420 request.url = GURL("https://www.google.com/");
8421
8422 // Since we have proxy, should try to establish tunnel.
8423 MockWrite data_writes1[] = {
8424 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8425 "Host: www.google.com\r\n"
8426 "Proxy-Connection: keep-alive\r\n\r\n"),
8427
8428 MockWrite("GET / HTTP/1.1\r\n"
8429 "Host: www.google.com\r\n"
8430 "Connection: keep-alive\r\n\r\n"),
8431 };
8432
8433 MockRead data_reads1[] = {
8434 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
8435
8436 MockRead("HTTP/1.1 200 OK\r\n"),
8437 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8438 MockRead("Content-Length: 100\r\n\r\n"),
8439 MockRead(false, OK),
8440 };
8441
8442 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8443 data_writes1, arraysize(data_writes1));
8444 session_deps.socket_factory.AddSocketDataProvider(&data1);
8445 SSLSocketDataProvider ssl(true, OK);
8446 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
8447
[email protected]f1f3f0f82011-10-01 20:38:108448 TestOldCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:008449
[email protected]0b0bf032010-09-21 18:08:508450 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
8451
[email protected]76a505b2010-08-25 06:23:008452 int rv = trans->Start(&request, &callback1, log.bound());
8453 EXPECT_EQ(ERR_IO_PENDING, rv);
8454
8455 rv = callback1.WaitForResult();
8456 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:408457 net::CapturingNetLog::EntryList entries;
8458 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:008459 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:408460 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:008461 NetLog::PHASE_NONE);
8462 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:408463 entries, pos,
[email protected]76a505b2010-08-25 06:23:008464 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8465 NetLog::PHASE_NONE);
8466
8467 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508468 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:008469
8470 EXPECT_TRUE(response->headers->IsKeepAlive());
8471 EXPECT_EQ(200, response->headers->response_code());
8472 EXPECT_EQ(100, response->headers->GetContentLength());
8473 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8474 EXPECT_TRUE(response->was_fetched_via_proxy);
8475}
8476
8477// Test a basic HTTPS GET request through a proxy, but the server hangs up
8478// while establishing the tunnel.
8479TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]81cdfcd2010-10-16 00:49:008480 SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
[email protected]76a505b2010-08-25 06:23:008481 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
8482 session_deps.net_log = log.bound().net_log();
8483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8484
[email protected]76a505b2010-08-25 06:23:008485 HttpRequestInfo request;
8486 request.method = "GET";
8487 request.url = GURL("https://www.google.com/");
8488
8489 // Since we have proxy, should try to establish tunnel.
8490 MockWrite data_writes1[] = {
8491 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8492 "Host: www.google.com\r\n"
8493 "Proxy-Connection: keep-alive\r\n\r\n"),
8494
8495 MockWrite("GET / HTTP/1.1\r\n"
8496 "Host: www.google.com\r\n"
8497 "Connection: keep-alive\r\n\r\n"),
8498 };
8499
8500 MockRead data_reads1[] = {
8501 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8502 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
8503 MockRead(true, 0, 0), // EOF
8504 };
8505
8506 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8507 data_writes1, arraysize(data_writes1));
8508 session_deps.socket_factory.AddSocketDataProvider(&data1);
8509 SSLSocketDataProvider ssl(true, OK);
8510 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
8511
[email protected]f1f3f0f82011-10-01 20:38:108512 TestOldCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:008513
[email protected]0b0bf032010-09-21 18:08:508514 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
8515
[email protected]76a505b2010-08-25 06:23:008516 int rv = trans->Start(&request, &callback1, log.bound());
8517 EXPECT_EQ(ERR_IO_PENDING, rv);
8518
8519 rv = callback1.WaitForResult();
8520 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]b2fcd0e2010-12-01 15:19:408521 net::CapturingNetLog::EntryList entries;
8522 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:008523 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:408524 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:008525 NetLog::PHASE_NONE);
8526 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:408527 entries, pos,
[email protected]76a505b2010-08-25 06:23:008528 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8529 NetLog::PHASE_NONE);
8530}
8531
[email protected]749eefa82010-09-13 22:14:038532// Test for crbug.com/55424.
8533TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
8534 SessionDependencies session_deps;
8535
8536 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(
8537 "https://www.google.com", false, 1, LOWEST));
8538 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
8539
8540 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
8541 scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
8542 MockRead spdy_reads[] = {
8543 CreateMockRead(*resp),
8544 CreateMockRead(*data),
8545 MockRead(true, 0, 0),
8546 };
8547
8548 scoped_refptr<DelayedSocketData> spdy_data(
8549 new DelayedSocketData(
8550 1, // wait for one write to finish before reading.
8551 spdy_reads, arraysize(spdy_reads),
8552 spdy_writes, arraysize(spdy_writes)));
8553 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
8554
8555 SSLSocketDataProvider ssl(true, OK);
8556 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
8557 ssl.next_proto = "spdy/2";
8558 ssl.was_npn_negotiated = true;
8559 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
8560
8561 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8562
8563 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:388564 HostPortPair host_port_pair("www.google.com", 443);
8565 HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
[email protected]749eefa82010-09-13 22:14:038566 scoped_refptr<SpdySession> spdy_session =
[email protected]102e27c2011-02-23 01:01:318567 session->spdy_session_pool()->Get(pair, BoundNetLog());
[email protected]ab739042011-04-07 15:22:288568 scoped_refptr<TransportSocketParams> transport_params(
[email protected]acdda412011-11-15 21:21:298569 new TransportSocketParams(host_port_pair, MEDIUM, false, false));
[email protected]6ecf2b92011-12-15 01:14:528570 TestOldCompletionCallback old_callback;
8571 TestCompletionCallback callback;
[email protected]02b0c342010-09-25 21:09:388572
8573 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
8574 EXPECT_EQ(ERR_IO_PENDING,
[email protected]ab739042011-04-07 15:22:288575 connection->Init(host_port_pair.ToString(), transport_params,
[email protected]6ecf2b92011-12-15 01:14:528576 LOWEST, callback.callback(),
[email protected]a42dbd142011-11-17 16:42:028577 session->GetTransportSocketPool(), BoundNetLog()));
[email protected]02b0c342010-09-25 21:09:388578 EXPECT_EQ(OK, callback.WaitForResult());
8579 spdy_session->InitializeWithSocket(connection.release(), false, OK);
[email protected]749eefa82010-09-13 22:14:038580
8581 HttpRequestInfo request;
8582 request.method = "GET";
8583 request.url = GURL("https://www.google.com/");
8584 request.load_flags = 0;
8585
8586 // This is the important line that marks this as a preconnect.
8587 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
8588
8589 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
8590
[email protected]6ecf2b92011-12-15 01:14:528591 int rv = trans->Start(&request, &old_callback, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:038592 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6ecf2b92011-12-15 01:14:528593 EXPECT_EQ(OK, old_callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:038594}
8595
[email protected]73b8dd222010-11-11 19:55:248596// Given a net error, cause that error to be returned from the first Write()
8597// call and verify that the HttpTransaction fails with that error.
8598static void CheckErrorIsPassedBack(int error, bool async) {
[email protected]cb9bf6ca2011-01-28 13:15:278599 net::HttpRequestInfo request_info;
8600 request_info.url = GURL("https://www.example.com/");
8601 request_info.method = "GET";
8602 request_info.load_flags = net::LOAD_NORMAL;
8603
[email protected]73b8dd222010-11-11 19:55:248604 SessionDependencies session_deps;
8605
8606 SSLSocketDataProvider ssl_data(async, OK);
8607 net::MockWrite data_writes[] = {
8608 net::MockWrite(async, error),
8609 };
8610 net::StaticSocketDataProvider data(NULL, 0,
8611 data_writes, arraysize(data_writes));
8612 session_deps.socket_factory.AddSocketDataProvider(&data);
8613 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data);
8614
8615 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8616 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
8617
[email protected]f1f3f0f82011-10-01 20:38:108618 TestOldCompletionCallback callback;
[email protected]73b8dd222010-11-11 19:55:248619 int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
8620 if (rv == net::ERR_IO_PENDING)
8621 rv = callback.WaitForResult();
8622 ASSERT_EQ(error, rv);
8623}
8624
8625TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
8626 // Just check a grab bag of cert errors.
8627 static const int kErrors[] = {
8628 ERR_CERT_COMMON_NAME_INVALID,
8629 ERR_CERT_AUTHORITY_INVALID,
8630 ERR_CERT_DATE_INVALID,
8631 };
8632 for (size_t i = 0; i < arraysize(kErrors); i++) {
8633 CheckErrorIsPassedBack(kErrors[i], false /* not async */);
8634 CheckErrorIsPassedBack(kErrors[i], true /* async */);
8635 }
8636}
8637
[email protected]bd0b6772011-01-11 19:59:308638// Ensure that a client certificate is removed from the SSL client auth
8639// cache when:
8640// 1) No proxy is involved.
8641// 2) TLS False Start is disabled.
8642// 3) The initial TLS handshake requests a client certificate.
8643// 4) The client supplies an invalid/unacceptable certificate.
8644TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:278645 net::HttpRequestInfo request_info;
8646 request_info.url = GURL("https://www.example.com/");
8647 request_info.method = "GET";
8648 request_info.load_flags = net::LOAD_NORMAL;
8649
[email protected]bd0b6772011-01-11 19:59:308650 SessionDependencies session_deps;
8651
8652 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
8653 cert_request->host_and_port = "www.example.com:443";
8654
8655 // [ssl_]data1 contains the data for the first SSL handshake. When a
8656 // CertificateRequest is received for the first time, the handshake will
8657 // be aborted to allow the caller to provide a certificate.
8658 SSLSocketDataProvider ssl_data1(true /* async */,
8659 net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
8660 ssl_data1.cert_request_info = cert_request.get();
8661 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
8662 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
8663 session_deps.socket_factory.AddSocketDataProvider(&data1);
8664
8665 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
8666 // False Start is not being used, the result of the SSL handshake will be
8667 // returned as part of the SSLClientSocket::Connect() call. This test
8668 // matches the result of a server sending a handshake_failure alert,
8669 // rather than a Finished message, because it requires a client
8670 // certificate and none was supplied.
8671 SSLSocketDataProvider ssl_data2(true /* async */,
8672 net::ERR_SSL_PROTOCOL_ERROR);
8673 ssl_data2.cert_request_info = cert_request.get();
8674 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
8675 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
8676 session_deps.socket_factory.AddSocketDataProvider(&data2);
8677
8678 // [ssl_]data3 contains the data for the third SSL handshake. When a
8679 // connection to a server fails during an SSL handshake,
8680 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the initial
8681 // connection was attempted with TLSv1. This is transparent to the caller
8682 // of the HttpNetworkTransaction. Because this test failure is due to
8683 // requiring a client certificate, this fallback handshake should also
8684 // fail.
8685 SSLSocketDataProvider ssl_data3(true /* async */,
8686 net::ERR_SSL_PROTOCOL_ERROR);
8687 ssl_data3.cert_request_info = cert_request.get();
8688 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
8689 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
8690 session_deps.socket_factory.AddSocketDataProvider(&data3);
8691
8692 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8693 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
8694
[email protected]bd0b6772011-01-11 19:59:308695 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]f1f3f0f82011-10-01 20:38:108696 TestOldCompletionCallback callback;
[email protected]bd0b6772011-01-11 19:59:308697 int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
8698 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8699
8700 // Complete the SSL handshake, which should abort due to requiring a
8701 // client certificate.
8702 rv = callback.WaitForResult();
8703 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
8704
8705 // Indicate that no certificate should be supplied. From the perspective
8706 // of SSLClientCertCache, NULL is just as meaningful as a real
8707 // certificate, so this is the same as supply a
8708 // legitimate-but-unacceptable certificate.
8709 rv = trans->RestartWithCertificate(NULL, &callback);
8710 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8711
8712 // Ensure the certificate was added to the client auth cache before
8713 // allowing the connection to continue restarting.
8714 scoped_refptr<X509Certificate> client_cert;
8715 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8716 &client_cert));
8717 ASSERT_EQ(NULL, client_cert.get());
8718
8719 // Restart the handshake. This will consume ssl_data2, which fails, and
8720 // then consume ssl_data3, which should also fail. The result code is
8721 // checked against what ssl_data3 should return.
8722 rv = callback.WaitForResult();
8723 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
8724
8725 // Ensure that the client certificate is removed from the cache on a
8726 // handshake failure.
8727 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8728 &client_cert));
8729}
8730
8731// Ensure that a client certificate is removed from the SSL client auth
8732// cache when:
8733// 1) No proxy is involved.
8734// 2) TLS False Start is enabled.
8735// 3) The initial TLS handshake requests a client certificate.
8736// 4) The client supplies an invalid/unacceptable certificate.
8737TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:278738 net::HttpRequestInfo request_info;
8739 request_info.url = GURL("https://www.example.com/");
8740 request_info.method = "GET";
8741 request_info.load_flags = net::LOAD_NORMAL;
8742
[email protected]bd0b6772011-01-11 19:59:308743 SessionDependencies session_deps;
8744
8745 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
8746 cert_request->host_and_port = "www.example.com:443";
8747
8748 // When TLS False Start is used, SSLClientSocket::Connect() calls will
8749 // return successfully after reading up to the peer's Certificate message.
8750 // This is to allow the caller to call SSLClientSocket::Write(), which can
8751 // enqueue application data to be sent in the same packet as the
8752 // ChangeCipherSpec and Finished messages.
8753 // The actual handshake will be finished when SSLClientSocket::Read() is
8754 // called, which expects to process the peer's ChangeCipherSpec and
8755 // Finished messages. If there was an error negotiating with the peer,
8756 // such as due to the peer requiring a client certificate when none was
8757 // supplied, the alert sent by the peer won't be processed until Read() is
8758 // called.
8759
8760 // Like the non-False Start case, when a client certificate is requested by
8761 // the peer, the handshake is aborted during the Connect() call.
8762 // [ssl_]data1 represents the initial SSL handshake with the peer.
8763 SSLSocketDataProvider ssl_data1(true /* async */,
8764 net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
8765 ssl_data1.cert_request_info = cert_request.get();
8766 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
8767 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
8768 session_deps.socket_factory.AddSocketDataProvider(&data1);
8769
8770 // When a client certificate is supplied, Connect() will not be aborted
8771 // when the peer requests the certificate. Instead, the handshake will
8772 // artificially succeed, allowing the caller to write the HTTP request to
8773 // the socket. The handshake messages are not processed until Read() is
8774 // called, which then detects that the handshake was aborted, due to the
8775 // peer sending a handshake_failure because it requires a client
8776 // certificate.
8777 SSLSocketDataProvider ssl_data2(true /* async */, net::OK);
8778 ssl_data2.cert_request_info = cert_request.get();
8779 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
8780 net::MockRead data2_reads[] = {
8781 net::MockRead(true /* async */, net::ERR_SSL_PROTOCOL_ERROR),
8782 };
8783 net::StaticSocketDataProvider data2(
8784 data2_reads, arraysize(data2_reads), NULL, 0);
8785 session_deps.socket_factory.AddSocketDataProvider(&data2);
8786
8787 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
8788 // the data for the SSL handshake once the TLSv1 connection falls back to
8789 // SSLv3. It has the same behaviour as [ssl_]data2.
8790 SSLSocketDataProvider ssl_data3(true /* async */, net::OK);
8791 ssl_data3.cert_request_info = cert_request.get();
8792 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
8793 net::StaticSocketDataProvider data3(
8794 data2_reads, arraysize(data2_reads), NULL, 0);
8795 session_deps.socket_factory.AddSocketDataProvider(&data3);
8796
8797 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8798 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
8799
[email protected]bd0b6772011-01-11 19:59:308800 // Begin the initial SSL handshake.
[email protected]f1f3f0f82011-10-01 20:38:108801 TestOldCompletionCallback callback;
[email protected]bd0b6772011-01-11 19:59:308802 int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
8803 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8804
8805 // Complete the SSL handshake, which should abort due to requiring a
8806 // client certificate.
8807 rv = callback.WaitForResult();
8808 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
8809
8810 // Indicate that no certificate should be supplied. From the perspective
8811 // of SSLClientCertCache, NULL is just as meaningful as a real
8812 // certificate, so this is the same as supply a
8813 // legitimate-but-unacceptable certificate.
8814 rv = trans->RestartWithCertificate(NULL, &callback);
8815 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8816
8817 // Ensure the certificate was added to the client auth cache before
8818 // allowing the connection to continue restarting.
8819 scoped_refptr<X509Certificate> client_cert;
8820 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8821 &client_cert));
8822 ASSERT_EQ(NULL, client_cert.get());
8823
8824
8825 // Restart the handshake. This will consume ssl_data2, which fails, and
8826 // then consume ssl_data3, which should also fail. The result code is
8827 // checked against what ssl_data3 should return.
8828 rv = callback.WaitForResult();
8829 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
8830
8831 // Ensure that the client certificate is removed from the cache on a
8832 // handshake failure.
8833 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8834 &client_cert));
8835}
8836
[email protected]8c405132011-01-11 22:03:188837// Ensure that a client certificate is removed from the SSL client auth
8838// cache when:
8839// 1) An HTTPS proxy is involved.
8840// 3) The HTTPS proxy requests a client certificate.
8841// 4) The client supplies an invalid/unacceptable certificate for the
8842// proxy.
8843// The test is repeated twice, first for connecting to an HTTPS endpoint,
8844// then for connecting to an HTTP endpoint.
8845TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
8846 SessionDependencies session_deps(
8847 ProxyService::CreateFixed("https://proxy:70"));
8848 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
8849 session_deps.net_log = log.bound().net_log();
8850
8851 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
8852 cert_request->host_and_port = "proxy:70";
8853
8854 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
8855 // [ssl_]data[1-3]. Rather than represending the endpoint
8856 // (www.example.com:443), they represent failures with the HTTPS proxy
8857 // (proxy:70).
8858 SSLSocketDataProvider ssl_data1(true /* async */,
8859 net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
8860 ssl_data1.cert_request_info = cert_request.get();
8861 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
8862 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
8863 session_deps.socket_factory.AddSocketDataProvider(&data1);
8864
8865 SSLSocketDataProvider ssl_data2(true /* async */,
8866 net::ERR_SSL_PROTOCOL_ERROR);
8867 ssl_data2.cert_request_info = cert_request.get();
8868 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
8869 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
8870 session_deps.socket_factory.AddSocketDataProvider(&data2);
8871
8872 SSLSocketDataProvider ssl_data3(true /* async */,
8873 net::ERR_SSL_PROTOCOL_ERROR);
8874 ssl_data3.cert_request_info = cert_request.get();
8875 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
8876 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
8877 session_deps.socket_factory.AddSocketDataProvider(&data3);
8878
8879 net::HttpRequestInfo requests[2];
8880 requests[0].url = GURL("https://www.example.com/");
8881 requests[0].method = "GET";
8882 requests[0].load_flags = net::LOAD_NORMAL;
8883
8884 requests[1].url = GURL("http://www.example.com/");
8885 requests[1].method = "GET";
8886 requests[1].load_flags = net::LOAD_NORMAL;
8887
8888 for (size_t i = 0; i < arraysize(requests); ++i) {
8889 session_deps.socket_factory.ResetNextMockIndexes();
8890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8891 scoped_ptr<HttpNetworkTransaction> trans(
8892 new HttpNetworkTransaction(session));
8893
8894 // Begin the SSL handshake with the proxy.
[email protected]f1f3f0f82011-10-01 20:38:108895 TestOldCompletionCallback callback;
[email protected]8c405132011-01-11 22:03:188896 int rv = trans->Start(&requests[i], &callback, net::BoundNetLog());
8897 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8898
8899 // Complete the SSL handshake, which should abort due to requiring a
8900 // client certificate.
8901 rv = callback.WaitForResult();
8902 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
8903
8904 // Indicate that no certificate should be supplied. From the perspective
8905 // of SSLClientCertCache, NULL is just as meaningful as a real
8906 // certificate, so this is the same as supply a
8907 // legitimate-but-unacceptable certificate.
8908 rv = trans->RestartWithCertificate(NULL, &callback);
8909 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8910
8911 // Ensure the certificate was added to the client auth cache before
8912 // allowing the connection to continue restarting.
8913 scoped_refptr<X509Certificate> client_cert;
8914 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
8915 &client_cert));
8916 ASSERT_EQ(NULL, client_cert.get());
8917 // Ensure the certificate was NOT cached for the endpoint. This only
8918 // applies to HTTPS requests, but is fine to check for HTTP requests.
8919 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8920 &client_cert));
8921
8922 // Restart the handshake. This will consume ssl_data2, which fails, and
8923 // then consume ssl_data3, which should also fail. The result code is
8924 // checked against what ssl_data3 should return.
8925 rv = callback.WaitForResult();
8926 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
8927
8928 // Now that the new handshake has failed, ensure that the client
8929 // certificate was removed from the client auth cache.
8930 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
8931 &client_cert));
8932 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8933 &client_cert));
8934 }
8935}
8936
[email protected]5c288bc2011-07-26 15:12:058937void IPPoolingAddAlias(MockCachingHostResolver* host_resolver,
8938 SpdySessionPoolPeer* pool_peer,
8939 std::string host,
8940 int port,
8941 std::string iplist) {
8942 // Create a host resolver dependency that returns address |iplist| for
8943 // resolutions of |host|.
8944 host_resolver->rules()->AddIPLiteralRule(host, iplist, "");
[email protected]46da33be2011-07-19 21:58:048945
[email protected]5c288bc2011-07-26 15:12:058946 // Setup a HostPortProxyPair.
8947 HostPortPair host_port_pair(host, port);
8948 HostPortProxyPair pair = HostPortProxyPair(host_port_pair,
8949 ProxyServer::Direct());
[email protected]46da33be2011-07-19 21:58:048950
[email protected]5c288bc2011-07-26 15:12:058951 // Resolve the host and port.
8952 AddressList addresses;
8953 HostResolver::RequestInfo info(host_port_pair);
[email protected]aa22b242011-11-16 18:58:298954 TestCompletionCallback callback;
8955 int rv = host_resolver->Resolve(info, &addresses, callback.callback(), NULL,
[email protected]6e78dfb2011-07-28 21:34:478956 BoundNetLog());
8957 if (rv == ERR_IO_PENDING)
8958 rv = callback.WaitForResult();
8959 DCHECK_EQ(OK, rv);
[email protected]46da33be2011-07-19 21:58:048960
[email protected]5c288bc2011-07-26 15:12:058961 // Add the first address as an alias. It would have been better to call
8962 // MockClientSocket::GetPeerAddress but that returns 192.0.2.33 whereas
8963 // MockHostResolver returns 127.0.0.1 (MockHostResolverBase::Reset). So we use
8964 // the first address (127.0.0.1) returned by MockHostResolver as an alias for
8965 // the |pair|.
8966 const addrinfo* address = addresses.head();
8967 pool_peer->AddAlias(address, pair);
[email protected]46da33be2011-07-19 21:58:048968}
8969
[email protected]e3ceb682011-06-28 23:55:468970TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
8971 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:348972 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:468973
8974 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
8975 SessionDependencies session_deps;
8976 MockCachingHostResolver host_resolver;
8977 net::HttpNetworkSession::Params params;
8978 params.client_socket_factory = &session_deps.socket_factory;
8979 params.host_resolver = &host_resolver;
8980 params.cert_verifier = session_deps.cert_verifier.get();
8981 params.proxy_service = session_deps.proxy_service.get();
8982 params.ssl_config_service = session_deps.ssl_config_service;
8983 params.http_auth_handler_factory =
8984 session_deps.http_auth_handler_factory.get();
[email protected]17291a022011-10-10 07:32:538985 params.http_server_properties = &session_deps.http_server_properties;
[email protected]e3ceb682011-06-28 23:55:468986 params.net_log = session_deps.net_log;
8987 scoped_refptr<HttpNetworkSession> session(new HttpNetworkSession(params));
[email protected]b9ec6882011-07-01 07:40:268988 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
8989 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:468990
8991 SSLSocketDataProvider ssl(true, OK);
8992 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
8993 ssl.next_proto = "spdy/2";
8994 ssl.was_npn_negotiated = true;
8995 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
8996
8997 scoped_ptr<spdy::SpdyFrame> host1_req(ConstructSpdyGet(
8998 "https://www.google.com", false, 1, LOWEST));
8999 scoped_ptr<spdy::SpdyFrame> host2_req(ConstructSpdyGet(
9000 "https://www.gmail.com", false, 3, LOWEST));
9001 MockWrite spdy_writes[] = {
9002 CreateMockWrite(*host1_req, 1),
9003 CreateMockWrite(*host2_req, 4),
9004 };
9005 scoped_ptr<spdy::SpdyFrame> host1_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
9006 scoped_ptr<spdy::SpdyFrame> host1_resp_body(ConstructSpdyBodyFrame(1, true));
9007 scoped_ptr<spdy::SpdyFrame> host2_resp(ConstructSpdyGetSynReply(NULL, 0, 3));
9008 scoped_ptr<spdy::SpdyFrame> host2_resp_body(ConstructSpdyBodyFrame(3, true));
9009 MockRead spdy_reads[] = {
9010 CreateMockRead(*host1_resp, 2),
9011 CreateMockRead(*host1_resp_body, 3),
9012 CreateMockRead(*host2_resp, 5),
9013 CreateMockRead(*host2_resp_body, 6),
9014 MockRead(true, 0, 7),
9015 };
9016
9017 scoped_refptr<OrderedSocketData> spdy_data(
9018 new OrderedSocketData(
9019 spdy_reads, arraysize(spdy_reads),
9020 spdy_writes, arraysize(spdy_writes)));
9021 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
9022
[email protected]aa22b242011-11-16 18:58:299023 TestCompletionCallback callback;
9024 TestOldCompletionCallback old_callback;
[email protected]e3ceb682011-06-28 23:55:469025 HttpRequestInfo request1;
9026 request1.method = "GET";
9027 request1.url = GURL("https://www.google.com/");
9028 request1.load_flags = 0;
9029 HttpNetworkTransaction trans1(session);
9030
[email protected]aa22b242011-11-16 18:58:299031 int rv = trans1.Start(&request1, &old_callback, BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:469032 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]aa22b242011-11-16 18:58:299033 EXPECT_EQ(OK, old_callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:469034
9035 const HttpResponseInfo* response = trans1.GetResponseInfo();
9036 ASSERT_TRUE(response != NULL);
9037 ASSERT_TRUE(response->headers != NULL);
9038 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9039
9040 std::string response_data;
9041 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9042 EXPECT_EQ("hello!", response_data);
9043
9044 // Preload www.gmail.com into HostCache.
9045 HostPortPair host_port("www.gmail.com", 443);
9046 HostResolver::RequestInfo resolve_info(host_port);
9047 AddressList ignored;
[email protected]aa22b242011-11-16 18:58:299048 rv = host_resolver.Resolve(resolve_info, &ignored, callback.callback(), NULL,
[email protected]6e78dfb2011-07-28 21:34:479049 BoundNetLog());
9050 EXPECT_EQ(ERR_IO_PENDING, rv);
9051 rv = callback.WaitForResult();
9052 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:469053
[email protected]5c288bc2011-07-26 15:12:059054 // MockHostResolver returns 127.0.0.1, port 443 for https://www.google.com/
9055 // and https://www.gmail.com/. Add 127.0.0.1 as alias for host_port_pair:
9056 // (www.google.com, 443).
9057 IPPoolingAddAlias(&host_resolver, &pool_peer, "www.google.com", 443,
9058 "127.0.0.1");
[email protected]46da33be2011-07-19 21:58:049059
[email protected]e3ceb682011-06-28 23:55:469060 HttpRequestInfo request2;
9061 request2.method = "GET";
9062 request2.url = GURL("https://www.gmail.com/");
9063 request2.load_flags = 0;
9064 HttpNetworkTransaction trans2(session);
9065
[email protected]aa22b242011-11-16 18:58:299066 rv = trans2.Start(&request2, &old_callback, BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:469067 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]aa22b242011-11-16 18:58:299068 EXPECT_EQ(OK, old_callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:469069
9070 response = trans2.GetResponseInfo();
9071 ASSERT_TRUE(response != NULL);
9072 ASSERT_TRUE(response->headers != NULL);
9073 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9074 EXPECT_TRUE(response->was_fetched_via_spdy);
9075 EXPECT_TRUE(response->was_npn_negotiated);
9076 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9077 EXPECT_EQ("hello!", response_data);
9078
[email protected]5285d972011-10-18 18:56:349079 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]e3ceb682011-06-28 23:55:469080 HttpStreamFactory::set_use_alternate_protocols(false);
9081}
9082
9083class OneTimeCachingHostResolver : public net::HostResolver {
9084 public:
9085 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
9086 : host_port_(host_port) {}
9087 virtual ~OneTimeCachingHostResolver() {}
9088
9089 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
9090
9091 // HostResolver methods:
9092 virtual int Resolve(const RequestInfo& info,
9093 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:299094 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:469095 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:409096 const BoundNetLog& net_log) OVERRIDE {
9097 return host_resolver_.Resolve(
[email protected]e3ceb682011-06-28 23:55:469098 info, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:409099 }
9100
9101 virtual int ResolveFromCache(const RequestInfo& info,
9102 AddressList* addresses,
9103 const BoundNetLog& net_log) OVERRIDE {
9104 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
9105 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:099106 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:469107 return rv;
9108 }
9109
[email protected]95a214c2011-08-04 21:50:409110 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:469111 host_resolver_.CancelRequest(req);
9112 }
9113
[email protected]46da33be2011-07-19 21:58:049114 MockCachingHostResolver* GetMockHostResolver() {
9115 return &host_resolver_;
9116 }
9117
[email protected]e3ceb682011-06-28 23:55:469118 private:
9119 MockCachingHostResolver host_resolver_;
9120 const HostPortPair host_port_;
9121};
9122
9123TEST_F(HttpNetworkTransactionTest,
9124 UseIPConnectionPoolingWithHostCacheExpiration) {
9125 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]5285d972011-10-18 18:56:349126 HttpStreamFactory::set_next_protos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:469127
9128 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
9129 SessionDependencies session_deps;
9130 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
9131 net::HttpNetworkSession::Params params;
9132 params.client_socket_factory = &session_deps.socket_factory;
9133 params.host_resolver = &host_resolver;
9134 params.cert_verifier = session_deps.cert_verifier.get();
9135 params.proxy_service = session_deps.proxy_service.get();
9136 params.ssl_config_service = session_deps.ssl_config_service;
9137 params.http_auth_handler_factory =
9138 session_deps.http_auth_handler_factory.get();
[email protected]17291a022011-10-10 07:32:539139 params.http_server_properties = &session_deps.http_server_properties;
[email protected]e3ceb682011-06-28 23:55:469140 params.net_log = session_deps.net_log;
9141 scoped_refptr<HttpNetworkSession> session(new HttpNetworkSession(params));
[email protected]b9ec6882011-07-01 07:40:269142 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
9143 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:469144
9145 SSLSocketDataProvider ssl(true, OK);
9146 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9147 ssl.next_proto = "spdy/2";
9148 ssl.was_npn_negotiated = true;
9149 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
9150
9151 scoped_ptr<spdy::SpdyFrame> host1_req(ConstructSpdyGet(
9152 "https://www.google.com", false, 1, LOWEST));
9153 scoped_ptr<spdy::SpdyFrame> host2_req(ConstructSpdyGet(
9154 "https://www.gmail.com", false, 3, LOWEST));
9155 MockWrite spdy_writes[] = {
9156 CreateMockWrite(*host1_req, 1),
9157 CreateMockWrite(*host2_req, 4),
9158 };
9159 scoped_ptr<spdy::SpdyFrame> host1_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
9160 scoped_ptr<spdy::SpdyFrame> host1_resp_body(ConstructSpdyBodyFrame(1, true));
9161 scoped_ptr<spdy::SpdyFrame> host2_resp(ConstructSpdyGetSynReply(NULL, 0, 3));
9162 scoped_ptr<spdy::SpdyFrame> host2_resp_body(ConstructSpdyBodyFrame(3, true));
9163 MockRead spdy_reads[] = {
9164 CreateMockRead(*host1_resp, 2),
9165 CreateMockRead(*host1_resp_body, 3),
9166 CreateMockRead(*host2_resp, 5),
9167 CreateMockRead(*host2_resp_body, 6),
9168 MockRead(true, 0, 7),
9169 };
9170
9171 scoped_refptr<OrderedSocketData> spdy_data(
9172 new OrderedSocketData(
9173 spdy_reads, arraysize(spdy_reads),
9174 spdy_writes, arraysize(spdy_writes)));
9175 session_deps.socket_factory.AddSocketDataProvider(spdy_data);
9176
[email protected]aa22b242011-11-16 18:58:299177 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:469178 HttpRequestInfo request1;
9179 request1.method = "GET";
9180 request1.url = GURL("https://www.google.com/");
9181 request1.load_flags = 0;
9182 HttpNetworkTransaction trans1(session);
9183
[email protected]aa22b242011-11-16 18:58:299184 TestOldCompletionCallback old_callback;
9185 int rv = trans1.Start(&request1, &old_callback, BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:469186 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]aa22b242011-11-16 18:58:299187 EXPECT_EQ(OK, old_callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:469188
9189 const HttpResponseInfo* response = trans1.GetResponseInfo();
9190 ASSERT_TRUE(response != NULL);
9191 ASSERT_TRUE(response->headers != NULL);
9192 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9193
9194 std::string response_data;
9195 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9196 EXPECT_EQ("hello!", response_data);
9197
9198 // Preload cache entries into HostCache.
9199 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
9200 AddressList ignored;
[email protected]aa22b242011-11-16 18:58:299201 rv = host_resolver.Resolve(resolve_info, &ignored, callback.callback(), NULL,
[email protected]6e78dfb2011-07-28 21:34:479202 BoundNetLog());
9203 EXPECT_EQ(ERR_IO_PENDING, rv);
9204 rv = callback.WaitForResult();
9205 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:469206
9207 HttpRequestInfo request2;
9208 request2.method = "GET";
9209 request2.url = GURL("https://www.gmail.com/");
9210 request2.load_flags = 0;
9211 HttpNetworkTransaction trans2(session);
9212
[email protected]5c288bc2011-07-26 15:12:059213 // MockHostResolver returns 127.0.0.1, port 443 for https://www.google.com/
9214 // and https://www.gmail.com/. Add 127.0.0.1 as alias for host_port_pair:
9215 // (www.google.com, 443).
9216 IPPoolingAddAlias(host_resolver.GetMockHostResolver(), &pool_peer,
9217 "www.google.com", 443, "127.0.0.1");
[email protected]46da33be2011-07-19 21:58:049218
[email protected]aa22b242011-11-16 18:58:299219 rv = trans2.Start(&request2, &old_callback, BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:469220 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]aa22b242011-11-16 18:58:299221 EXPECT_EQ(OK, old_callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:469222
9223 response = trans2.GetResponseInfo();
9224 ASSERT_TRUE(response != NULL);
9225 ASSERT_TRUE(response->headers != NULL);
9226 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9227 EXPECT_TRUE(response->was_fetched_via_spdy);
9228 EXPECT_TRUE(response->was_npn_negotiated);
9229 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9230 EXPECT_EQ("hello!", response_data);
9231
[email protected]5285d972011-10-18 18:56:349232 HttpStreamFactory::set_next_protos(std::vector<std::string>());
[email protected]e3ceb682011-06-28 23:55:469233 HttpStreamFactory::set_use_alternate_protocols(false);
9234}
9235
[email protected]5a60c8b2011-10-19 20:14:299236TEST_F(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
9237 MockRead data_reads1[] = {
9238 MockRead(false, ERR_PIPELINE_EVICTION),
9239 };
9240 MockRead data_reads2[] = {
9241 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9242 MockRead("hello world"),
9243 MockRead(false, OK),
9244 };
9245 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
9246 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
9247 StaticSocketDataProvider* data[] = { &data1, &data2 };
9248
9249 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
9250
9251 EXPECT_EQ(OK, out.rv);
9252 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
9253 EXPECT_EQ("hello world", out.response_data);
9254}
9255
9256TEST_F(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
9257 MockWrite data_writes1[] = {
9258 MockWrite(false, ERR_PIPELINE_EVICTION),
9259 };
9260 MockWrite data_writes2[] = {
9261 MockWrite("GET / HTTP/1.1\r\n"
9262 "Host: www.google.com\r\n"
9263 "Connection: keep-alive\r\n\r\n"),
9264 };
9265 MockRead data_reads2[] = {
9266 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9267 MockRead("hello world"),
9268 MockRead(false, OK),
9269 };
9270 StaticSocketDataProvider data1(NULL, 0,
9271 data_writes1, arraysize(data_writes1));
9272 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9273 data_writes2, arraysize(data_writes2));
9274 StaticSocketDataProvider* data[] = { &data1, &data2 };
9275
9276 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
9277
9278 EXPECT_EQ(OK, out.rv);
9279 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
9280 EXPECT_EQ("hello world", out.response_data);
9281}
9282
[email protected]d4dfdab2011-12-07 16:56:599283TEST_F(HttpNetworkTransactionTest, CloseOldSpdySessionToOpenNewOne) {
9284 HttpStreamFactory::set_next_protos(SpdyNextProtos());
9285 int old_max_sockets_per_group =
9286 ClientSocketPoolManager::max_sockets_per_group();
9287 int old_max_sockets_per_proxy_server =
9288 ClientSocketPoolManager::max_sockets_per_proxy_server();
9289 int old_max_sockets_per_pool =
9290 ClientSocketPoolManager::max_sockets_per_pool();
9291 ClientSocketPoolManager::set_max_sockets_per_group(1);
9292 ClientSocketPoolManager::set_max_sockets_per_proxy_server(1);
9293 ClientSocketPoolManager::set_max_sockets_per_pool(1);
9294
9295 // Use two different hosts with different IPs so they don't get pooled.
9296 SessionDependencies session_deps;
9297 session_deps.host_resolver->rules()->AddRule("a.com", "10.0.0.1");
9298 session_deps.host_resolver->rules()->AddRule("b.com", "10.0.0.2");
9299 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
9300
9301 SSLSocketDataProvider ssl1(true, OK);
9302 ssl1.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9303 ssl1.next_proto = "spdy/2";
9304 ssl1.was_npn_negotiated = true;
9305 SSLSocketDataProvider ssl2(true, OK);
9306 ssl2.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9307 ssl2.next_proto = "spdy/2";
9308 ssl2.was_npn_negotiated = true;
9309 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl1);
9310 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
9311
9312 scoped_ptr<spdy::SpdyFrame> host1_req(ConstructSpdyGet(
9313 "https://www.a.com", false, 1, LOWEST));
9314 MockWrite spdy1_writes[] = {
9315 CreateMockWrite(*host1_req, 1),
9316 };
9317 scoped_ptr<spdy::SpdyFrame> host1_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
9318 scoped_ptr<spdy::SpdyFrame> host1_resp_body(ConstructSpdyBodyFrame(1, true));
9319 MockRead spdy1_reads[] = {
9320 CreateMockRead(*host1_resp, 2),
9321 CreateMockRead(*host1_resp_body, 3),
9322 MockRead(true, ERR_IO_PENDING, 4),
9323 };
9324
9325 scoped_refptr<OrderedSocketData> spdy1_data(
9326 new OrderedSocketData(
9327 spdy1_reads, arraysize(spdy1_reads),
9328 spdy1_writes, arraysize(spdy1_writes)));
9329 session_deps.socket_factory.AddSocketDataProvider(spdy1_data);
9330
9331 scoped_ptr<spdy::SpdyFrame> host2_req(ConstructSpdyGet(
9332 "https://www.b.com", false, 1, LOWEST));
9333 MockWrite spdy2_writes[] = {
9334 CreateMockWrite(*host2_req, 1),
9335 };
9336 scoped_ptr<spdy::SpdyFrame> host2_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
9337 scoped_ptr<spdy::SpdyFrame> host2_resp_body(ConstructSpdyBodyFrame(1, true));
9338 MockRead spdy2_reads[] = {
9339 CreateMockRead(*host2_resp, 2),
9340 CreateMockRead(*host2_resp_body, 3),
9341 MockRead(true, ERR_IO_PENDING, 4),
9342 };
9343
9344 scoped_refptr<OrderedSocketData> spdy2_data(
9345 new OrderedSocketData(
9346 spdy2_reads, arraysize(spdy2_reads),
9347 spdy2_writes, arraysize(spdy2_writes)));
9348 session_deps.socket_factory.AddSocketDataProvider(spdy2_data);
9349
9350 MockWrite http_write[] = {
9351 MockWrite("GET / HTTP/1.1\r\n"
9352 "Host: www.a.com\r\n"
9353 "Connection: keep-alive\r\n\r\n"),
9354 };
9355
9356 MockRead http_read[] = {
9357 MockRead("HTTP/1.1 200 OK\r\n"),
9358 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9359 MockRead("Content-Length: 6\r\n\r\n"),
9360 MockRead("hello!"),
9361 };
9362
9363 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
9364 http_write, arraysize(http_write));
9365 session_deps.socket_factory.AddSocketDataProvider(&http_data);
9366
9367 HostPortPair host_port_pair_a("www.a.com", 443);
9368 HostPortProxyPair host_port_proxy_pair_a(
9369 host_port_pair_a, ProxyServer::Direct());
9370 EXPECT_FALSE(
9371 session->spdy_session_pool()->HasSession(host_port_proxy_pair_a));
9372
9373 TestOldCompletionCallback callback;
9374 HttpRequestInfo request1;
9375 request1.method = "GET";
9376 request1.url = GURL("https://www.a.com/");
9377 request1.load_flags = 0;
9378 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
9379
9380 int rv = trans->Start(&request1, &callback, BoundNetLog());
9381 EXPECT_EQ(ERR_IO_PENDING, rv);
9382 EXPECT_EQ(OK, callback.WaitForResult());
9383
9384 const HttpResponseInfo* response = trans->GetResponseInfo();
9385 ASSERT_TRUE(response != NULL);
9386 ASSERT_TRUE(response->headers != NULL);
9387 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9388 EXPECT_TRUE(response->was_fetched_via_spdy);
9389 EXPECT_TRUE(response->was_npn_negotiated);
9390
9391 std::string response_data;
9392 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9393 EXPECT_EQ("hello!", response_data);
9394 trans.reset();
9395 EXPECT_TRUE(
9396 session->spdy_session_pool()->HasSession(host_port_proxy_pair_a));
9397
9398 HostPortPair host_port_pair_b("www.b.com", 443);
9399 HostPortProxyPair host_port_proxy_pair_b(
9400 host_port_pair_b, ProxyServer::Direct());
9401 EXPECT_FALSE(
9402 session->spdy_session_pool()->HasSession(host_port_proxy_pair_b));
9403 HttpRequestInfo request2;
9404 request2.method = "GET";
9405 request2.url = GURL("https://www.b.com/");
9406 request2.load_flags = 0;
9407 trans.reset(new HttpNetworkTransaction(session));
9408
9409 rv = trans->Start(&request2, &callback, BoundNetLog());
9410 EXPECT_EQ(ERR_IO_PENDING, rv);
9411 EXPECT_EQ(OK, callback.WaitForResult());
9412
9413 response = trans->GetResponseInfo();
9414 ASSERT_TRUE(response != NULL);
9415 ASSERT_TRUE(response->headers != NULL);
9416 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9417 EXPECT_TRUE(response->was_fetched_via_spdy);
9418 EXPECT_TRUE(response->was_npn_negotiated);
9419 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9420 EXPECT_EQ("hello!", response_data);
9421 EXPECT_FALSE(
9422 session->spdy_session_pool()->HasSession(host_port_proxy_pair_a));
9423 EXPECT_TRUE(
9424 session->spdy_session_pool()->HasSession(host_port_proxy_pair_b));
9425
9426 HostPortPair host_port_pair_a1("www.a.com", 80);
9427 HostPortProxyPair host_port_proxy_pair_a1(
9428 host_port_pair_a1, ProxyServer::Direct());
9429 EXPECT_FALSE(
9430 session->spdy_session_pool()->HasSession(host_port_proxy_pair_a1));
9431 HttpRequestInfo request3;
9432 request3.method = "GET";
9433 request3.url = GURL("http://www.a.com/");
9434 request3.load_flags = 0;
9435 trans.reset(new HttpNetworkTransaction(session));
9436
9437 rv = trans->Start(&request3, &callback, BoundNetLog());
9438 EXPECT_EQ(ERR_IO_PENDING, rv);
9439 EXPECT_EQ(OK, callback.WaitForResult());
9440
9441 response = trans->GetResponseInfo();
9442 ASSERT_TRUE(response != NULL);
9443 ASSERT_TRUE(response->headers != NULL);
9444 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9445 EXPECT_FALSE(response->was_fetched_via_spdy);
9446 EXPECT_FALSE(response->was_npn_negotiated);
9447 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9448 EXPECT_EQ("hello!", response_data);
9449 EXPECT_FALSE(
9450 session->spdy_session_pool()->HasSession(host_port_proxy_pair_a));
9451 EXPECT_FALSE(
9452 session->spdy_session_pool()->HasSession(host_port_proxy_pair_b));
9453
9454 HttpStreamFactory::set_next_protos(std::vector<std::string>());
9455 ClientSocketPoolManager::set_max_sockets_per_pool(old_max_sockets_per_pool);
9456 ClientSocketPoolManager::set_max_sockets_per_proxy_server(
9457 old_max_sockets_per_proxy_server);
9458 ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets_per_group);
9459}
9460
[email protected]89ceba9a2009-03-21 03:46:069461} // namespace net