blob: 57ea425ca67d3bec5ebc8984f76299f22a52cc75 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]77848d12008-11-14 00:00:225#include <math.h> // ceil
6
[email protected]68bf9152008-09-25 19:47:307#include "base/compiler_specific.h"
[email protected]bacff652009-03-31 17:50:338#include "net/base/completion_callback.h"
[email protected]9172a982009-06-06 00:30:259#include "net/base/host_resolver_unittest.h"
[email protected]bacff652009-03-31 17:50:3310#include "net/base/ssl_info.h"
initial.commit586acc5fe2008-07-26 22:42:5211#include "net/base/test_completion_callback.h"
12#include "net/base/upload_data.h"
[email protected]385a4672009-03-11 22:21:2913#include "net/http/http_auth_handler_ntlm.h"
initial.commit586acc5fe2008-07-26 22:42:5214#include "net/http/http_network_session.h"
15#include "net/http/http_network_transaction.h"
16#include "net/http/http_transaction_unittest.h"
[email protected]51fff29d2008-12-19 22:17:5317#include "net/proxy/proxy_config_service_fixed.h"
[email protected]f7984fc62009-06-22 23:26:4418#include "net/socket/client_socket_factory.h"
19#include "net/socket/socket_test_util.h"
20#include "net/socket/ssl_client_socket.h"
initial.commit586acc5fe2008-07-26 22:42:5221#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1522#include "testing/platform_test.h"
initial.commit586acc5fe2008-07-26 22:42:5223
24//-----------------------------------------------------------------------------
25
[email protected]89ceba9a2009-03-21 03:46:0626namespace net {
27
[email protected]db8f44c2008-12-13 04:52:0128// Create a proxy service which fails on all requests (falls back to direct).
[email protected]1c773ea12009-04-28 19:58:4229ProxyService* CreateNullProxyService() {
30 return ProxyService::CreateNull();
initial.commit586acc5fe2008-07-26 22:42:5231}
32
[email protected]e44de5d2009-06-05 20:12:4533// Helper to manage the lifetimes of the dependencies for a
34// HttpNetworkTransaction.
[email protected]228ff742009-06-05 01:19:5935class SessionDependencies {
36 public:
37 // Default set of dependencies -- "null" proxy service.
38 SessionDependencies() : proxy_service(CreateNullProxyService()) {}
39
40 // Custom proxy service dependency.
[email protected]e44de5d2009-06-05 20:12:4541 explicit SessionDependencies(ProxyService* proxy_service)
[email protected]228ff742009-06-05 01:19:5942 : proxy_service(proxy_service) {}
43
[email protected]8a00f00a2009-06-12 00:49:3844 HostResolver host_resolver;
[email protected]228ff742009-06-05 01:19:5945 scoped_ptr<ProxyService> proxy_service;
46 MockClientSocketFactory socket_factory;
47};
48
[email protected]1c773ea12009-04-28 19:58:4249ProxyService* CreateFixedProxyService(const std::string& proxy) {
[email protected]ab501a6a2009-05-12 15:07:5050 net::ProxyConfig proxy_config;
51 proxy_config.proxy_rules.ParseFromString(proxy);
[email protected]3e44697f2009-05-22 14:37:3952 return ProxyService::CreateFixed(proxy_config);
[email protected]51fff29d2008-12-19 22:17:5353}
54
55
[email protected]228ff742009-06-05 01:19:5956HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
[email protected]8a00f00a2009-06-12 00:49:3857 return new HttpNetworkSession(&session_deps->host_resolver,
58 session_deps->proxy_service.get(),
[email protected]228ff742009-06-05 01:19:5959 &session_deps->socket_factory);
[email protected]e8d536192008-10-17 22:21:1460}
61
[email protected]89836e22008-09-25 20:33:4262class HttpNetworkTransactionTest : public PlatformTest {
initial.commit586acc5fe2008-07-26 22:42:5263 public:
[email protected]0e75a732008-10-16 20:36:0964 virtual void TearDown() {
65 // Empty the current queue.
66 MessageLoop::current()->RunAllPending();
67 PlatformTest::TearDown();
68 }
69
[email protected]3d2a59b2008-09-26 19:44:2570 protected:
71 void KeepAliveConnectionResendRequestTest(const MockRead& read_failure);
initial.commit586acc5fe2008-07-26 22:42:5272
[email protected]ff007e162009-05-23 09:13:1573 struct SimpleGetHelperResult {
74 int rv;
75 std::string status_line;
76 std::string response_data;
77 };
initial.commit586acc5fe2008-07-26 22:42:5278
[email protected]ff007e162009-05-23 09:13:1579 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) {
80 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:5281
[email protected]228ff742009-06-05 01:19:5982 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:4083 scoped_ptr<HttpTransaction> trans(
84 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:5985 CreateSession(&session_deps),
86 &session_deps.socket_factory));
initial.commit586acc5fe2008-07-26 22:42:5287
[email protected]ff007e162009-05-23 09:13:1588 HttpRequestInfo request;
89 request.method = "GET";
90 request.url = GURL("http://www.google.com/");
91 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:5292
[email protected]69b43fe2009-06-15 09:47:3793 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:5994 session_deps.socket_factory.AddMockSocket(&data);
initial.commit586acc5fe2008-07-26 22:42:5295
[email protected]ff007e162009-05-23 09:13:1596 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:5297
[email protected]ff007e162009-05-23 09:13:1598 int rv = trans->Start(&request, &callback);
99 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52100
[email protected]ff007e162009-05-23 09:13:15101 out.rv = callback.WaitForResult();
102 if (out.rv != OK)
103 return out;
104
105 const HttpResponseInfo* response = trans->GetResponseInfo();
106 EXPECT_TRUE(response != NULL);
107
108 EXPECT_TRUE(response->headers != NULL);
109 out.status_line = response->headers->GetStatusLine();
110
111 rv = ReadTransaction(trans.get(), &out.response_data);
112 EXPECT_EQ(OK, rv);
113
[email protected]aecfbf22008-10-16 02:02:47114 return out;
[email protected]ff007e162009-05-23 09:13:15115 }
initial.commit586acc5fe2008-07-26 22:42:52116
[email protected]ff007e162009-05-23 09:13:15117 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
118 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52119
[email protected]ff007e162009-05-23 09:13:15120 void ConnectStatusHelper(const MockRead& status);
[email protected]ff007e162009-05-23 09:13:15121};
[email protected]231d5a32008-09-13 00:45:27122
[email protected]15a5ccf82008-10-23 19:57:43123// Fill |str| with a long header list that consumes >= |size| bytes.
124void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19125 const char* row =
126 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
127 const int sizeof_row = strlen(row);
128 const int num_rows = static_cast<int>(
129 ceil(static_cast<float>(size) / sizeof_row));
130 const int sizeof_data = num_rows * sizeof_row;
131 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43132 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51133
[email protected]4ddaf2502008-10-23 18:26:19134 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43135 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19136}
137
[email protected]385a4672009-03-11 22:21:29138// Alternative functions that eliminate randomness and dependency on the local
139// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20140void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29141 static const uint8 bytes[] = {
142 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
143 };
144 static size_t current_byte = 0;
145 for (size_t i = 0; i < n; ++i) {
146 output[i] = bytes[current_byte++];
147 current_byte %= arraysize(bytes);
148 }
149}
150
[email protected]fe2bc6a2009-03-23 16:52:20151void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29152 static const uint8 bytes[] = {
153 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
154 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
155 };
156 static size_t current_byte = 0;
157 for (size_t i = 0; i < n; ++i) {
158 output[i] = bytes[current_byte++];
159 current_byte %= arraysize(bytes);
160 }
161}
162
[email protected]fe2bc6a2009-03-23 16:52:20163std::string MockGetHostName() {
164 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29165}
166
[email protected]231d5a32008-09-13 00:45:27167//-----------------------------------------------------------------------------
168
169TEST_F(HttpNetworkTransactionTest, Basic) {
[email protected]228ff742009-06-05 01:19:59170 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40171 scoped_ptr<HttpTransaction> trans(
172 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59173 CreateSession(&session_deps),
174 &session_deps.socket_factory));
[email protected]231d5a32008-09-13 00:45:27175}
176
177TEST_F(HttpNetworkTransactionTest, SimpleGET) {
178 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35179 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
180 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42181 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27182 };
[email protected]231d5a32008-09-13 00:45:27183 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42184 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27185 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
186 EXPECT_EQ("hello world", out.response_data);
187}
188
189// Response with no status line.
190TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
191 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35192 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42193 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27194 };
[email protected]231d5a32008-09-13 00:45:27195 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42196 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27197 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
198 EXPECT_EQ("hello world", out.response_data);
199}
200
201// Allow up to 4 bytes of junk to precede status line.
202TEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) {
203 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35204 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]1c773ea12009-04-28 19:58:42205 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27206 };
207 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42208 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27209 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
210 EXPECT_EQ("DATA", out.response_data);
211}
212
213// Allow up to 4 bytes of junk to precede status line.
214TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
215 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35216 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]1c773ea12009-04-28 19:58:42217 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27218 };
219 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42220 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27221 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
222 EXPECT_EQ("DATA", out.response_data);
223}
224
225// Beyond 4 bytes of slop and it should fail to find a status line.
226TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
227 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35228 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]1c773ea12009-04-28 19:58:42229 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27230 };
231 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42232 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25233 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
234 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27235}
236
237// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
238TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
239 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35240 MockRead("\n"),
241 MockRead("\n"),
242 MockRead("Q"),
243 MockRead("J"),
244 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]1c773ea12009-04-28 19:58:42245 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27246 };
247 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42248 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27249 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
250 EXPECT_EQ("DATA", out.response_data);
251}
252
253// Close the connection before enough bytes to have a status line.
254TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
255 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35256 MockRead("HTT"),
[email protected]1c773ea12009-04-28 19:58:42257 MockRead(false, OK),
[email protected]231d5a32008-09-13 00:45:27258 };
259 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42260 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27261 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
262 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52263}
264
[email protected]f9d44aa2008-09-23 23:57:17265// Simulate a 204 response, lacking a Content-Length header, sent over a
266// persistent connection. The response should still terminate since a 204
267// cannot have a response body.
268TEST_F(HttpNetworkTransactionTest, StopsReading204) {
269 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35270 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
271 MockRead("junk"), // Should not be read!!
[email protected]1c773ea12009-04-28 19:58:42272 MockRead(false, OK),
[email protected]f9d44aa2008-09-23 23:57:17273 };
274 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42275 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17276 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
277 EXPECT_EQ("", out.response_data);
278}
279
[email protected]ef0faf2e72009-03-05 23:27:23280// Do a request using the HEAD method. Verify that we don't try to read the
281// message body (since HEAD has none).
282TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]228ff742009-06-05 01:19:59283 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40284 scoped_ptr<HttpTransaction> trans(
285 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59286 CreateSession(&session_deps),
287 &session_deps.socket_factory));
[email protected]ef0faf2e72009-03-05 23:27:23288
[email protected]1c773ea12009-04-28 19:58:42289 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23290 request.method = "HEAD";
291 request.url = GURL("http://www.google.com/");
292 request.load_flags = 0;
293
294 MockWrite data_writes1[] = {
295 MockWrite("HEAD / HTTP/1.1\r\n"
296 "Host: www.google.com\r\n"
297 "Connection: keep-alive\r\n"
298 "Content-Length: 0\r\n\r\n"),
299 };
300 MockRead data_reads1[] = {
301 MockRead("HTTP/1.1 404 Not Found\r\n"),
302 MockRead("Server: Blah\r\n"),
303 MockRead("Content-Length: 1234\r\n\r\n"),
304
305 // No response body because the test stops reading here.
[email protected]1c773ea12009-04-28 19:58:42306 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23307 };
308
[email protected]69b43fe2009-06-15 09:47:37309 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]228ff742009-06-05 01:19:59310 session_deps.socket_factory.AddMockSocket(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23311
312 TestCompletionCallback callback1;
313
314 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:42315 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23316
317 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42318 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23319
[email protected]1c773ea12009-04-28 19:58:42320 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]ef0faf2e72009-03-05 23:27:23321 EXPECT_FALSE(response == NULL);
322
323 // Check that the headers got parsed.
324 EXPECT_TRUE(response->headers != NULL);
325 EXPECT_EQ(1234, response->headers->GetContentLength());
326 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
327
328 std::string server_header;
329 void* iter = NULL;
330 bool has_server_header = response->headers->EnumerateHeader(
331 &iter, "Server", &server_header);
332 EXPECT_TRUE(has_server_header);
333 EXPECT_EQ("Blah", server_header);
334
335 // Reading should give EOF right away, since there is no message body
336 // (despite non-zero content-length).
337 std::string response_data;
338 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42339 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23340 EXPECT_EQ("", response_data);
341}
342
initial.commit586acc5fe2008-07-26 22:42:52343TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]228ff742009-06-05 01:19:59344 SessionDependencies session_deps;
345 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
initial.commit586acc5fe2008-07-26 22:42:52346
347 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35348 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
349 MockRead("hello"),
350 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
351 MockRead("world"),
[email protected]1c773ea12009-04-28 19:58:42352 MockRead(false, OK),
initial.commit586acc5fe2008-07-26 22:42:52353 };
[email protected]69b43fe2009-06-15 09:47:37354 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:59355 session_deps.socket_factory.AddMockSocket(&data);
initial.commit586acc5fe2008-07-26 22:42:52356
357 const char* kExpectedResponseData[] = {
358 "hello", "world"
359 };
360
361 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42362 scoped_ptr<HttpTransaction> trans(
[email protected]228ff742009-06-05 01:19:59363 new HttpNetworkTransaction(session, &session_deps.socket_factory));
initial.commit586acc5fe2008-07-26 22:42:52364
[email protected]1c773ea12009-04-28 19:58:42365 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52366 request.method = "GET";
367 request.url = GURL("http://www.google.com/");
368 request.load_flags = 0;
369
370 TestCompletionCallback callback;
371
372 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:42373 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52374
375 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42376 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52377
[email protected]1c773ea12009-04-28 19:58:42378 const HttpResponseInfo* response = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:52379 EXPECT_TRUE(response != NULL);
380
381 EXPECT_TRUE(response->headers != NULL);
[email protected]3d2a59b2008-09-26 19:44:25382 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:52383
384 std::string response_data;
[email protected]af4876d2008-10-21 23:10:57385 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42386 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:25387 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:52388 }
389}
390
391TEST_F(HttpNetworkTransactionTest, Ignores100) {
[email protected]228ff742009-06-05 01:19:59392 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40393 scoped_ptr<HttpTransaction> trans(
394 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59395 CreateSession(&session_deps),
396 &session_deps.socket_factory));
initial.commit586acc5fe2008-07-26 22:42:52397
[email protected]1c773ea12009-04-28 19:58:42398 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52399 request.method = "POST";
400 request.url = GURL("http://www.foo.com/");
[email protected]1c773ea12009-04-28 19:58:42401 request.upload_data = new UploadData;
initial.commit586acc5fe2008-07-26 22:42:52402 request.upload_data->AppendBytes("foo", 3);
403 request.load_flags = 0;
404
405 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35406 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
407 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
408 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42409 MockRead(false, OK),
initial.commit586acc5fe2008-07-26 22:42:52410 };
[email protected]69b43fe2009-06-15 09:47:37411 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:59412 session_deps.socket_factory.AddMockSocket(&data);
initial.commit586acc5fe2008-07-26 22:42:52413
414 TestCompletionCallback callback;
415
416 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:42417 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52418
419 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42420 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52421
[email protected]1c773ea12009-04-28 19:58:42422 const HttpResponseInfo* response = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:52423 EXPECT_TRUE(response != NULL);
424
425 EXPECT_TRUE(response->headers != NULL);
[email protected]3d2a59b2008-09-26 19:44:25426 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:52427
428 std::string response_data;
[email protected]af4876d2008-10-21 23:10:57429 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42430 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:25431 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:52432}
433
[email protected]3a2d3662009-03-27 03:49:14434// This test is almost the same as Ignores100 above, but the response contains
435// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
436// HTTP/1.1.
437TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]228ff742009-06-05 01:19:59438 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40439 scoped_ptr<HttpTransaction> trans(
440 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59441 CreateSession(&session_deps),
442 &session_deps.socket_factory));
[email protected]3a2d3662009-03-27 03:49:14443
[email protected]1c773ea12009-04-28 19:58:42444 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:14445 request.method = "GET";
446 request.url = GURL("http://www.foo.com/");
447 request.load_flags = 0;
448
449 MockRead data_reads[] = {
450 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"),
451 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
452 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42453 MockRead(false, OK),
[email protected]3a2d3662009-03-27 03:49:14454 };
[email protected]69b43fe2009-06-15 09:47:37455 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:59456 session_deps.socket_factory.AddMockSocket(&data);
[email protected]3a2d3662009-03-27 03:49:14457
458 TestCompletionCallback callback;
459
460 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:42461 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:14462
463 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42464 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:14465
[email protected]1c773ea12009-04-28 19:58:42466 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3a2d3662009-03-27 03:49:14467 EXPECT_TRUE(response != NULL);
468
469 EXPECT_TRUE(response->headers != NULL);
470 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
471
472 std::string response_data;
473 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42474 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:14475 EXPECT_EQ("hello world", response_data);
476}
477
[email protected]3d2a59b2008-09-26 19:44:25478// read_failure specifies a read failure that should cause the network
479// transaction to resend the request.
480void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
481 const MockRead& read_failure) {
[email protected]228ff742009-06-05 01:19:59482 SessionDependencies session_deps;
483 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
initial.commit586acc5fe2008-07-26 22:42:52484
[email protected]1c773ea12009-04-28 19:58:42485 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52486 request.method = "GET";
487 request.url = GURL("http://www.foo.com/");
488 request.load_flags = 0;
489
490 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:35491 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
492 MockRead("hello"),
[email protected]3d2a59b2008-09-26 19:44:25493 read_failure, // Now, we reuse the connection and fail the first read.
initial.commit586acc5fe2008-07-26 22:42:52494 };
[email protected]69b43fe2009-06-15 09:47:37495 StaticMockSocket data1(data1_reads, NULL);
[email protected]228ff742009-06-05 01:19:59496 session_deps.socket_factory.AddMockSocket(&data1);
initial.commit586acc5fe2008-07-26 22:42:52497
498 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:35499 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
500 MockRead("world"),
[email protected]1c773ea12009-04-28 19:58:42501 MockRead(true, OK),
initial.commit586acc5fe2008-07-26 22:42:52502 };
[email protected]69b43fe2009-06-15 09:47:37503 StaticMockSocket data2(data2_reads, NULL);
[email protected]228ff742009-06-05 01:19:59504 session_deps.socket_factory.AddMockSocket(&data2);
initial.commit586acc5fe2008-07-26 22:42:52505
506 const char* kExpectedResponseData[] = {
507 "hello", "world"
508 };
509
510 for (int i = 0; i < 2; ++i) {
511 TestCompletionCallback callback;
512
[email protected]1c773ea12009-04-28 19:58:42513 scoped_ptr<HttpTransaction> trans(
[email protected]228ff742009-06-05 01:19:59514 new HttpNetworkTransaction(session, &session_deps.socket_factory));
initial.commit586acc5fe2008-07-26 22:42:52515
516 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:42517 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52518
519 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42520 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52521
[email protected]1c773ea12009-04-28 19:58:42522 const HttpResponseInfo* response = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:52523 EXPECT_TRUE(response != NULL);
524
525 EXPECT_TRUE(response->headers != NULL);
[email protected]3d2a59b2008-09-26 19:44:25526 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:52527
528 std::string response_data;
[email protected]af4876d2008-10-21 23:10:57529 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42530 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:25531 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:52532 }
533}
[email protected]3d2a59b2008-09-26 19:44:25534
535TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:42536 MockRead read_failure(true, ERR_CONNECTION_RESET);
[email protected]3d2a59b2008-09-26 19:44:25537 KeepAliveConnectionResendRequestTest(read_failure);
538}
539
540TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]1c773ea12009-04-28 19:58:42541 MockRead read_failure(false, OK); // EOF
[email protected]3d2a59b2008-09-26 19:44:25542 KeepAliveConnectionResendRequestTest(read_failure);
543}
544
545TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]228ff742009-06-05 01:19:59546 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40547 scoped_ptr<HttpTransaction> trans(
548 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59549 CreateSession(&session_deps),
550 &session_deps.socket_factory));
[email protected]3d2a59b2008-09-26 19:44:25551
[email protected]1c773ea12009-04-28 19:58:42552 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:25553 request.method = "GET";
554 request.url = GURL("http://www.google.com/");
555 request.load_flags = 0;
556
557 MockRead data_reads[] = {
[email protected]1c773ea12009-04-28 19:58:42558 MockRead(true, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:35559 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
560 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42561 MockRead(false, OK),
[email protected]3d2a59b2008-09-26 19:44:25562 };
[email protected]69b43fe2009-06-15 09:47:37563 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:59564 session_deps.socket_factory.AddMockSocket(&data);
[email protected]3d2a59b2008-09-26 19:44:25565
566 TestCompletionCallback callback;
567
568 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:42569 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:25570
571 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42572 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:25573
[email protected]1c773ea12009-04-28 19:58:42574 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:25575 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:25576}
577
578// What do various browsers do when the server closes a non-keepalive
579// connection without sending any response header or body?
580//
581// IE7: error page
582// Safari 3.1.2 (Windows): error page
583// Firefox 3.0.1: blank page
584// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:42585// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
586// Us: error page (EMPTY_RESPONSE)
[email protected]3d2a59b2008-09-26 19:44:25587TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
588 MockRead data_reads[] = {
[email protected]1c773ea12009-04-28 19:58:42589 MockRead(false, OK), // EOF
[email protected]217e6022008-09-29 18:18:35590 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
591 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:42592 MockRead(false, OK),
[email protected]3d2a59b2008-09-26 19:44:25593 };
594 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
[email protected]1c773ea12009-04-28 19:58:42595 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25596}
[email protected]038e9a32008-10-08 22:40:16597
598// Test the request-challenge-retry sequence for basic auth.
599// (basic auth is the easiest to mock, because it has no randomness).
600TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]228ff742009-06-05 01:19:59601 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40602 scoped_ptr<HttpTransaction> trans(
603 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59604 CreateSession(&session_deps),
605 &session_deps.socket_factory));
[email protected]038e9a32008-10-08 22:40:16606
[email protected]1c773ea12009-04-28 19:58:42607 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:16608 request.method = "GET";
609 request.url = GURL("http://www.google.com/");
610 request.load_flags = 0;
611
[email protected]f9ee6b52008-11-08 06:46:23612 MockWrite data_writes1[] = {
613 MockWrite("GET / HTTP/1.1\r\n"
614 "Host: www.google.com\r\n"
615 "Connection: keep-alive\r\n\r\n"),
616 };
617
[email protected]038e9a32008-10-08 22:40:16618 MockRead data_reads1[] = {
619 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
620 // Give a couple authenticate options (only the middle one is actually
621 // supported).
[email protected]aaead502008-10-15 00:20:11622 MockRead("WWW-Authenticate: Basic\r\n"), // Malformed
[email protected]038e9a32008-10-08 22:40:16623 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
624 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
625 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
626 // Large content-length -- won't matter, as connection will be reset.
627 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:42628 MockRead(false, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:16629 };
630
631 // After calling trans->RestartWithAuth(), this is the request we should
632 // be issuing -- the final header line contains the credentials.
633 MockWrite data_writes2[] = {
634 MockWrite("GET / HTTP/1.1\r\n"
635 "Host: www.google.com\r\n"
636 "Connection: keep-alive\r\n"
637 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
638 };
639
640 // Lastly, the server responds with the actual content.
641 MockRead data_reads2[] = {
642 MockRead("HTTP/1.0 200 OK\r\n"),
643 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
644 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:42645 MockRead(false, OK),
[email protected]038e9a32008-10-08 22:40:16646 };
647
[email protected]69b43fe2009-06-15 09:47:37648 StaticMockSocket data1(data_reads1, data_writes1);
649 StaticMockSocket data2(data_reads2, data_writes2);
[email protected]228ff742009-06-05 01:19:59650 session_deps.socket_factory.AddMockSocket(&data1);
651 session_deps.socket_factory.AddMockSocket(&data2);
[email protected]038e9a32008-10-08 22:40:16652
653 TestCompletionCallback callback1;
654
655 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:42656 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:16657
658 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42659 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:16660
[email protected]1c773ea12009-04-28 19:58:42661 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]038e9a32008-10-08 22:40:16662 EXPECT_FALSE(response == NULL);
663
664 // The password prompt info should have been set in response->auth_challenge.
665 EXPECT_FALSE(response->auth_challenge.get() == NULL);
666
[email protected]71e4573a2009-05-21 22:03:00667 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]038e9a32008-10-08 22:40:16668 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
669 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
670
671 TestCompletionCallback callback2;
672
673 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
[email protected]1c773ea12009-04-28 19:58:42674 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:16675
676 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42677 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:16678
679 response = trans->GetResponseInfo();
680 EXPECT_FALSE(response == NULL);
681 EXPECT_TRUE(response->auth_challenge.get() == NULL);
682 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:16683}
684
[email protected]2d2697f92009-02-18 21:00:32685// Test the request-challenge-retry sequence for basic auth, over a keep-alive
686// connection.
687TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]228ff742009-06-05 01:19:59688 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40689 scoped_ptr<HttpTransaction> trans(
690 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59691 CreateSession(&session_deps),
692 &session_deps.socket_factory));
[email protected]2d2697f92009-02-18 21:00:32693
[email protected]1c773ea12009-04-28 19:58:42694 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:32695 request.method = "GET";
696 request.url = GURL("http://www.google.com/");
697 request.load_flags = 0;
698
699 MockWrite data_writes1[] = {
700 MockWrite("GET / HTTP/1.1\r\n"
701 "Host: www.google.com\r\n"
702 "Connection: keep-alive\r\n\r\n"),
703
704 // After calling trans->RestartWithAuth(), this is the request we should
705 // be issuing -- the final header line contains the credentials.
706 MockWrite("GET / HTTP/1.1\r\n"
707 "Host: www.google.com\r\n"
708 "Connection: keep-alive\r\n"
709 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
710 };
711
712 MockRead data_reads1[] = {
713 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
714 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
715 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
716 MockRead("Content-Length: 14\r\n\r\n"),
717 MockRead("Unauthorized\r\n"),
718
719 // Lastly, the server responds with the actual content.
720 MockRead("HTTP/1.1 200 OK\r\n"),
721 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
722 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:42723 MockRead(false, OK),
[email protected]2d2697f92009-02-18 21:00:32724 };
725
[email protected]69b43fe2009-06-15 09:47:37726 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]228ff742009-06-05 01:19:59727 session_deps.socket_factory.AddMockSocket(&data1);
[email protected]2d2697f92009-02-18 21:00:32728
729 TestCompletionCallback callback1;
730
731 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:42732 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32733
734 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42735 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:32736
[email protected]1c773ea12009-04-28 19:58:42737 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]2d2697f92009-02-18 21:00:32738 EXPECT_FALSE(response == NULL);
739
740 // The password prompt info should have been set in response->auth_challenge.
741 EXPECT_FALSE(response->auth_challenge.get() == NULL);
742
[email protected]71e4573a2009-05-21 22:03:00743 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]2d2697f92009-02-18 21:00:32744 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
745 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
746
747 TestCompletionCallback callback2;
748
749 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
[email protected]1c773ea12009-04-28 19:58:42750 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32751
752 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42753 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:32754
755 response = trans->GetResponseInfo();
756 EXPECT_FALSE(response == NULL);
757 EXPECT_TRUE(response->auth_challenge.get() == NULL);
758 EXPECT_EQ(100, response->headers->GetContentLength());
759}
760
761// Test the request-challenge-retry sequence for basic auth, over a keep-alive
762// connection and with no response body to drain.
763TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]228ff742009-06-05 01:19:59764 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40765 scoped_ptr<HttpTransaction> trans(
766 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59767 CreateSession(&session_deps),
768 &session_deps.socket_factory));
[email protected]2d2697f92009-02-18 21:00:32769
[email protected]1c773ea12009-04-28 19:58:42770 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:32771 request.method = "GET";
772 request.url = GURL("http://www.google.com/");
773 request.load_flags = 0;
774
775 MockWrite data_writes1[] = {
776 MockWrite("GET / HTTP/1.1\r\n"
777 "Host: www.google.com\r\n"
778 "Connection: keep-alive\r\n\r\n"),
779
780 // After calling trans->RestartWithAuth(), this is the request we should
781 // be issuing -- the final header line contains the credentials.
782 MockWrite("GET / HTTP/1.1\r\n"
783 "Host: www.google.com\r\n"
784 "Connection: keep-alive\r\n"
785 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
786 };
787
788 // Respond with 5 kb of response body.
789 std::string large_body_string("Unauthorized");
790 large_body_string.append(5 * 1024, ' ');
791 large_body_string.append("\r\n");
792
793 MockRead data_reads1[] = {
794 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
795 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
796 MockRead("Content-Length: 0\r\n\r\n"),
797
798 // Lastly, the server responds with the actual content.
799 MockRead("HTTP/1.1 200 OK\r\n"),
800 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
801 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:42802 MockRead(false, OK),
[email protected]2d2697f92009-02-18 21:00:32803 };
804
[email protected]69b43fe2009-06-15 09:47:37805 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]228ff742009-06-05 01:19:59806 session_deps.socket_factory.AddMockSocket(&data1);
[email protected]2d2697f92009-02-18 21:00:32807
808 TestCompletionCallback callback1;
809
810 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:42811 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32812
813 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42814 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:32815
[email protected]1c773ea12009-04-28 19:58:42816 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]2d2697f92009-02-18 21:00:32817 EXPECT_FALSE(response == NULL);
818
819 // The password prompt info should have been set in response->auth_challenge.
820 EXPECT_FALSE(response->auth_challenge.get() == NULL);
821
[email protected]71e4573a2009-05-21 22:03:00822 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]2d2697f92009-02-18 21:00:32823 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
824 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
825
826 TestCompletionCallback callback2;
827
828 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
[email protected]1c773ea12009-04-28 19:58:42829 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32830
831 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42832 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:32833
834 response = trans->GetResponseInfo();
835 EXPECT_FALSE(response == NULL);
836 EXPECT_TRUE(response->auth_challenge.get() == NULL);
837 EXPECT_EQ(100, response->headers->GetContentLength());
838}
839
840// Test the request-challenge-retry sequence for basic auth, over a keep-alive
841// connection and with a large response body to drain.
842TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]228ff742009-06-05 01:19:59843 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:40844 scoped_ptr<HttpTransaction> trans(
845 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59846 CreateSession(&session_deps),
847 &session_deps.socket_factory));
[email protected]2d2697f92009-02-18 21:00:32848
[email protected]1c773ea12009-04-28 19:58:42849 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:32850 request.method = "GET";
851 request.url = GURL("http://www.google.com/");
852 request.load_flags = 0;
853
854 MockWrite data_writes1[] = {
855 MockWrite("GET / HTTP/1.1\r\n"
856 "Host: www.google.com\r\n"
857 "Connection: keep-alive\r\n\r\n"),
858
859 // After calling trans->RestartWithAuth(), this is the request we should
860 // be issuing -- the final header line contains the credentials.
861 MockWrite("GET / HTTP/1.1\r\n"
862 "Host: www.google.com\r\n"
863 "Connection: keep-alive\r\n"
864 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
865 };
866
867 // Respond with 5 kb of response body.
868 std::string large_body_string("Unauthorized");
869 large_body_string.append(5 * 1024, ' ');
870 large_body_string.append("\r\n");
871
872 MockRead data_reads1[] = {
873 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
874 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
875 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
876 // 5134 = 12 + 5 * 1024 + 2
877 MockRead("Content-Length: 5134\r\n\r\n"),
878 MockRead(true, large_body_string.data(), large_body_string.size()),
879
880 // Lastly, the server responds with the actual content.
881 MockRead("HTTP/1.1 200 OK\r\n"),
882 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
883 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:42884 MockRead(false, OK),
[email protected]2d2697f92009-02-18 21:00:32885 };
886
[email protected]69b43fe2009-06-15 09:47:37887 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]228ff742009-06-05 01:19:59888 session_deps.socket_factory.AddMockSocket(&data1);
[email protected]2d2697f92009-02-18 21:00:32889
890 TestCompletionCallback callback1;
891
892 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:42893 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32894
895 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42896 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:32897
[email protected]1c773ea12009-04-28 19:58:42898 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]2d2697f92009-02-18 21:00:32899 EXPECT_FALSE(response == NULL);
900
901 // The password prompt info should have been set in response->auth_challenge.
902 EXPECT_FALSE(response->auth_challenge.get() == NULL);
903
[email protected]71e4573a2009-05-21 22:03:00904 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]2d2697f92009-02-18 21:00:32905 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
906 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
907
908 TestCompletionCallback callback2;
909
910 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
[email protected]1c773ea12009-04-28 19:58:42911 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32912
913 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42914 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:32915
916 response = trans->GetResponseInfo();
917 EXPECT_FALSE(response == NULL);
918 EXPECT_TRUE(response->auth_challenge.get() == NULL);
919 EXPECT_EQ(100, response->headers->GetContentLength());
920}
921
922// Test the request-challenge-retry sequence for basic auth, over a keep-alive
923// proxy connection, when setting up an SSL tunnel.
924TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
925 // Configure against proxy server "myproxy:70".
[email protected]228ff742009-06-05 01:19:59926 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
927 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]2d2697f92009-02-18 21:00:32928
[email protected]1c773ea12009-04-28 19:58:42929 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:59930 session.get(), &session_deps.socket_factory));
[email protected]2d2697f92009-02-18 21:00:32931
[email protected]1c773ea12009-04-28 19:58:42932 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:32933 request.method = "GET";
934 request.url = GURL("https://www.google.com/");
935 request.load_flags = 0;
936
937 // Since we have proxy, should try to establish tunnel.
938 MockWrite data_writes1[] = {
939 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:45940 "Host: www.google.com\r\n"
941 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:32942
943 // After calling trans->RestartWithAuth(), this is the request we should
944 // be issuing -- the final header line contains the credentials.
945 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
946 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:45947 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:32948 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
949 };
950
951 // The proxy responds to the connect with a 407, using a persistent
952 // connection.
953 MockRead data_reads1[] = {
954 // No credentials.
955 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
956 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
957 MockRead("Content-Length: 10\r\n\r\n"),
958 MockRead("0123456789"),
959
960 // Wrong credentials (wrong password).
961 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
962 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
963 MockRead("Content-Length: 10\r\n\r\n"),
964 // No response body because the test stops reading here.
[email protected]1c773ea12009-04-28 19:58:42965 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:32966 };
967
[email protected]69b43fe2009-06-15 09:47:37968 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]228ff742009-06-05 01:19:59969 session_deps.socket_factory.AddMockSocket(&data1);
[email protected]2d2697f92009-02-18 21:00:32970
971 TestCompletionCallback callback1;
972
973 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:42974 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32975
976 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42977 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:32978
[email protected]1c773ea12009-04-28 19:58:42979 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]2d2697f92009-02-18 21:00:32980 EXPECT_FALSE(response == NULL);
981
982 EXPECT_TRUE(response->headers->IsKeepAlive());
983 EXPECT_EQ(407, response->headers->response_code());
984 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:42985 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]2d2697f92009-02-18 21:00:32986
987 // The password prompt info should have been set in response->auth_challenge.
988 EXPECT_FALSE(response->auth_challenge.get() == NULL);
989
[email protected]71e4573a2009-05-21 22:03:00990 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
[email protected]2d2697f92009-02-18 21:00:32991 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
992 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
993
994 TestCompletionCallback callback2;
995
996 // Wrong password (should be "bar").
997 rv = trans->RestartWithAuth(L"foo", L"baz", &callback2);
[email protected]1c773ea12009-04-28 19:58:42998 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:32999
1000 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421001 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321002
1003 response = trans->GetResponseInfo();
1004 EXPECT_FALSE(response == NULL);
1005
1006 EXPECT_TRUE(response->headers->IsKeepAlive());
1007 EXPECT_EQ(407, response->headers->response_code());
1008 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:421009 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]2d2697f92009-02-18 21:00:321010
1011 // The password prompt info should have been set in response->auth_challenge.
1012 EXPECT_FALSE(response->auth_challenge.get() == NULL);
1013
[email protected]71e4573a2009-05-21 22:03:001014 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
[email protected]2d2697f92009-02-18 21:00:321015 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
1016 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
1017}
1018
[email protected]a8e9b162009-03-12 00:06:441019// Test that we don't read the response body when we fail to establish a tunnel,
1020// even if the user cancels the proxy's auth attempt.
1021TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
1022 // Configure against proxy server "myproxy:70".
[email protected]228ff742009-06-05 01:19:591023 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:441024
[email protected]e44de5d2009-06-05 20:12:451025 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]a8e9b162009-03-12 00:06:441026
[email protected]1c773ea12009-04-28 19:58:421027 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591028 session.get(), &session_deps.socket_factory));
[email protected]a8e9b162009-03-12 00:06:441029
[email protected]1c773ea12009-04-28 19:58:421030 HttpRequestInfo request;
[email protected]a8e9b162009-03-12 00:06:441031 request.method = "GET";
1032 request.url = GURL("https://www.google.com/");
1033 request.load_flags = 0;
1034
1035 // Since we have proxy, should try to establish tunnel.
1036 MockWrite data_writes[] = {
1037 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:451038 "Host: www.google.com\r\n"
1039 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:441040 };
1041
1042 // The proxy responds to the connect with a 407.
1043 MockRead data_reads[] = {
1044 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
1045 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1046 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421047 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:441048 };
1049
[email protected]69b43fe2009-06-15 09:47:371050 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:591051 session_deps.socket_factory.AddMockSocket(&data);
[email protected]a8e9b162009-03-12 00:06:441052
1053 TestCompletionCallback callback;
1054
1055 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:421056 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:441057
1058 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421059 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:441060
[email protected]1c773ea12009-04-28 19:58:421061 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]a8e9b162009-03-12 00:06:441062 EXPECT_FALSE(response == NULL);
1063
1064 EXPECT_TRUE(response->headers->IsKeepAlive());
1065 EXPECT_EQ(407, response->headers->response_code());
1066 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:421067 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:441068
1069 std::string response_data;
1070 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421071 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]a8e9b162009-03-12 00:06:441072}
1073
[email protected]ff007e162009-05-23 09:13:151074void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:081075 const MockRead& status, int expected_status) {
1076 // Configure against proxy server "myproxy:70".
[email protected]228ff742009-06-05 01:19:591077 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
[email protected]c744cf22009-02-27 07:28:081078
[email protected]228ff742009-06-05 01:19:591079 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]c744cf22009-02-27 07:28:081080
[email protected]1c773ea12009-04-28 19:58:421081 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591082 session.get(), &session_deps.socket_factory));
[email protected]c744cf22009-02-27 07:28:081083
[email protected]1c773ea12009-04-28 19:58:421084 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:081085 request.method = "GET";
1086 request.url = GURL("https://www.google.com/");
1087 request.load_flags = 0;
1088
1089 // Since we have proxy, should try to establish tunnel.
1090 MockWrite data_writes[] = {
1091 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:451092 "Host: www.google.com\r\n"
1093 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:081094 };
1095
1096 MockRead data_reads[] = {
1097 status,
1098 MockRead("Content-Length: 10\r\n\r\n"),
1099 // No response body because the test stops reading here.
[email protected]1c773ea12009-04-28 19:58:421100 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:081101 };
1102
[email protected]69b43fe2009-06-15 09:47:371103 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:591104 session_deps.socket_factory.AddMockSocket(&data);
[email protected]c744cf22009-02-27 07:28:081105
1106 TestCompletionCallback callback;
1107
1108 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:421109 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:081110
1111 rv = callback.WaitForResult();
1112 EXPECT_EQ(expected_status, rv);
1113}
1114
[email protected]ff007e162009-05-23 09:13:151115void HttpNetworkTransactionTest::ConnectStatusHelper(const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:081116 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:421117 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:081118}
1119
1120TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
1121 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
1122}
1123
1124TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
1125 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
1126}
1127
1128TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
1129 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
1130}
1131
1132TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
1133 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
1134}
1135
1136TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
1137 ConnectStatusHelper(
1138 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
1139}
1140
1141TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
1142 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
1143}
1144
1145TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
1146 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
1147}
1148
1149TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
1150 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
1151}
1152
1153TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
1154 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
1155}
1156
1157TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
1158 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
1159}
1160
1161TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
1162 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
1163}
1164
1165TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
1166 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
1167}
1168
1169TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
1170 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
1171}
1172
1173TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
1174 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
1175}
1176
1177TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
1178 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
1179}
1180
1181TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
1182 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
1183}
1184
1185TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
1186 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
1187}
1188
1189TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
1190 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
1191}
1192
1193TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
1194 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
1195}
1196
1197TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
1198 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
1199}
1200
1201TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
1202 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
1203}
1204
1205TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
1206 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
1207}
1208
1209TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
1210 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
1211}
1212
1213TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
1214 ConnectStatusHelperWithExpectedStatus(
1215 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]1c773ea12009-04-28 19:58:421216 ERR_PROXY_AUTH_REQUESTED);
[email protected]c744cf22009-02-27 07:28:081217}
1218
1219TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
1220 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
1221}
1222
1223TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
1224 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
1225}
1226
1227TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
1228 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
1229}
1230
1231TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
1232 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
1233}
1234
1235TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
1236 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
1237}
1238
1239TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
1240 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
1241}
1242
1243TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
1244 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
1245}
1246
1247TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
1248 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
1249}
1250
1251TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
1252 ConnectStatusHelper(
1253 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
1254}
1255
1256TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
1257 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
1258}
1259
1260TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
1261 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
1262}
1263
1264TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
1265 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
1266}
1267
1268TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
1269 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
1270}
1271
1272TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
1273 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
1274}
1275
1276TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
1277 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
1278}
1279
1280TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
1281 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
1282}
1283
[email protected]038e9a32008-10-08 22:40:161284// Test the flow when both the proxy server AND origin server require
1285// authentication. Again, this uses basic auth for both since that is
1286// the simplest to mock.
1287TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]228ff742009-06-05 01:19:591288 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:011289
[email protected]038e9a32008-10-08 22:40:161290 // Configure against proxy server "myproxy:70".
[email protected]1c773ea12009-04-28 19:58:421291 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591292 CreateSession(&session_deps),
1293 &session_deps.socket_factory));
[email protected]038e9a32008-10-08 22:40:161294
[email protected]1c773ea12009-04-28 19:58:421295 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161296 request.method = "GET";
1297 request.url = GURL("http://www.google.com/");
1298 request.load_flags = 0;
1299
[email protected]f9ee6b52008-11-08 06:46:231300 MockWrite data_writes1[] = {
1301 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
1302 "Host: www.google.com\r\n"
1303 "Proxy-Connection: keep-alive\r\n\r\n"),
1304 };
1305
[email protected]038e9a32008-10-08 22:40:161306 MockRead data_reads1[] = {
1307 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
1308 // Give a couple authenticate options (only the middle one is actually
1309 // supported).
[email protected]aaead502008-10-15 00:20:111310 MockRead("Proxy-Authenticate: Basic\r\n"), // Malformed
[email protected]038e9a32008-10-08 22:40:161311 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1312 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1313 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1314 // Large content-length -- won't matter, as connection will be reset.
1315 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421316 MockRead(false, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161317 };
1318
1319 // After calling trans->RestartWithAuth() the first time, this is the
1320 // request we should be issuing -- the final header line contains the
1321 // proxy's credentials.
1322 MockWrite data_writes2[] = {
1323 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
1324 "Host: www.google.com\r\n"
1325 "Proxy-Connection: keep-alive\r\n"
1326 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1327 };
1328
1329 // Now the proxy server lets the request pass through to origin server.
1330 // The origin server responds with a 401.
1331 MockRead data_reads2[] = {
1332 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1333 // Note: We are using the same realm-name as the proxy server. This is
1334 // completely valid, as realms are unique across hosts.
1335 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1336 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1337 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421338 MockRead(false, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:161339 };
1340
1341 // After calling trans->RestartWithAuth() the second time, we should send
1342 // the credentials for both the proxy and origin server.
1343 MockWrite data_writes3[] = {
1344 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
1345 "Host: www.google.com\r\n"
1346 "Proxy-Connection: keep-alive\r\n"
1347 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
1348 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
1349 };
1350
1351 // Lastly we get the desired content.
1352 MockRead data_reads3[] = {
1353 MockRead("HTTP/1.0 200 OK\r\n"),
1354 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1355 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421356 MockRead(false, OK),
[email protected]038e9a32008-10-08 22:40:161357 };
1358
[email protected]69b43fe2009-06-15 09:47:371359 StaticMockSocket data1(data_reads1, data_writes1);
1360 StaticMockSocket data2(data_reads2, data_writes2);
1361 StaticMockSocket data3(data_reads3, data_writes3);
[email protected]228ff742009-06-05 01:19:591362 session_deps.socket_factory.AddMockSocket(&data1);
1363 session_deps.socket_factory.AddMockSocket(&data2);
1364 session_deps.socket_factory.AddMockSocket(&data3);
[email protected]038e9a32008-10-08 22:40:161365
1366 TestCompletionCallback callback1;
1367
1368 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:421369 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161370
1371 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421372 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161373
[email protected]1c773ea12009-04-28 19:58:421374 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]038e9a32008-10-08 22:40:161375 EXPECT_FALSE(response == NULL);
1376
1377 // The password prompt info should have been set in response->auth_challenge.
1378 EXPECT_FALSE(response->auth_challenge.get() == NULL);
1379
[email protected]71e4573a2009-05-21 22:03:001380 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
[email protected]038e9a32008-10-08 22:40:161381 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
1382 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
1383
1384 TestCompletionCallback callback2;
1385
1386 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
[email protected]1c773ea12009-04-28 19:58:421387 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161388
1389 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421390 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161391
1392 response = trans->GetResponseInfo();
1393 EXPECT_FALSE(response == NULL);
1394 EXPECT_FALSE(response->auth_challenge.get() == NULL);
1395
[email protected]71e4573a2009-05-21 22:03:001396 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]038e9a32008-10-08 22:40:161397 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
1398 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
1399
1400 TestCompletionCallback callback3;
1401
1402 rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback3);
[email protected]1c773ea12009-04-28 19:58:421403 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161404
1405 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421406 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161407
1408 response = trans->GetResponseInfo();
1409 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1410 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161411}
[email protected]4ddaf2502008-10-23 18:26:191412
[email protected]385a4672009-03-11 22:21:291413// The NTLM authentication unit tests were generated by capturing the HTTP
1414// requests and responses using Fiddler 2 and inspecting the generated random
1415// bytes in the debugger.
1416
1417// Enter the correct password and authenticate successfully.
1418TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:421419 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
[email protected]fe2bc6a2009-03-23 16:52:201420 MockGetHostName);
[email protected]228ff742009-06-05 01:19:591421 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:401422 scoped_ptr<HttpTransaction> trans(
1423 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591424 CreateSession(&session_deps),
1425 &session_deps.socket_factory));
[email protected]3f918782009-02-28 01:29:241426
[email protected]1c773ea12009-04-28 19:58:421427 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:241428 request.method = "GET";
1429 request.url = GURL("http://172.22.68.17/kids/login.aspx");
1430 request.load_flags = 0;
1431
1432 MockWrite data_writes1[] = {
1433 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1434 "Host: 172.22.68.17\r\n"
1435 "Connection: keep-alive\r\n\r\n"),
1436 };
1437
1438 MockRead data_reads1[] = {
1439 MockRead("HTTP/1.1 401 Access Denied\r\n"),
1440 // Negotiate and NTLM are often requested together. We only support NTLM.
1441 MockRead("WWW-Authenticate: Negotiate\r\n"),
1442 MockRead("WWW-Authenticate: NTLM\r\n"),
1443 MockRead("Connection: close\r\n"),
1444 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:361445 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:241446 // Missing content -- won't matter, as connection will be reset.
[email protected]1c773ea12009-04-28 19:58:421447 MockRead(false, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:241448 };
1449
1450 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:221451 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:241452 // request we should be issuing -- the final header line contains a Type
1453 // 1 message.
1454 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1455 "Host: 172.22.68.17\r\n"
1456 "Connection: keep-alive\r\n"
1457 "Authorization: NTLM "
1458 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
1459
1460 // After calling trans->RestartWithAuth(), we should send a Type 3 message
1461 // (the credentials for the origin server). The second request continues
1462 // on the same connection.
1463 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1464 "Host: 172.22.68.17\r\n"
1465 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:291466 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
1467 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
1468 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
1469 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
1470 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:241471 };
1472
1473 MockRead data_reads2[] = {
1474 // The origin server responds with a Type 2 message.
1475 MockRead("HTTP/1.1 401 Access Denied\r\n"),
1476 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:291477 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:241478 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
1479 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
1480 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
1481 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
1482 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
1483 "BtAAAAAAA=\r\n"),
1484 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:361485 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:241486 MockRead("You are not authorized to view this page\r\n"),
1487
1488 // Lastly we get the desired content.
1489 MockRead("HTTP/1.1 200 OK\r\n"),
1490 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
1491 MockRead("Content-Length: 13\r\n\r\n"),
1492 MockRead("Please Login\r\n"),
[email protected]1c773ea12009-04-28 19:58:421493 MockRead(false, OK),
[email protected]3f918782009-02-28 01:29:241494 };
1495
[email protected]69b43fe2009-06-15 09:47:371496 StaticMockSocket data1(data_reads1, data_writes1);
1497 StaticMockSocket data2(data_reads2, data_writes2);
[email protected]228ff742009-06-05 01:19:591498 session_deps.socket_factory.AddMockSocket(&data1);
1499 session_deps.socket_factory.AddMockSocket(&data2);
[email protected]3f918782009-02-28 01:29:241500
1501 TestCompletionCallback callback1;
1502
1503 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:421504 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:241505
1506 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421507 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:241508
[email protected]0757e7702009-03-27 04:00:221509 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
1510 TestCompletionCallback callback2;
1511 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
[email protected]1c773ea12009-04-28 19:58:421512 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:221513 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421514 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:221515 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
1516
[email protected]1c773ea12009-04-28 19:58:421517 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3f918782009-02-28 01:29:241518 EXPECT_FALSE(response == NULL);
1519
1520 // The password prompt info should have been set in response->auth_challenge.
1521 EXPECT_FALSE(response->auth_challenge.get() == NULL);
1522
[email protected]71e4573a2009-05-21 22:03:001523 EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
[email protected]3f918782009-02-28 01:29:241524 EXPECT_EQ(L"", response->auth_challenge->realm);
1525 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
1526
[email protected]0757e7702009-03-27 04:00:221527 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:241528
[email protected]0757e7702009-03-27 04:00:221529 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback3);
[email protected]1c773ea12009-04-28 19:58:421530 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:241531
[email protected]0757e7702009-03-27 04:00:221532 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421533 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:241534
1535 response = trans->GetResponseInfo();
1536 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1537 EXPECT_EQ(13, response->headers->GetContentLength());
1538}
1539
[email protected]385a4672009-03-11 22:21:291540// Enter a wrong password, and then the correct one.
1541TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:421542 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
[email protected]fe2bc6a2009-03-23 16:52:201543 MockGetHostName);
[email protected]228ff742009-06-05 01:19:591544 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:401545 scoped_ptr<HttpTransaction> trans(
1546 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591547 CreateSession(&session_deps),
1548 &session_deps.socket_factory));
[email protected]385a4672009-03-11 22:21:291549
[email protected]1c773ea12009-04-28 19:58:421550 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:291551 request.method = "GET";
1552 request.url = GURL("http://172.22.68.17/kids/login.aspx");
1553 request.load_flags = 0;
1554
1555 MockWrite data_writes1[] = {
1556 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1557 "Host: 172.22.68.17\r\n"
1558 "Connection: keep-alive\r\n\r\n"),
1559 };
1560
1561 MockRead data_reads1[] = {
1562 MockRead("HTTP/1.1 401 Access Denied\r\n"),
1563 // Negotiate and NTLM are often requested together. We only support NTLM.
1564 MockRead("WWW-Authenticate: Negotiate\r\n"),
1565 MockRead("WWW-Authenticate: NTLM\r\n"),
1566 MockRead("Connection: close\r\n"),
1567 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:361568 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:291569 // Missing content -- won't matter, as connection will be reset.
[email protected]1c773ea12009-04-28 19:58:421570 MockRead(false, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:291571 };
1572
1573 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:221574 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:291575 // request we should be issuing -- the final header line contains a Type
1576 // 1 message.
1577 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1578 "Host: 172.22.68.17\r\n"
1579 "Connection: keep-alive\r\n"
1580 "Authorization: NTLM "
1581 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
1582
1583 // After calling trans->RestartWithAuth(), we should send a Type 3 message
1584 // (the credentials for the origin server). The second request continues
1585 // on the same connection.
1586 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1587 "Host: 172.22.68.17\r\n"
1588 "Connection: keep-alive\r\n"
1589 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
1590 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
1591 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
1592 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
1593 "4Ww7b7E=\r\n\r\n"),
1594 };
1595
1596 MockRead data_reads2[] = {
1597 // The origin server responds with a Type 2 message.
1598 MockRead("HTTP/1.1 401 Access Denied\r\n"),
1599 MockRead("WWW-Authenticate: NTLM "
1600 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
1601 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
1602 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
1603 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
1604 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
1605 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
1606 "BtAAAAAAA=\r\n"),
1607 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:361608 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:291609 MockRead("You are not authorized to view this page\r\n"),
1610
1611 // Wrong password.
1612 MockRead("HTTP/1.1 401 Access Denied\r\n"),
1613 MockRead("WWW-Authenticate: Negotiate\r\n"),
1614 MockRead("WWW-Authenticate: NTLM\r\n"),
1615 MockRead("Connection: close\r\n"),
1616 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:361617 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:291618 // Missing content -- won't matter, as connection will be reset.
[email protected]1c773ea12009-04-28 19:58:421619 MockRead(false, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:291620 };
1621
1622 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:221623 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:291624 // request we should be issuing -- the final header line contains a Type
1625 // 1 message.
1626 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1627 "Host: 172.22.68.17\r\n"
1628 "Connection: keep-alive\r\n"
1629 "Authorization: NTLM "
1630 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
1631
1632 // After calling trans->RestartWithAuth(), we should send a Type 3 message
1633 // (the credentials for the origin server). The second request continues
1634 // on the same connection.
1635 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
1636 "Host: 172.22.68.17\r\n"
1637 "Connection: keep-alive\r\n"
1638 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
1639 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
1640 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
1641 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
1642 "+4MUm7c=\r\n\r\n"),
1643 };
1644
1645 MockRead data_reads3[] = {
1646 // The origin server responds with a Type 2 message.
1647 MockRead("HTTP/1.1 401 Access Denied\r\n"),
1648 MockRead("WWW-Authenticate: NTLM "
1649 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
1650 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
1651 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
1652 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
1653 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
1654 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
1655 "BtAAAAAAA=\r\n"),
1656 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:361657 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:291658 MockRead("You are not authorized to view this page\r\n"),
1659
1660 // Lastly we get the desired content.
1661 MockRead("HTTP/1.1 200 OK\r\n"),
1662 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
1663 MockRead("Content-Length: 13\r\n\r\n"),
1664 MockRead("Please Login\r\n"),
[email protected]1c773ea12009-04-28 19:58:421665 MockRead(false, OK),
[email protected]385a4672009-03-11 22:21:291666 };
1667
[email protected]69b43fe2009-06-15 09:47:371668 StaticMockSocket data1(data_reads1, data_writes1);
1669 StaticMockSocket data2(data_reads2, data_writes2);
1670 StaticMockSocket data3(data_reads3, data_writes3);
[email protected]228ff742009-06-05 01:19:591671 session_deps.socket_factory.AddMockSocket(&data1);
1672 session_deps.socket_factory.AddMockSocket(&data2);
1673 session_deps.socket_factory.AddMockSocket(&data3);
[email protected]385a4672009-03-11 22:21:291674
1675 TestCompletionCallback callback1;
1676
1677 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:421678 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:291679
1680 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421681 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:291682
[email protected]0757e7702009-03-27 04:00:221683 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:291684 TestCompletionCallback callback2;
[email protected]0757e7702009-03-27 04:00:221685 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
[email protected]1c773ea12009-04-28 19:58:421686 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:291687 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421688 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:221689 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:291690
[email protected]1c773ea12009-04-28 19:58:421691 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]385a4672009-03-11 22:21:291692 EXPECT_FALSE(response == NULL);
1693
1694 // The password prompt info should have been set in response->auth_challenge.
1695 EXPECT_FALSE(response->auth_challenge.get() == NULL);
1696
[email protected]71e4573a2009-05-21 22:03:001697 EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
[email protected]385a4672009-03-11 22:21:291698 EXPECT_EQ(L"", response->auth_challenge->realm);
1699 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
1700
1701 TestCompletionCallback callback3;
1702
[email protected]0757e7702009-03-27 04:00:221703 // Enter the wrong password.
1704 rv = trans->RestartWithAuth(L"testing-ntlm", L"wrongpassword", &callback3);
[email protected]1c773ea12009-04-28 19:58:421705 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:291706
1707 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421708 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:291709
[email protected]0757e7702009-03-27 04:00:221710 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
1711 TestCompletionCallback callback4;
1712 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback4);
[email protected]1c773ea12009-04-28 19:58:421713 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:221714 rv = callback4.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421715 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:221716 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
1717
1718 response = trans->GetResponseInfo();
1719 EXPECT_FALSE(response == NULL);
1720
1721 // The password prompt info should have been set in response->auth_challenge.
1722 EXPECT_FALSE(response->auth_challenge.get() == NULL);
1723
[email protected]71e4573a2009-05-21 22:03:001724 EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
[email protected]0757e7702009-03-27 04:00:221725 EXPECT_EQ(L"", response->auth_challenge->realm);
1726 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
1727
1728 TestCompletionCallback callback5;
1729
1730 // Now enter the right password.
1731 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback5);
[email protected]1c773ea12009-04-28 19:58:421732 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:221733
1734 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421735 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:221736
[email protected]385a4672009-03-11 22:21:291737 response = trans->GetResponseInfo();
1738 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1739 EXPECT_EQ(13, response->headers->GetContentLength());
1740}
1741
[email protected]4ddaf2502008-10-23 18:26:191742// Test reading a server response which has only headers, and no body.
1743// After some maximum number of bytes is consumed, the transaction should
1744// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
1745TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]228ff742009-06-05 01:19:591746 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:401747 scoped_ptr<HttpTransaction> trans(
1748 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591749 CreateSession(&session_deps),
1750 &session_deps.socket_factory));
[email protected]4ddaf2502008-10-23 18:26:191751
[email protected]1c773ea12009-04-28 19:58:421752 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:191753 request.method = "GET";
1754 request.url = GURL("http://www.google.com/");
1755 request.load_flags = 0;
1756
1757 // Respond with 50 kb of headers (we should fail after 32 kb).
[email protected]15a5ccf82008-10-23 19:57:431758 std::string large_headers_string;
1759 FillLargeHeadersString(&large_headers_string, 50 * 1024);
[email protected]4ddaf2502008-10-23 18:26:191760
1761 MockRead data_reads[] = {
1762 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]15a5ccf82008-10-23 19:57:431763 MockRead(true, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:191764 MockRead("\r\nBODY"),
[email protected]1c773ea12009-04-28 19:58:421765 MockRead(false, OK),
[email protected]4ddaf2502008-10-23 18:26:191766 };
[email protected]69b43fe2009-06-15 09:47:371767 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:591768 session_deps.socket_factory.AddMockSocket(&data);
[email protected]4ddaf2502008-10-23 18:26:191769
1770 TestCompletionCallback callback;
1771
1772 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:421773 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:191774
1775 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421776 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:191777
[email protected]1c773ea12009-04-28 19:58:421778 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:191779 EXPECT_TRUE(response == NULL);
1780}
[email protected]f4e426b2008-11-05 00:24:491781
1782// Make sure that we don't try to reuse a TCPClientSocket when failing to
1783// establish tunnel.
1784// http://code.google.com/p/chromium/issues/detail?id=3772
1785TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) {
1786 // Configure against proxy server "myproxy:70".
[email protected]228ff742009-06-05 01:19:591787 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:011788
[email protected]228ff742009-06-05 01:19:591789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]f4e426b2008-11-05 00:24:491790
[email protected]1c773ea12009-04-28 19:58:421791 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591792 session.get(), &session_deps.socket_factory));
[email protected]f4e426b2008-11-05 00:24:491793
[email protected]1c773ea12009-04-28 19:58:421794 HttpRequestInfo request;
[email protected]f4e426b2008-11-05 00:24:491795 request.method = "GET";
1796 request.url = GURL("https://www.google.com/");
1797 request.load_flags = 0;
1798
1799 // Since we have proxy, should try to establish tunnel.
1800 MockWrite data_writes1[] = {
1801 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:451802 "Host: www.google.com\r\n"
1803 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:491804 };
1805
[email protected]77848d12008-11-14 00:00:221806 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:491807 // connection. Usually a proxy would return 501 (not implemented),
1808 // or 200 (tunnel established).
1809 MockRead data_reads1[] = {
1810 MockRead("HTTP/1.1 404 Not Found\r\n"),
1811 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:421812 MockRead(false, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:491813 };
1814
[email protected]69b43fe2009-06-15 09:47:371815 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]228ff742009-06-05 01:19:591816 session_deps.socket_factory.AddMockSocket(&data1);
[email protected]f4e426b2008-11-05 00:24:491817
1818 TestCompletionCallback callback1;
1819
1820 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:421821 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:491822
1823 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421824 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:491825
[email protected]1c773ea12009-04-28 19:58:421826 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:081827 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:491828
[email protected]b4404c02009-04-10 16:38:521829 // Empty the current queue. This is necessary because idle sockets are
1830 // added to the connection pool asynchronously with a PostTask.
1831 MessageLoop::current()->RunAllPending();
1832
[email protected]f4e426b2008-11-05 00:24:491833 // We now check to make sure the TCPClientSocket was not added back to
1834 // the pool.
[email protected]df0c05c62009-06-17 15:50:581835 EXPECT_EQ(0, session->connection_pool()->IdleSocketCount());
[email protected]f4e426b2008-11-05 00:24:491836 trans.reset();
[email protected]b4404c02009-04-10 16:38:521837 MessageLoop::current()->RunAllPending();
[email protected]f4e426b2008-11-05 00:24:491838 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]df0c05c62009-06-17 15:50:581839 EXPECT_EQ(0, session->connection_pool()->IdleSocketCount());
[email protected]f4e426b2008-11-05 00:24:491840}
[email protected]372d34a2008-11-05 21:30:511841
[email protected]1b157c02009-04-21 01:55:401842// Make sure that we recycle a socket after reading all of the response body.
1843TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]228ff742009-06-05 01:19:591844 SessionDependencies session_deps;
1845 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]1b157c02009-04-21 01:55:401846
[email protected]1c773ea12009-04-28 19:58:421847 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591848 session.get(), &session_deps.socket_factory));
[email protected]1b157c02009-04-21 01:55:401849
[email protected]1c773ea12009-04-28 19:58:421850 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:401851 request.method = "GET";
1852 request.url = GURL("http://www.google.com/");
1853 request.load_flags = 0;
1854
1855 MockRead data_reads[] = {
1856 // A part of the response body is received with the response headers.
1857 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
1858 // The rest of the response body is received in two parts.
1859 MockRead("lo"),
1860 MockRead(" world"),
1861 MockRead("junk"), // Should not be read!!
[email protected]1c773ea12009-04-28 19:58:421862 MockRead(false, OK),
[email protected]1b157c02009-04-21 01:55:401863 };
1864
[email protected]69b43fe2009-06-15 09:47:371865 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:591866 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1b157c02009-04-21 01:55:401867
1868 TestCompletionCallback callback;
1869
1870 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:421871 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:401872
1873 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421874 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:401875
[email protected]1c773ea12009-04-28 19:58:421876 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]1b157c02009-04-21 01:55:401877 EXPECT_TRUE(response != NULL);
1878
1879 EXPECT_TRUE(response->headers != NULL);
1880 std::string status_line = response->headers->GetStatusLine();
1881 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
1882
[email protected]df0c05c62009-06-17 15:50:581883 EXPECT_EQ(0, session->connection_pool()->IdleSocketCount());
[email protected]1b157c02009-04-21 01:55:401884
1885 std::string response_data;
1886 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421887 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:401888 EXPECT_EQ("hello world", response_data);
1889
1890 // Empty the current queue. This is necessary because idle sockets are
1891 // added to the connection pool asynchronously with a PostTask.
1892 MessageLoop::current()->RunAllPending();
1893
1894 // We now check to make sure the socket was added back to the pool.
[email protected]df0c05c62009-06-17 15:50:581895 EXPECT_EQ(1, session->connection_pool()->IdleSocketCount());
[email protected]1b157c02009-04-21 01:55:401896}
1897
[email protected]b4404c02009-04-10 16:38:521898// Make sure that we recycle a socket after a zero-length response.
1899// http://crbug.com/9880
1900TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]228ff742009-06-05 01:19:591901 SessionDependencies session_deps;
1902 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
[email protected]b4404c02009-04-10 16:38:521903
[email protected]1c773ea12009-04-28 19:58:421904 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:591905 session.get(), &session_deps.socket_factory));
[email protected]b4404c02009-04-10 16:38:521906
[email protected]1c773ea12009-04-28 19:58:421907 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:521908 request.method = "GET";
1909 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
1910 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
1911 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
1912 "rt=prt.2642,ol.2649,xjs.2951");
1913 request.load_flags = 0;
1914
1915 MockRead data_reads[] = {
1916 MockRead("HTTP/1.1 204 No Content\r\n"
1917 "Content-Length: 0\r\n"
1918 "Content-Type: text/html\r\n\r\n"),
1919 MockRead("junk"), // Should not be read!!
[email protected]1c773ea12009-04-28 19:58:421920 MockRead(false, OK),
[email protected]b4404c02009-04-10 16:38:521921 };
1922
[email protected]69b43fe2009-06-15 09:47:371923 StaticMockSocket data(data_reads, NULL);
[email protected]228ff742009-06-05 01:19:591924 session_deps.socket_factory.AddMockSocket(&data);
[email protected]b4404c02009-04-10 16:38:521925
1926 TestCompletionCallback callback;
1927
1928 int rv = trans->Start(&request, &callback);
[email protected]1c773ea12009-04-28 19:58:421929 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:521930
1931 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421932 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:521933
[email protected]1c773ea12009-04-28 19:58:421934 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]b4404c02009-04-10 16:38:521935 EXPECT_TRUE(response != NULL);
1936
1937 EXPECT_TRUE(response->headers != NULL);
1938 std::string status_line = response->headers->GetStatusLine();
1939 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
1940
[email protected]df0c05c62009-06-17 15:50:581941 EXPECT_EQ(0, session->connection_pool()->IdleSocketCount());
[email protected]b4404c02009-04-10 16:38:521942
1943 std::string response_data;
1944 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421945 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:521946 EXPECT_EQ("", response_data);
1947
1948 // Empty the current queue. This is necessary because idle sockets are
1949 // added to the connection pool asynchronously with a PostTask.
1950 MessageLoop::current()->RunAllPending();
1951
1952 // We now check to make sure the socket was added back to the pool.
[email protected]df0c05c62009-06-17 15:50:581953 EXPECT_EQ(1, session->connection_pool()->IdleSocketCount());
[email protected]b4404c02009-04-10 16:38:521954}
1955
[email protected]372d34a2008-11-05 21:30:511956TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]1c773ea12009-04-28 19:58:421957 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:511958 // Transaction 1: a GET request that succeeds. The socket is recycled
1959 // after use.
1960 request[0].method = "GET";
1961 request[0].url = GURL("http://www.google.com/");
1962 request[0].load_flags = 0;
1963 // Transaction 2: a POST request. Reuses the socket kept alive from
1964 // transaction 1. The first attempts fails when writing the POST data.
1965 // This causes the transaction to retry with a new socket. The second
1966 // attempt succeeds.
1967 request[1].method = "POST";
1968 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]1c773ea12009-04-28 19:58:421969 request[1].upload_data = new UploadData;
[email protected]372d34a2008-11-05 21:30:511970 request[1].upload_data->AppendBytes("foo", 3);
1971 request[1].load_flags = 0;
1972
[email protected]228ff742009-06-05 01:19:591973 SessionDependencies session_deps;
1974 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
[email protected]372d34a2008-11-05 21:30:511975
1976 // The first socket is used for transaction 1 and the first attempt of
1977 // transaction 2.
1978
1979 // The response of transaction 1.
1980 MockRead data_reads1[] = {
1981 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
1982 MockRead("hello world"),
[email protected]1c773ea12009-04-28 19:58:421983 MockRead(false, OK),
[email protected]372d34a2008-11-05 21:30:511984 };
1985 // The mock write results of transaction 1 and the first attempt of
1986 // transaction 2.
1987 MockWrite data_writes1[] = {
1988 MockWrite(false, 64), // GET
1989 MockWrite(false, 93), // POST
[email protected]1c773ea12009-04-28 19:58:421990 MockWrite(false, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:511991 };
[email protected]69b43fe2009-06-15 09:47:371992 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:511993
1994 // The second socket is used for the second attempt of transaction 2.
1995
1996 // The response of transaction 2.
1997 MockRead data_reads2[] = {
1998 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
1999 MockRead("welcome"),
[email protected]1c773ea12009-04-28 19:58:422000 MockRead(false, OK),
[email protected]372d34a2008-11-05 21:30:512001 };
2002 // The mock write results of the second attempt of transaction 2.
2003 MockWrite data_writes2[] = {
2004 MockWrite(false, 93), // POST
2005 MockWrite(false, 3), // POST data
2006 };
[email protected]69b43fe2009-06-15 09:47:372007 StaticMockSocket data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:512008
[email protected]228ff742009-06-05 01:19:592009 session_deps.socket_factory.AddMockSocket(&data1);
2010 session_deps.socket_factory.AddMockSocket(&data2);
[email protected]372d34a2008-11-05 21:30:512011
2012 const char* kExpectedResponseData[] = {
2013 "hello world", "welcome"
2014 };
2015
2016 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:422017 scoped_ptr<HttpTransaction> trans(
[email protected]228ff742009-06-05 01:19:592018 new HttpNetworkTransaction(session, &session_deps.socket_factory));
[email protected]372d34a2008-11-05 21:30:512019
2020 TestCompletionCallback callback;
2021
2022 int rv = trans->Start(&request[i], &callback);
[email protected]1c773ea12009-04-28 19:58:422023 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:512024
2025 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422026 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:512027
[email protected]1c773ea12009-04-28 19:58:422028 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]372d34a2008-11-05 21:30:512029 EXPECT_TRUE(response != NULL);
2030
2031 EXPECT_TRUE(response->headers != NULL);
2032 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2033
2034 std::string response_data;
2035 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422036 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:512037 EXPECT_EQ(kExpectedResponseData[i], response_data);
2038 }
2039}
[email protected]f9ee6b52008-11-08 06:46:232040
2041// Test the request-challenge-retry sequence for basic auth when there is
2042// an identity in the URL. The request should be sent as normal, but when
2043// it fails the identity from the URL is used to answer the challenge.
2044TEST_F(HttpNetworkTransactionTest, AuthIdentityInUrl) {
[email protected]228ff742009-06-05 01:19:592045 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402046 scoped_ptr<HttpTransaction> trans(
2047 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592048 CreateSession(&session_deps),
2049 &session_deps.socket_factory));
[email protected]f9ee6b52008-11-08 06:46:232050
[email protected]1c773ea12009-04-28 19:58:422051 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:232052 request.method = "GET";
2053 // Note: the URL has a username:password in it.
2054 request.url = GURL("http://foo:[email protected]/");
2055 request.load_flags = 0;
2056
2057 MockWrite data_writes1[] = {
2058 MockWrite("GET / HTTP/1.1\r\n"
2059 "Host: www.google.com\r\n"
2060 "Connection: keep-alive\r\n\r\n"),
2061 };
2062
2063 MockRead data_reads1[] = {
2064 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2065 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2066 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422067 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:232068 };
2069
2070 // After the challenge above, the transaction will be restarted using the
2071 // identity from the url (foo, bar) to answer the challenge.
2072 MockWrite data_writes2[] = {
2073 MockWrite("GET / HTTP/1.1\r\n"
2074 "Host: www.google.com\r\n"
2075 "Connection: keep-alive\r\n"
2076 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2077 };
2078
2079 MockRead data_reads2[] = {
2080 MockRead("HTTP/1.0 200 OK\r\n"),
2081 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422082 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:232083 };
2084
[email protected]69b43fe2009-06-15 09:47:372085 StaticMockSocket data1(data_reads1, data_writes1);
2086 StaticMockSocket data2(data_reads2, data_writes2);
[email protected]228ff742009-06-05 01:19:592087 session_deps.socket_factory.AddMockSocket(&data1);
2088 session_deps.socket_factory.AddMockSocket(&data2);
[email protected]f9ee6b52008-11-08 06:46:232089
2090 TestCompletionCallback callback1;
2091
2092 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:422093 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232094
2095 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422096 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232097
[email protected]0757e7702009-03-27 04:00:222098 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
2099 TestCompletionCallback callback2;
2100 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
[email protected]1c773ea12009-04-28 19:58:422101 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:222102 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422103 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:222104 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
2105
[email protected]1c773ea12009-04-28 19:58:422106 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]f9ee6b52008-11-08 06:46:232107 EXPECT_FALSE(response == NULL);
2108
2109 // There is no challenge info, since the identity in URL worked.
2110 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2111
2112 EXPECT_EQ(100, response->headers->GetContentLength());
2113
2114 // Empty the current queue.
2115 MessageLoop::current()->RunAllPending();
2116}
2117
2118// Test that previously tried username/passwords for a realm get re-used.
2119TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]228ff742009-06-05 01:19:592120 SessionDependencies session_deps;
2121 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
[email protected]f9ee6b52008-11-08 06:46:232122
2123 // Transaction 1: authenticate (foo, bar) on MyRealm1
2124 {
[email protected]1c773ea12009-04-28 19:58:422125 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592126 session, &session_deps.socket_factory));
[email protected]f9ee6b52008-11-08 06:46:232127
[email protected]1c773ea12009-04-28 19:58:422128 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:232129 request.method = "GET";
2130 request.url = GURL("http://www.google.com/x/y/z");
2131 request.load_flags = 0;
2132
2133 MockWrite data_writes1[] = {
2134 MockWrite("GET /x/y/z HTTP/1.1\r\n"
2135 "Host: www.google.com\r\n"
2136 "Connection: keep-alive\r\n\r\n"),
2137 };
2138
2139 MockRead data_reads1[] = {
2140 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2141 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2142 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422143 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:232144 };
2145
2146 // Resend with authorization (username=foo, password=bar)
2147 MockWrite data_writes2[] = {
2148 MockWrite("GET /x/y/z HTTP/1.1\r\n"
2149 "Host: www.google.com\r\n"
2150 "Connection: keep-alive\r\n"
2151 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2152 };
2153
2154 // Sever accepts the authorization.
2155 MockRead data_reads2[] = {
2156 MockRead("HTTP/1.0 200 OK\r\n"),
2157 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422158 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:232159 };
2160
[email protected]69b43fe2009-06-15 09:47:372161 StaticMockSocket data1(data_reads1, data_writes1);
2162 StaticMockSocket data2(data_reads2, data_writes2);
[email protected]228ff742009-06-05 01:19:592163 session_deps.socket_factory.AddMockSocket(&data1);
2164 session_deps.socket_factory.AddMockSocket(&data2);
[email protected]f9ee6b52008-11-08 06:46:232165
2166 TestCompletionCallback callback1;
2167
2168 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:422169 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232170
2171 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422172 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232173
[email protected]1c773ea12009-04-28 19:58:422174 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]f9ee6b52008-11-08 06:46:232175 EXPECT_FALSE(response == NULL);
2176
2177 // The password prompt info should have been set in
2178 // response->auth_challenge.
2179 EXPECT_FALSE(response->auth_challenge.get() == NULL);
2180
[email protected]71e4573a2009-05-21 22:03:002181 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]f9ee6b52008-11-08 06:46:232182 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
2183 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
2184
2185 TestCompletionCallback callback2;
2186
2187 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
[email protected]1c773ea12009-04-28 19:58:422188 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232189
2190 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422191 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232192
2193 response = trans->GetResponseInfo();
2194 EXPECT_FALSE(response == NULL);
2195 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2196 EXPECT_EQ(100, response->headers->GetContentLength());
2197 }
2198
2199 // ------------------------------------------------------------------------
2200
2201 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
2202 {
[email protected]1c773ea12009-04-28 19:58:422203 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592204 session, &session_deps.socket_factory));
[email protected]f9ee6b52008-11-08 06:46:232205
[email protected]1c773ea12009-04-28 19:58:422206 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:232207 request.method = "GET";
2208 // Note that Transaction 1 was at /x/y/z, so this is in the same
2209 // protection space as MyRealm1.
2210 request.url = GURL("http://www.google.com/x/y/a/b");
2211 request.load_flags = 0;
2212
2213 MockWrite data_writes1[] = {
2214 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
2215 "Host: www.google.com\r\n"
2216 "Connection: keep-alive\r\n"
2217 // Send preemptive authorization for MyRealm1
2218 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2219 };
2220
2221 // The server didn't like the preemptive authorization, and
2222 // challenges us for a different realm (MyRealm2).
2223 MockRead data_reads1[] = {
2224 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2225 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
2226 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422227 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:232228 };
2229
2230 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
2231 MockWrite data_writes2[] = {
2232 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
2233 "Host: www.google.com\r\n"
2234 "Connection: keep-alive\r\n"
2235 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
2236 };
2237
2238 // Sever accepts the authorization.
2239 MockRead data_reads2[] = {
2240 MockRead("HTTP/1.0 200 OK\r\n"),
2241 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422242 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:232243 };
2244
[email protected]69b43fe2009-06-15 09:47:372245 StaticMockSocket data1(data_reads1, data_writes1);
2246 StaticMockSocket data2(data_reads2, data_writes2);
[email protected]228ff742009-06-05 01:19:592247 session_deps.socket_factory.AddMockSocket(&data1);
2248 session_deps.socket_factory.AddMockSocket(&data2);
[email protected]f9ee6b52008-11-08 06:46:232249
2250 TestCompletionCallback callback1;
2251
2252 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:422253 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232254
2255 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422256 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232257
[email protected]1c773ea12009-04-28 19:58:422258 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]f9ee6b52008-11-08 06:46:232259 EXPECT_FALSE(response == NULL);
2260
2261 // The password prompt info should have been set in
2262 // response->auth_challenge.
2263 EXPECT_FALSE(response->auth_challenge.get() == NULL);
2264
[email protected]71e4573a2009-05-21 22:03:002265 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]f9ee6b52008-11-08 06:46:232266 EXPECT_EQ(L"MyRealm2", response->auth_challenge->realm);
2267 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
2268
2269 TestCompletionCallback callback2;
2270
2271 rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback2);
[email protected]1c773ea12009-04-28 19:58:422272 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232273
2274 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422275 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232276
2277 response = trans->GetResponseInfo();
2278 EXPECT_FALSE(response == NULL);
2279 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2280 EXPECT_EQ(100, response->headers->GetContentLength());
2281 }
2282
2283 // ------------------------------------------------------------------------
2284
2285 // Transaction 3: Resend a request in MyRealm's protection space --
2286 // succeed with preemptive authorization.
2287 {
[email protected]1c773ea12009-04-28 19:58:422288 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592289 session, &session_deps.socket_factory));
[email protected]f9ee6b52008-11-08 06:46:232290
[email protected]1c773ea12009-04-28 19:58:422291 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:232292 request.method = "GET";
2293 request.url = GURL("http://www.google.com/x/y/z2");
2294 request.load_flags = 0;
2295
2296 MockWrite data_writes1[] = {
2297 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
2298 "Host: www.google.com\r\n"
2299 "Connection: keep-alive\r\n"
2300 // The authorization for MyRealm1 gets sent preemptively
2301 // (since the url is in the same protection space)
2302 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2303 };
2304
2305 // Sever accepts the preemptive authorization
2306 MockRead data_reads1[] = {
2307 MockRead("HTTP/1.0 200 OK\r\n"),
2308 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422309 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:232310 };
2311
[email protected]69b43fe2009-06-15 09:47:372312 StaticMockSocket data1(data_reads1, data_writes1);
[email protected]228ff742009-06-05 01:19:592313 session_deps.socket_factory.AddMockSocket(&data1);
[email protected]f9ee6b52008-11-08 06:46:232314
2315 TestCompletionCallback callback1;
2316
2317 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:422318 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232319
2320 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422321 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232322
[email protected]1c773ea12009-04-28 19:58:422323 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]f9ee6b52008-11-08 06:46:232324 EXPECT_FALSE(response == NULL);
2325
2326 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2327 EXPECT_EQ(100, response->headers->GetContentLength());
2328 }
2329
2330 // ------------------------------------------------------------------------
2331
2332 // Transaction 4: request another URL in MyRealm (however the
2333 // url is not known to belong to the protection space, so no pre-auth).
2334 {
[email protected]1c773ea12009-04-28 19:58:422335 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592336 session, &session_deps.socket_factory));
[email protected]f9ee6b52008-11-08 06:46:232337
[email protected]1c773ea12009-04-28 19:58:422338 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:232339 request.method = "GET";
2340 request.url = GURL("http://www.google.com/x/1");
2341 request.load_flags = 0;
2342
2343 MockWrite data_writes1[] = {
2344 MockWrite("GET /x/1 HTTP/1.1\r\n"
2345 "Host: www.google.com\r\n"
2346 "Connection: keep-alive\r\n\r\n"),
2347 };
2348
2349 MockRead data_reads1[] = {
2350 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2351 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2352 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422353 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:232354 };
2355
2356 // Resend with authorization from MyRealm's cache.
2357 MockWrite data_writes2[] = {
2358 MockWrite("GET /x/1 HTTP/1.1\r\n"
2359 "Host: www.google.com\r\n"
2360 "Connection: keep-alive\r\n"
2361 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2362 };
2363
2364 // Sever accepts the authorization.
2365 MockRead data_reads2[] = {
2366 MockRead("HTTP/1.0 200 OK\r\n"),
2367 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422368 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:232369 };
2370
[email protected]69b43fe2009-06-15 09:47:372371 StaticMockSocket data1(data_reads1, data_writes1);
2372 StaticMockSocket data2(data_reads2, data_writes2);
[email protected]228ff742009-06-05 01:19:592373 session_deps.socket_factory.AddMockSocket(&data1);
2374 session_deps.socket_factory.AddMockSocket(&data2);
[email protected]f9ee6b52008-11-08 06:46:232375
2376 TestCompletionCallback callback1;
2377
2378 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:422379 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232380
2381 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422382 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232383
[email protected]0757e7702009-03-27 04:00:222384 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
2385 TestCompletionCallback callback2;
2386 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
[email protected]1c773ea12009-04-28 19:58:422387 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:222388 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422389 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:222390 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
2391
[email protected]1c773ea12009-04-28 19:58:422392 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]f9ee6b52008-11-08 06:46:232393 EXPECT_FALSE(response == NULL);
2394 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2395 EXPECT_EQ(100, response->headers->GetContentLength());
2396 }
2397
2398 // ------------------------------------------------------------------------
2399
2400 // Transaction 5: request a URL in MyRealm, but the server rejects the
2401 // cached identity. Should invalidate and re-prompt.
2402 {
[email protected]1c773ea12009-04-28 19:58:422403 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592404 session, &session_deps.socket_factory));
[email protected]f9ee6b52008-11-08 06:46:232405
[email protected]1c773ea12009-04-28 19:58:422406 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:232407 request.method = "GET";
2408 request.url = GURL("http://www.google.com/p/q/t");
2409 request.load_flags = 0;
2410
2411 MockWrite data_writes1[] = {
2412 MockWrite("GET /p/q/t HTTP/1.1\r\n"
2413 "Host: www.google.com\r\n"
2414 "Connection: keep-alive\r\n\r\n"),
2415 };
2416
2417 MockRead data_reads1[] = {
2418 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2419 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2420 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422421 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:232422 };
2423
2424 // Resend with authorization from cache for MyRealm.
2425 MockWrite data_writes2[] = {
2426 MockWrite("GET /p/q/t HTTP/1.1\r\n"
2427 "Host: www.google.com\r\n"
2428 "Connection: keep-alive\r\n"
2429 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2430 };
2431
2432 // Sever rejects the authorization.
2433 MockRead data_reads2[] = {
2434 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2435 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2436 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422437 MockRead(false, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:232438 };
2439
2440 // At this point we should prompt for new credentials for MyRealm.
2441 // Restart with username=foo3, password=foo4.
2442 MockWrite data_writes3[] = {
2443 MockWrite("GET /p/q/t HTTP/1.1\r\n"
2444 "Host: www.google.com\r\n"
2445 "Connection: keep-alive\r\n"
2446 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
2447 };
2448
2449 // Sever accepts the authorization.
2450 MockRead data_reads3[] = {
2451 MockRead("HTTP/1.0 200 OK\r\n"),
2452 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422453 MockRead(false, OK),
[email protected]f9ee6b52008-11-08 06:46:232454 };
2455
[email protected]69b43fe2009-06-15 09:47:372456 StaticMockSocket data1(data_reads1, data_writes1);
2457 StaticMockSocket data2(data_reads2, data_writes2);
2458 StaticMockSocket data3(data_reads3, data_writes3);
[email protected]228ff742009-06-05 01:19:592459 session_deps.socket_factory.AddMockSocket(&data1);
2460 session_deps.socket_factory.AddMockSocket(&data2);
2461 session_deps.socket_factory.AddMockSocket(&data3);
[email protected]f9ee6b52008-11-08 06:46:232462
2463 TestCompletionCallback callback1;
2464
2465 int rv = trans->Start(&request, &callback1);
[email protected]1c773ea12009-04-28 19:58:422466 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232467
2468 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422469 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232470
[email protected]0757e7702009-03-27 04:00:222471 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
2472 TestCompletionCallback callback2;
2473 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
[email protected]1c773ea12009-04-28 19:58:422474 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:222475 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422476 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:222477 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
2478
[email protected]1c773ea12009-04-28 19:58:422479 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]f9ee6b52008-11-08 06:46:232480 EXPECT_FALSE(response == NULL);
2481
2482 // The password prompt info should have been set in
2483 // response->auth_challenge.
2484 EXPECT_FALSE(response->auth_challenge.get() == NULL);
2485
[email protected]71e4573a2009-05-21 22:03:002486 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
[email protected]f9ee6b52008-11-08 06:46:232487 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
2488 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
2489
[email protected]0757e7702009-03-27 04:00:222490 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:232491
[email protected]0757e7702009-03-27 04:00:222492 rv = trans->RestartWithAuth(L"foo3", L"bar3", &callback3);
[email protected]1c773ea12009-04-28 19:58:422493 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:232494
[email protected]0757e7702009-03-27 04:00:222495 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422496 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:232497
2498 response = trans->GetResponseInfo();
2499 EXPECT_FALSE(response == NULL);
2500 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2501 EXPECT_EQ(100, response->headers->GetContentLength());
2502 }
2503}
[email protected]89ceba9a2009-03-21 03:46:062504
2505// Test the ResetStateForRestart() private method.
2506TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
2507 // Create a transaction (the dependencies aren't important).
[email protected]228ff742009-06-05 01:19:592508 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402509 scoped_ptr<HttpNetworkTransaction> trans(
2510 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592511 CreateSession(&session_deps),
2512 &session_deps.socket_factory));
[email protected]89ceba9a2009-03-21 03:46:062513
2514 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]ffeb0882009-04-30 21:51:252515 trans->header_buf_->Realloc(10);
[email protected]89ceba9a2009-03-21 03:46:062516 trans->header_buf_capacity_ = 10;
2517 trans->header_buf_len_ = 3;
2518 trans->header_buf_body_offset_ = 11;
2519 trans->header_buf_http_offset_ = 0;
2520 trans->response_body_length_ = 100;
2521 trans->response_body_read_ = 1;
2522 trans->read_buf_ = new IOBuffer(15);
2523 trans->read_buf_len_ = 15;
[email protected]ffeb0882009-04-30 21:51:252524 trans->request_headers_->headers_ = "Authorization: NTLM";
[email protected]89ceba9a2009-03-21 03:46:062525 trans->request_headers_bytes_sent_ = 3;
2526
2527 // Setup state in response_
2528 trans->response_.auth_challenge = new AuthChallengeInfo();
2529 trans->response_.ssl_info.cert_status = -15;
2530 trans->response_.response_time = base::Time::Now();
[email protected]b4404c02009-04-10 16:38:522531 trans->response_.was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:062532
2533 { // Setup state for response_.vary_data
2534 HttpRequestInfo request;
2535 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
2536 std::replace(temp.begin(), temp.end(), '\n', '\0');
2537 scoped_refptr<HttpResponseHeaders> response = new HttpResponseHeaders(temp);
2538 request.extra_headers = "Foo: 1\nbar: 23";
2539 EXPECT_TRUE(trans->response_.vary_data.Init(request, *response));
2540 }
2541
2542 // Cause the above state to be reset.
2543 trans->ResetStateForRestart();
2544
2545 // Verify that the state that needed to be reset, has been reset.
[email protected]ffeb0882009-04-30 21:51:252546 EXPECT_EQ(NULL, trans->header_buf_->headers());
[email protected]89ceba9a2009-03-21 03:46:062547 EXPECT_EQ(0, trans->header_buf_capacity_);
2548 EXPECT_EQ(0, trans->header_buf_len_);
2549 EXPECT_EQ(-1, trans->header_buf_body_offset_);
2550 EXPECT_EQ(-1, trans->header_buf_http_offset_);
2551 EXPECT_EQ(-1, trans->response_body_length_);
2552 EXPECT_EQ(0, trans->response_body_read_);
2553 EXPECT_EQ(NULL, trans->read_buf_.get());
2554 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]ffeb0882009-04-30 21:51:252555 EXPECT_EQ("", trans->request_headers_->headers_);
[email protected]89ceba9a2009-03-21 03:46:062556 EXPECT_EQ(0U, trans->request_headers_bytes_sent_);
2557 EXPECT_EQ(NULL, trans->response_.auth_challenge.get());
2558 EXPECT_EQ(NULL, trans->response_.headers.get());
2559 EXPECT_EQ(false, trans->response_.was_cached);
[email protected]89ceba9a2009-03-21 03:46:062560 EXPECT_EQ(0, trans->response_.ssl_info.cert_status);
2561 EXPECT_FALSE(trans->response_.vary_data.is_valid());
2562}
2563
[email protected]bacff652009-03-31 17:50:332564// Test HTTPS connections to a site with a bad certificate
2565TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]228ff742009-06-05 01:19:592566 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402567 scoped_ptr<HttpTransaction> trans(
2568 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592569 CreateSession(&session_deps),
2570 &session_deps.socket_factory));
[email protected]bacff652009-03-31 17:50:332571
2572 HttpRequestInfo request;
2573 request.method = "GET";
2574 request.url = GURL("https://www.google.com/");
2575 request.load_flags = 0;
2576
2577 MockWrite data_writes[] = {
2578 MockWrite("GET / HTTP/1.1\r\n"
2579 "Host: www.google.com\r\n"
2580 "Connection: keep-alive\r\n\r\n"),
2581 };
2582
2583 MockRead data_reads[] = {
2584 MockRead("HTTP/1.0 200 OK\r\n"),
2585 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2586 MockRead("Content-Length: 100\r\n\r\n"),
2587 MockRead(false, OK),
2588 };
2589
[email protected]69b43fe2009-06-15 09:47:372590 StaticMockSocket ssl_bad_certificate;
2591 StaticMockSocket data(data_reads, data_writes);
[email protected]bacff652009-03-31 17:50:332592 MockSSLSocket ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
2593 MockSSLSocket ssl(true, OK);
2594
[email protected]228ff742009-06-05 01:19:592595 session_deps.socket_factory.AddMockSocket(&ssl_bad_certificate);
2596 session_deps.socket_factory.AddMockSocket(&data);
2597 session_deps.socket_factory.AddMockSSLSocket(&ssl_bad);
2598 session_deps.socket_factory.AddMockSSLSocket(&ssl);
[email protected]bacff652009-03-31 17:50:332599
2600 TestCompletionCallback callback;
2601
2602 int rv = trans->Start(&request, &callback);
2603 EXPECT_EQ(ERR_IO_PENDING, rv);
2604
2605 rv = callback.WaitForResult();
2606 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
2607
2608 rv = trans->RestartIgnoringLastError(&callback);
2609 EXPECT_EQ(ERR_IO_PENDING, rv);
2610
2611 rv = callback.WaitForResult();
2612 EXPECT_EQ(OK, rv);
2613
2614 const HttpResponseInfo* response = trans->GetResponseInfo();
2615
2616 EXPECT_FALSE(response == NULL);
2617 EXPECT_EQ(100, response->headers->GetContentLength());
2618}
2619
2620// Test HTTPS connections to a site with a bad certificate, going through a
2621// proxy
2622TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]228ff742009-06-05 01:19:592623 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
[email protected]bacff652009-03-31 17:50:332624
2625 HttpRequestInfo request;
2626 request.method = "GET";
2627 request.url = GURL("https://www.google.com/");
2628 request.load_flags = 0;
2629
2630 MockWrite proxy_writes[] = {
2631 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452632 "Host: www.google.com\r\n"
2633 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:332634 };
2635
2636 MockRead proxy_reads[] = {
2637 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:422638 MockRead(false, OK)
[email protected]bacff652009-03-31 17:50:332639 };
2640
2641 MockWrite data_writes[] = {
2642 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452643 "Host: www.google.com\r\n"
2644 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:332645 MockWrite("GET / HTTP/1.1\r\n"
2646 "Host: www.google.com\r\n"
2647 "Connection: keep-alive\r\n\r\n"),
2648 };
2649
2650 MockRead data_reads[] = {
2651 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
2652 MockRead("HTTP/1.0 200 OK\r\n"),
2653 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2654 MockRead("Content-Length: 100\r\n\r\n"),
2655 MockRead(false, OK),
2656 };
2657
[email protected]69b43fe2009-06-15 09:47:372658 StaticMockSocket ssl_bad_certificate(proxy_reads, proxy_writes);
2659 StaticMockSocket data(data_reads, data_writes);
[email protected]bacff652009-03-31 17:50:332660 MockSSLSocket ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
2661 MockSSLSocket ssl(true, OK);
2662
[email protected]228ff742009-06-05 01:19:592663 session_deps.socket_factory.AddMockSocket(&ssl_bad_certificate);
2664 session_deps.socket_factory.AddMockSocket(&data);
2665 session_deps.socket_factory.AddMockSSLSocket(&ssl_bad);
2666 session_deps.socket_factory.AddMockSSLSocket(&ssl);
[email protected]bacff652009-03-31 17:50:332667
2668 TestCompletionCallback callback;
2669
2670 for (int i = 0; i < 2; i++) {
[email protected]228ff742009-06-05 01:19:592671 session_deps.socket_factory.ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:332672
[email protected]d207a5f2009-06-04 05:28:402673 scoped_ptr<HttpTransaction> trans(
2674 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592675 CreateSession(&session_deps),
2676 &session_deps.socket_factory));
[email protected]bacff652009-03-31 17:50:332677
2678 int rv = trans->Start(&request, &callback);
2679 EXPECT_EQ(ERR_IO_PENDING, rv);
2680
2681 rv = callback.WaitForResult();
2682 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
2683
2684 rv = trans->RestartIgnoringLastError(&callback);
2685 EXPECT_EQ(ERR_IO_PENDING, rv);
2686
2687 rv = callback.WaitForResult();
2688 EXPECT_EQ(OK, rv);
2689
2690 const HttpResponseInfo* response = trans->GetResponseInfo();
2691
2692 EXPECT_FALSE(response == NULL);
2693 EXPECT_EQ(100, response->headers->GetContentLength());
2694 }
2695}
2696
[email protected]1c773ea12009-04-28 19:58:422697TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]228ff742009-06-05 01:19:592698 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402699 scoped_ptr<HttpTransaction> trans(
2700 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592701 CreateSession(&session_deps),
2702 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422703
2704 HttpRequestInfo request;
2705 request.method = "GET";
2706 request.url = GURL("http://www.google.com/");
2707 request.user_agent = "Chromium Ultra Awesome X Edition";
2708
2709 MockWrite data_writes[] = {
2710 MockWrite("GET / HTTP/1.1\r\n"
2711 "Host: www.google.com\r\n"
2712 "Connection: keep-alive\r\n"
2713 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
2714 };
2715
2716 // Lastly, the server responds with the actual content.
2717 MockRead data_reads[] = {
2718 MockRead("HTTP/1.0 200 OK\r\n"),
2719 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2720 MockRead("Content-Length: 100\r\n\r\n"),
2721 MockRead(false, OK),
2722 };
2723
[email protected]69b43fe2009-06-15 09:47:372724 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592725 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422726
2727 TestCompletionCallback callback;
2728
2729 int rv = trans->Start(&request, &callback);
2730 EXPECT_EQ(ERR_IO_PENDING, rv);
2731
2732 rv = callback.WaitForResult();
2733 EXPECT_EQ(OK, rv);
2734}
2735
2736TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]228ff742009-06-05 01:19:592737 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402738 scoped_ptr<HttpTransaction> trans(
2739 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592740 CreateSession(&session_deps),
2741 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422742
2743 HttpRequestInfo request;
2744 request.method = "GET";
2745 request.url = GURL("http://www.google.com/");
2746 request.load_flags = 0;
2747 request.referrer = GURL("http://the.previous.site.com/");
2748
2749 MockWrite data_writes[] = {
2750 MockWrite("GET / HTTP/1.1\r\n"
2751 "Host: www.google.com\r\n"
2752 "Connection: keep-alive\r\n"
2753 "Referer: http://the.previous.site.com/\r\n\r\n"),
2754 };
2755
2756 // Lastly, the server responds with the actual content.
2757 MockRead data_reads[] = {
2758 MockRead("HTTP/1.0 200 OK\r\n"),
2759 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2760 MockRead("Content-Length: 100\r\n\r\n"),
2761 MockRead(false, OK),
2762 };
2763
[email protected]69b43fe2009-06-15 09:47:372764 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592765 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422766
2767 TestCompletionCallback callback;
2768
2769 int rv = trans->Start(&request, &callback);
2770 EXPECT_EQ(ERR_IO_PENDING, rv);
2771
2772 rv = callback.WaitForResult();
2773 EXPECT_EQ(OK, rv);
2774}
2775
2776TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]228ff742009-06-05 01:19:592777 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402778 scoped_ptr<HttpTransaction> trans(
2779 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592780 CreateSession(&session_deps),
2781 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422782
2783 HttpRequestInfo request;
2784 request.method = "POST";
2785 request.url = GURL("http://www.google.com/");
2786
2787 MockWrite data_writes[] = {
2788 MockWrite("POST / HTTP/1.1\r\n"
2789 "Host: www.google.com\r\n"
2790 "Connection: keep-alive\r\n"
2791 "Content-Length: 0\r\n\r\n"),
2792 };
2793
2794 // Lastly, the server responds with the actual content.
2795 MockRead data_reads[] = {
2796 MockRead("HTTP/1.0 200 OK\r\n"),
2797 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2798 MockRead("Content-Length: 100\r\n\r\n"),
2799 MockRead(false, OK),
2800 };
2801
[email protected]69b43fe2009-06-15 09:47:372802 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592803 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422804
2805 TestCompletionCallback callback;
2806
2807 int rv = trans->Start(&request, &callback);
2808 EXPECT_EQ(ERR_IO_PENDING, rv);
2809
2810 rv = callback.WaitForResult();
2811 EXPECT_EQ(OK, rv);
2812}
2813
2814TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]228ff742009-06-05 01:19:592815 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402816 scoped_ptr<HttpTransaction> trans(
2817 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592818 CreateSession(&session_deps),
2819 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422820
2821 HttpRequestInfo request;
2822 request.method = "PUT";
2823 request.url = GURL("http://www.google.com/");
2824
2825 MockWrite data_writes[] = {
2826 MockWrite("PUT / HTTP/1.1\r\n"
2827 "Host: www.google.com\r\n"
2828 "Connection: keep-alive\r\n"
2829 "Content-Length: 0\r\n\r\n"),
2830 };
2831
2832 // Lastly, the server responds with the actual content.
2833 MockRead data_reads[] = {
2834 MockRead("HTTP/1.0 200 OK\r\n"),
2835 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2836 MockRead("Content-Length: 100\r\n\r\n"),
2837 MockRead(false, OK),
2838 };
2839
[email protected]69b43fe2009-06-15 09:47:372840 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592841 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422842
2843 TestCompletionCallback callback;
2844
2845 int rv = trans->Start(&request, &callback);
2846 EXPECT_EQ(ERR_IO_PENDING, rv);
2847
2848 rv = callback.WaitForResult();
2849 EXPECT_EQ(OK, rv);
2850}
2851
2852TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]228ff742009-06-05 01:19:592853 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402854 scoped_ptr<HttpTransaction> trans(
2855 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592856 CreateSession(&session_deps),
2857 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422858
2859 HttpRequestInfo request;
2860 request.method = "HEAD";
2861 request.url = GURL("http://www.google.com/");
2862
2863 MockWrite data_writes[] = {
2864 MockWrite("HEAD / HTTP/1.1\r\n"
2865 "Host: www.google.com\r\n"
2866 "Connection: keep-alive\r\n"
2867 "Content-Length: 0\r\n\r\n"),
2868 };
2869
2870 // Lastly, the server responds with the actual content.
2871 MockRead data_reads[] = {
2872 MockRead("HTTP/1.0 200 OK\r\n"),
2873 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2874 MockRead("Content-Length: 100\r\n\r\n"),
2875 MockRead(false, OK),
2876 };
2877
[email protected]69b43fe2009-06-15 09:47:372878 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592879 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422880
2881 TestCompletionCallback callback;
2882
2883 int rv = trans->Start(&request, &callback);
2884 EXPECT_EQ(ERR_IO_PENDING, rv);
2885
2886 rv = callback.WaitForResult();
2887 EXPECT_EQ(OK, rv);
2888}
2889
2890TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]228ff742009-06-05 01:19:592891 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402892 scoped_ptr<HttpTransaction> trans(
2893 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592894 CreateSession(&session_deps),
2895 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422896
2897 HttpRequestInfo request;
2898 request.method = "GET";
2899 request.url = GURL("http://www.google.com/");
2900 request.load_flags = LOAD_BYPASS_CACHE;
2901
2902 MockWrite data_writes[] = {
2903 MockWrite("GET / HTTP/1.1\r\n"
2904 "Host: www.google.com\r\n"
2905 "Connection: keep-alive\r\n"
2906 "Pragma: no-cache\r\n"
2907 "Cache-Control: no-cache\r\n\r\n"),
2908 };
2909
2910 // Lastly, the server responds with the actual content.
2911 MockRead data_reads[] = {
2912 MockRead("HTTP/1.0 200 OK\r\n"),
2913 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2914 MockRead("Content-Length: 100\r\n\r\n"),
2915 MockRead(false, OK),
2916 };
2917
[email protected]69b43fe2009-06-15 09:47:372918 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592919 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422920
2921 TestCompletionCallback callback;
2922
2923 int rv = trans->Start(&request, &callback);
2924 EXPECT_EQ(ERR_IO_PENDING, rv);
2925
2926 rv = callback.WaitForResult();
2927 EXPECT_EQ(OK, rv);
2928}
2929
2930TEST_F(HttpNetworkTransactionTest,
2931 BuildRequest_CacheControlValidateCache) {
[email protected]228ff742009-06-05 01:19:592932 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402933 scoped_ptr<HttpTransaction> trans(
2934 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592935 CreateSession(&session_deps),
2936 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422937
2938 HttpRequestInfo request;
2939 request.method = "GET";
2940 request.url = GURL("http://www.google.com/");
2941 request.load_flags = LOAD_VALIDATE_CACHE;
2942
2943 MockWrite data_writes[] = {
2944 MockWrite("GET / HTTP/1.1\r\n"
2945 "Host: www.google.com\r\n"
2946 "Connection: keep-alive\r\n"
2947 "Cache-Control: max-age=0\r\n\r\n"),
2948 };
2949
2950 // Lastly, the server responds with the actual content.
2951 MockRead data_reads[] = {
2952 MockRead("HTTP/1.0 200 OK\r\n"),
2953 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2954 MockRead("Content-Length: 100\r\n\r\n"),
2955 MockRead(false, OK),
2956 };
2957
[email protected]69b43fe2009-06-15 09:47:372958 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592959 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422960
2961 TestCompletionCallback callback;
2962
2963 int rv = trans->Start(&request, &callback);
2964 EXPECT_EQ(ERR_IO_PENDING, rv);
2965
2966 rv = callback.WaitForResult();
2967 EXPECT_EQ(OK, rv);
2968}
2969
2970TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]228ff742009-06-05 01:19:592971 SessionDependencies session_deps;
[email protected]d207a5f2009-06-04 05:28:402972 scoped_ptr<HttpTransaction> trans(
2973 new HttpNetworkTransaction(
[email protected]228ff742009-06-05 01:19:592974 CreateSession(&session_deps),
2975 &session_deps.socket_factory));
[email protected]1c773ea12009-04-28 19:58:422976
2977 HttpRequestInfo request;
2978 request.method = "GET";
2979 request.url = GURL("http://www.google.com/");
2980 request.extra_headers = "FooHeader: Bar\r\n";
2981
2982 MockWrite data_writes[] = {
2983 MockWrite("GET / HTTP/1.1\r\n"
2984 "Host: www.google.com\r\n"
2985 "Connection: keep-alive\r\n"
2986 "FooHeader: Bar\r\n\r\n"),
2987 };
2988
2989 // Lastly, the server responds with the actual content.
2990 MockRead data_reads[] = {
2991 MockRead("HTTP/1.0 200 OK\r\n"),
2992 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2993 MockRead("Content-Length: 100\r\n\r\n"),
2994 MockRead(false, OK),
2995 };
2996
[email protected]69b43fe2009-06-15 09:47:372997 StaticMockSocket data(data_reads, data_writes);
[email protected]228ff742009-06-05 01:19:592998 session_deps.socket_factory.AddMockSocket(&data);
[email protected]1c773ea12009-04-28 19:58:422999
3000 TestCompletionCallback callback;
3001
3002 int rv = trans->Start(&request, &callback);
3003 EXPECT_EQ(ERR_IO_PENDING, rv);
3004
3005 rv = callback.WaitForResult();
3006 EXPECT_EQ(OK, rv);
3007}
3008
[email protected]3cd17242009-06-23 02:59:023009TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
3010 SessionDependencies session_deps;
3011 session_deps.proxy_service.reset(CreateFixedProxyService(
3012 "socks4://myproxy:1080"));
3013
3014 scoped_ptr<HttpTransaction> trans(
3015 new HttpNetworkTransaction(
3016 CreateSession(&session_deps),
3017 &session_deps.socket_factory));
3018
3019 HttpRequestInfo request;
3020 request.method = "GET";
3021 request.url = GURL("http://www.google.com/");
3022 request.load_flags = 0;
3023
3024 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
3025 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
3026
3027 MockWrite data_writes[] = {
3028 MockWrite(true, write_buffer, 9),
3029 MockWrite("GET / HTTP/1.1\r\n"
3030 "Host: www.google.com\r\n"
3031 "Connection: keep-alive\r\n\r\n")
3032 };
3033
3034 MockRead data_reads[] = {
3035 MockWrite(true, read_buffer, 8),
3036 MockRead("HTTP/1.0 200 OK\r\n"),
3037 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
3038 MockRead("Payload"),
3039 MockRead(false, OK)
3040 };
3041
3042 StaticMockSocket data(data_reads, data_writes);
3043 session_deps.socket_factory.AddMockSocket(&data);
3044
3045 TestCompletionCallback callback;
3046
3047 int rv = trans->Start(&request, &callback);
3048 EXPECT_EQ(ERR_IO_PENDING, rv);
3049
3050 rv = callback.WaitForResult();
3051 EXPECT_EQ(OK, rv);
3052
3053 const HttpResponseInfo* response = trans->GetResponseInfo();
3054 EXPECT_FALSE(response == NULL);
3055
3056 std::string response_text;
3057 rv = ReadTransaction(trans.get(), &response_text);
3058 EXPECT_EQ(OK, rv);
3059 EXPECT_EQ("Payload", response_text);
3060}
3061
3062TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
3063 SessionDependencies session_deps;
3064 session_deps.proxy_service.reset(CreateFixedProxyService(
3065 "socks4://myproxy:1080"));
3066
3067 scoped_ptr<HttpTransaction> trans(
3068 new HttpNetworkTransaction(
3069 CreateSession(&session_deps),
3070 &session_deps.socket_factory));
3071
3072 HttpRequestInfo request;
3073 request.method = "GET";
3074 request.url = GURL("https://www.google.com/");
3075 request.load_flags = 0;
3076
3077 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
3078 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
3079
3080 MockWrite data_writes[] = {
3081 MockWrite(true, reinterpret_cast<char*>(write_buffer), 9),
3082 MockWrite("GET / HTTP/1.1\r\n"
3083 "Host: www.google.com\r\n"
3084 "Connection: keep-alive\r\n\r\n")
3085 };
3086
3087 MockRead data_reads[] = {
3088 MockWrite(true, reinterpret_cast<char*>(read_buffer), 8),
3089 MockRead("HTTP/1.0 200 OK\r\n"),
3090 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
3091 MockRead("Payload"),
3092 MockRead(false, OK)
3093 };
3094
3095 StaticMockSocket data(data_reads, data_writes);
3096 session_deps.socket_factory.AddMockSocket(&data);
3097
3098 MockSSLSocket ssl(true, OK);
3099 session_deps.socket_factory.AddMockSSLSocket(&ssl);
3100
3101 TestCompletionCallback callback;
3102
3103 int rv = trans->Start(&request, &callback);
3104 EXPECT_EQ(ERR_IO_PENDING, rv);
3105
3106 rv = callback.WaitForResult();
3107 EXPECT_EQ(OK, rv);
3108
3109 const HttpResponseInfo* response = trans->GetResponseInfo();
3110 EXPECT_FALSE(response == NULL);
3111
3112 std::string response_text;
3113 rv = ReadTransaction(trans.get(), &response_text);
3114 EXPECT_EQ(OK, rv);
3115 EXPECT_EQ("Payload", response_text);
3116}
3117
[email protected]9172a982009-06-06 00:30:253118TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
3119 scoped_refptr<RuleBasedHostMapper> host_mapper(new RuleBasedHostMapper());
3120 ScopedHostMapper scoped_host_mapper(host_mapper.get());
3121 host_mapper->AddSimulatedFailure("*");
3122
[email protected]5c6a17e2009-06-10 00:54:543123 SessionDependencies session_deps(
3124 CreateFixedProxyService("myproxy:70;foobar:80"));
[email protected]9172a982009-06-06 00:30:253125 scoped_ptr<HttpTransaction> trans(
3126 new HttpNetworkTransaction(
3127 CreateSession(&session_deps),
3128 &session_deps.socket_factory));
3129
3130 HttpRequestInfo request;
3131 request.method = "GET";
3132 request.url = GURL("http://www.google.com/");
3133
3134 TestCompletionCallback callback;
3135
3136 int rv = trans->Start(&request, &callback);
3137 EXPECT_EQ(ERR_IO_PENDING, rv);
3138
[email protected]9172a982009-06-06 00:30:253139 rv = callback.WaitForResult();
3140 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
3141}
3142
[email protected]f3e6c1e2009-06-15 20:52:123143// Host resolution observer used by
3144// HttpNetworkTransactionTest.ResolveMadeWithReferrer to check that host
3145// resovle requests are issued with a referrer of |expected_referrer|.
3146class ResolutionReferrerObserver : public HostResolver::Observer {
3147 public:
3148 explicit ResolutionReferrerObserver(const GURL& expected_referrer)
3149 : expected_referrer_(expected_referrer),
3150 called_start_with_referrer_(false),
3151 called_finish_with_referrer_(false) {
3152 }
3153
3154 virtual void OnStartResolution(int id,
3155 const HostResolver::RequestInfo& info) {
3156 if (info.referrer() == expected_referrer_)
3157 called_start_with_referrer_ = true;
3158 }
3159
3160 virtual void OnFinishResolutionWithStatus(
3161 int id, bool was_resolved, const HostResolver::RequestInfo& info ) {
3162 if (info.referrer() == expected_referrer_)
3163 called_finish_with_referrer_ = true;
3164 }
3165
[email protected]eb255d32009-06-17 02:11:033166 virtual void OnCancelResolution(int id,
3167 const HostResolver::RequestInfo& info ) {
3168 FAIL() << "Should not be cancelling any requests!";
3169 }
3170
[email protected]f3e6c1e2009-06-15 20:52:123171 bool did_complete_with_expected_referrer() const {
3172 return called_start_with_referrer_ && called_finish_with_referrer_;
3173 }
3174
3175 private:
3176 GURL expected_referrer_;
3177 bool called_start_with_referrer_;
3178 bool called_finish_with_referrer_;
3179
3180 DISALLOW_COPY_AND_ASSIGN(ResolutionReferrerObserver);
3181};
3182
3183// Make sure that when HostResolver::Resolve() is invoked, it passes through
3184// the "referrer". This is depended on by the DNS prefetch observer.
3185TEST_F(HttpNetworkTransactionTest, ResolveMadeWithReferrer) {
3186 GURL referrer = GURL("http://expected-referrer/");
3187 EXPECT_TRUE(referrer.is_valid());
3188 ResolutionReferrerObserver resolution_observer(referrer);
3189
3190 SessionDependencies session_deps;
3191 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
3192 CreateSession(&session_deps), &session_deps.socket_factory));
3193
3194 // Attach an observer to watch the host resolutions being made.
3195 session_deps.host_resolver.AddObserver(&resolution_observer);
3196
3197 // Connect up a mock socket which will fail when reading.
3198 MockRead data_reads[] = {
3199 MockRead(false, ERR_FAILED),
3200 };
3201 StaticMockSocket data(data_reads, NULL);
3202 session_deps.socket_factory.AddMockSocket(&data);
3203
3204 // Issue a request, containing an HTTP referrer.
3205 HttpRequestInfo request;
3206 request.method = "GET";
3207 request.referrer = referrer;
3208 request.url = GURL("http://www.google.com/");
3209
3210 // Run the request until it fails reading from the socket.
3211 TestCompletionCallback callback;
3212 int rv = trans->Start(&request, &callback);
3213 EXPECT_EQ(ERR_IO_PENDING, rv);
3214 rv = callback.WaitForResult();
3215 EXPECT_EQ(ERR_FAILED, rv);
3216
3217 // Check that the host resolution observer saw |referrer|.
3218 EXPECT_TRUE(resolution_observer.did_complete_with_expected_referrer());
3219}
3220
[email protected]3b9cca42009-06-16 01:08:283221// Make sure that when the load flags contain LOAD_BYPASS_CACHE, the resolver's
3222// host cache is bypassed.
3223TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
3224 SessionDependencies session_deps;
3225 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
3226 CreateSession(&session_deps), &session_deps.socket_factory));
3227
3228 // Warm up the host cache so it has an entry for "www.google.com" (by doing
3229 // a synchronous lookup.)
3230 AddressList addrlist;
3231 int rv = session_deps.host_resolver.Resolve(
3232 HostResolver::RequestInfo("www.google.com", 80), &addrlist, NULL, NULL);
3233 EXPECT_EQ(OK, rv);
3234
3235 // Verify that it was added to host cache, by doing a subsequent async lookup
3236 // and confirming it completes synchronously.
3237 TestCompletionCallback resolve_callback;
3238 rv = session_deps.host_resolver.Resolve(
3239 HostResolver::RequestInfo("www.google.com", 80), &addrlist,
3240 &resolve_callback, NULL);
3241 EXPECT_EQ(OK, rv);
3242
3243 // Inject a failure the next time that "www.google.com" is resolved. This way
3244 // we can tell if the next lookup hit the cache, or the "network".
3245 // (cache --> success, "network" --> failure).
3246 scoped_refptr<RuleBasedHostMapper> host_mapper(new RuleBasedHostMapper());
3247 ScopedHostMapper scoped_host_mapper(host_mapper.get());
3248 host_mapper->AddSimulatedFailure("www.google.com");
3249
3250 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
3251 // first read -- this won't be reached as the host resolution will fail first.
3252 MockRead data_reads[] = { MockRead(false, ERR_UNEXPECTED) };
3253 StaticMockSocket data(data_reads, NULL);
3254 session_deps.socket_factory.AddMockSocket(&data);
3255
3256 // Issue a request, asking to bypass the cache(s).
3257 HttpRequestInfo request;
3258 request.method = "GET";
3259 request.load_flags = LOAD_BYPASS_CACHE;
3260 request.url = GURL("http://www.google.com/");
3261
3262 // Run the request.
3263 TestCompletionCallback callback;
3264 rv = trans->Start(&request, &callback);
3265 ASSERT_EQ(ERR_IO_PENDING, rv);
3266 rv = callback.WaitForResult();
3267
3268 // If we bypassed the cache, we would have gotten a failure while resolving
3269 // "www.google.com".
3270 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
3271}
3272
[email protected]89ceba9a2009-03-21 03:46:063273} // namespace net