Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: net/http/http_network_transaction_unittest.cc

Issue 197283012: Retry requests on reused sockets that receive ERR_EMPTY_RESPONSE. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Indentation Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_network_transaction.cc ('k') | net/http/http_pipelined_connection_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include <math.h> // ceil 7 #include <math.h> // ceil
8 #include <stdarg.h> 8 #include <stdarg.h>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/file_util.h" 14 #include "base/file_util.h"
15 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/json/json_writer.h" 16 #include "base/json/json_writer.h"
17 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/weak_ptr.h" 18 #include "base/memory/weak_ptr.h"
19 #include "base/run_loop.h"
19 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
21 #include "base/test/test_file_util.h" 22 #include "base/test/test_file_util.h"
22 #include "net/base/auth.h" 23 #include "net/base/auth.h"
23 #include "net/base/capturing_net_log.h" 24 #include "net/base/capturing_net_log.h"
24 #include "net/base/completion_callback.h" 25 #include "net/base/completion_callback.h"
25 #include "net/base/load_timing_info.h" 26 #include "net/base/load_timing_info.h"
26 #include "net/base/load_timing_info_test_util.h" 27 #include "net/base/load_timing_info_test_util.h"
27 #include "net/base/net_log.h" 28 #include "net/base/net_log.h"
28 #include "net/base/net_log_unittest.h" 29 #include "net/base/net_log_unittest.h"
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 "\r\n\r\n"; 277 "\r\n\r\n";
277 } 278 }
278 279
279 // Either |write_failure| specifies a write failure or |read_failure| 280 // Either |write_failure| specifies a write failure or |read_failure|
280 // specifies a read failure when using a reused socket. In either case, the 281 // specifies a read failure when using a reused socket. In either case, the
281 // failure should cause the network transaction to resend the request, and the 282 // failure should cause the network transaction to resend the request, and the
282 // other argument should be NULL. 283 // other argument should be NULL.
283 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure, 284 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
284 const MockRead* read_failure); 285 const MockRead* read_failure);
285 286
287 // Either |write_failure| specifies a write failure or |read_failure|
288 // specifies a read failure when using a reused socket. In either case, the
289 // failure should cause the network transaction to resend the request, and the
290 // other argument should be NULL.
291 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
292 const MockRead* read_failure);
293
286 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[], 294 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
287 size_t data_count) { 295 size_t data_count) {
288 SimpleGetHelperResult out; 296 SimpleGetHelperResult out;
289 297
290 HttpRequestInfo request; 298 HttpRequestInfo request;
291 request.method = "GET"; 299 request.method = "GET";
292 request.url = GURL("http://www.google.com/"); 300 request.url = GURL("http://www.google.com/");
293 request.load_flags = 0; 301 request.load_flags = 0;
294 302
295 CapturingBoundNetLog log; 303 CapturingBoundNetLog log;
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 }; 1240 };
1233 1241
1234 // Read results for the first request. 1242 // Read results for the first request.
1235 MockRead data1_reads[] = { 1243 MockRead data1_reads[] = {
1236 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), 1244 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1237 MockRead("hello"), 1245 MockRead("hello"),
1238 MockRead(ASYNC, OK), 1246 MockRead(ASYNC, OK),
1239 }; 1247 };
1240 1248
1241 if (write_failure) { 1249 if (write_failure) {
1242 ASSERT_TRUE(!read_failure); 1250 ASSERT_FALSE(read_failure);
1243 data1_writes[1] = *write_failure; 1251 data1_writes[1] = *write_failure;
1244 } else { 1252 } else {
1245 ASSERT_TRUE(read_failure); 1253 ASSERT_TRUE(read_failure);
1246 data1_reads[2] = *read_failure; 1254 data1_reads[2] = *read_failure;
1247 } 1255 }
1248 1256
1249 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), 1257 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1250 data1_writes, arraysize(data1_writes)); 1258 data1_writes, arraysize(data1_writes));
1251 session_deps_.socket_factory->AddSocketDataProvider(&data1); 1259 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1252 1260
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 EXPECT_TRUE(response->headers.get() != NULL); 1299 EXPECT_TRUE(response->headers.get() != NULL);
1292 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 1300 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1293 1301
1294 std::string response_data; 1302 std::string response_data;
1295 rv = ReadTransaction(trans.get(), &response_data); 1303 rv = ReadTransaction(trans.get(), &response_data);
1296 EXPECT_EQ(OK, rv); 1304 EXPECT_EQ(OK, rv);
1297 EXPECT_EQ(kExpectedResponseData[i], response_data); 1305 EXPECT_EQ(kExpectedResponseData[i], response_data);
1298 } 1306 }
1299 } 1307 }
1300 1308
1309 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1310 const MockWrite* write_failure,
1311 const MockRead* read_failure) {
1312 HttpRequestInfo request;
1313 request.method = "GET";
1314 request.url = GURL("http://www.foo.com/");
1315 request.load_flags = 0;
1316
1317 CapturingNetLog net_log;
1318 session_deps_.net_log = &net_log;
1319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1320
1321 // Written data for successfully sending a request.
1322 MockWrite data1_writes[] = {
1323 MockWrite("GET / HTTP/1.1\r\n"
1324 "Host: www.foo.com\r\n"
1325 "Connection: keep-alive\r\n\r\n"),
1326 };
1327
1328 // Read results for the first request.
1329 MockRead data1_reads[] = {
1330 MockRead(ASYNC, OK),
1331 };
1332
1333 if (write_failure) {
1334 ASSERT_FALSE(read_failure);
1335 data1_writes[0] = *write_failure;
1336 } else {
1337 ASSERT_TRUE(read_failure);
1338 data1_reads[0] = *read_failure;
1339 }
1340
1341 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1342 data1_writes, arraysize(data1_writes));
1343 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1344
1345 MockRead data2_reads[] = {
1346 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1347 MockRead("hello"),
1348 MockRead(ASYNC, OK),
1349 };
1350 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1351 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1352
1353 // Preconnect a socket.
1354 net::SSLConfig ssl_config;
1355 session->ssl_config_service()->GetSSLConfig(&ssl_config);
1356 if (session->http_stream_factory()->has_next_protos())
1357 ssl_config.next_protos = session->http_stream_factory()->next_protos();
1358 session->http_stream_factory()->PreconnectStreams(
1359 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1360 // Wait for the preconnect to complete.
1361 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1362 base::RunLoop().RunUntilIdle();
1363 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
1364
1365 // Make the request.
1366 TestCompletionCallback callback;
1367
1368 scoped_ptr<HttpTransaction> trans(
1369 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1370
1371 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1372 EXPECT_EQ(ERR_IO_PENDING, rv);
1373
1374 rv = callback.WaitForResult();
1375 EXPECT_EQ(OK, rv);
1376
1377 LoadTimingInfo load_timing_info;
1378 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1379 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1380
1381 const HttpResponseInfo* response = trans->GetResponseInfo();
1382 ASSERT_TRUE(response != NULL);
1383
1384 EXPECT_TRUE(response->headers.get() != NULL);
1385 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1386
1387 std::string response_data;
1388 rv = ReadTransaction(trans.get(), &response_data);
1389 EXPECT_EQ(OK, rv);
1390 EXPECT_EQ("hello", response_data);
1391 }
1392
1301 TEST_P(HttpNetworkTransactionTest, 1393 TEST_P(HttpNetworkTransactionTest,
1302 KeepAliveConnectionNotConnectedOnWrite) { 1394 KeepAliveConnectionNotConnectedOnWrite) {
1303 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED); 1395 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1304 KeepAliveConnectionResendRequestTest(&write_failure, NULL); 1396 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1305 } 1397 }
1306 1398
1307 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) { 1399 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
1308 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET); 1400 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1309 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1401 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1310 } 1402 }
1311 1403
1312 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { 1404 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
1313 MockRead read_failure(SYNCHRONOUS, OK); // EOF 1405 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1314 KeepAliveConnectionResendRequestTest(NULL, &read_failure); 1406 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1315 } 1407 }
1316 1408
1409 TEST_P(HttpNetworkTransactionTest,
1410 PreconnectErrorNotConnectedOnWrite) {
1411 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1412 PreconnectErrorResendRequestTest(&write_failure, NULL);
1413 }
1414
1415 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1416 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1417 PreconnectErrorResendRequestTest(NULL, &read_failure);
1418 }
1419
1420 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1421 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1422 PreconnectErrorResendRequestTest(NULL, &read_failure);
1423 }
1424
1317 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { 1425 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
1318 HttpRequestInfo request; 1426 HttpRequestInfo request;
1319 request.method = "GET"; 1427 request.method = "GET";
1320 request.url = GURL("http://www.google.com/"); 1428 request.url = GURL("http://www.google.com/");
1321 request.load_flags = 0; 1429 request.load_flags = 0;
1322 1430
1323 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); 1431 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1324 scoped_ptr<HttpTransaction> trans( 1432 scoped_ptr<HttpTransaction> trans(
1325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); 1433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1326 1434
(...skipping 11108 matching lines...) Expand 10 before | Expand all | Expand 10 after
12435 // established, to let the HTTP request start. 12543 // established, to let the HTTP request start.
12436 ASSERT_EQ(OK, http_callback.WaitForResult()); 12544 ASSERT_EQ(OK, http_callback.WaitForResult());
12437 std::string response_data; 12545 std::string response_data;
12438 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data)); 12546 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12439 EXPECT_EQ("falafel", response_data); 12547 EXPECT_EQ("falafel", response_data);
12440 12548
12441 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session)); 12549 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12442 } 12550 }
12443 12551
12444 } // namespace net 12552 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_network_transaction.cc ('k') | net/http/http_pipelined_connection_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698