| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // 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 | 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 "base/compiler_specific.h" | 5 #include "base/compiler_specific.h" |
| 6 #include "base/platform_test.h" | 6 #include "base/platform_test.h" |
| 7 #include "net/base/client_socket_factory.h" | 7 #include "net/base/client_socket_factory.h" |
| 8 #include "net/base/test_completion_callback.h" | 8 #include "net/base/test_completion_callback.h" |
| 9 #include "net/base/upload_data.h" | 9 #include "net/base/upload_data.h" |
| 10 #include "net/http/http_network_session.h" | 10 #include "net/http/http_network_session.h" |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 return new net::HttpNetworkSession(new NullProxyResolver()); | 162 return new net::HttpNetworkSession(new NullProxyResolver()); |
| 163 } | 163 } |
| 164 | 164 |
| 165 class HttpNetworkTransactionTest : public PlatformTest { | 165 class HttpNetworkTransactionTest : public PlatformTest { |
| 166 public: | 166 public: |
| 167 virtual void SetUp() { | 167 virtual void SetUp() { |
| 168 PlatformTest::SetUp(); | 168 PlatformTest::SetUp(); |
| 169 mock_sockets[0] = NULL; | 169 mock_sockets[0] = NULL; |
| 170 mock_sockets_index = 0; | 170 mock_sockets_index = 0; |
| 171 } | 171 } |
| 172 |
| 173 protected: |
| 174 void KeepAliveConnectionResendRequestTest(const MockRead& read_failure); |
| 172 }; | 175 }; |
| 173 | 176 |
| 174 struct SimpleGetHelperResult { | 177 struct SimpleGetHelperResult { |
| 175 std::string status_line; | 178 std::string status_line; |
| 176 std::string response_data; | 179 std::string response_data; |
| 177 }; | 180 }; |
| 178 | 181 |
| 179 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) { | 182 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) { |
| 180 SimpleGetHelperResult out; | 183 SimpleGetHelperResult out; |
| 181 | 184 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 EXPECT_EQ("DATA", out.response_data); | 274 EXPECT_EQ("DATA", out.response_data); |
| 272 } | 275 } |
| 273 | 276 |
| 274 // Beyond 4 bytes of slop and it should fail to find a status line. | 277 // Beyond 4 bytes of slop and it should fail to find a status line. |
| 275 TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { | 278 TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { |
| 276 MockRead data_reads[] = { | 279 MockRead data_reads[] = { |
| 277 { true, 0, "xxxxxHTTP/1.1 404 Not Found\nServer: blah", -1 }, | 280 { true, 0, "xxxxxHTTP/1.1 404 Not Found\nServer: blah", -1 }, |
| 278 { false, net::OK, NULL, 0 }, | 281 { false, net::OK, NULL, 0 }, |
| 279 }; | 282 }; |
| 280 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 283 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 281 EXPECT_TRUE(out.status_line == "HTTP/0.9 200 OK"); | 284 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); |
| 282 EXPECT_TRUE(out.response_data == "xxxxxHTTP/1.1 404 Not Found\nServer: blah"); | 285 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); |
| 283 } | 286 } |
| 284 | 287 |
| 285 // Same as StatusLineJunk4Bytes, except the read chunks are smaller. | 288 // Same as StatusLineJunk4Bytes, except the read chunks are smaller. |
| 286 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { | 289 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { |
| 287 MockRead data_reads[] = { | 290 MockRead data_reads[] = { |
| 288 { true, 0, "\n", -1 }, | 291 { true, 0, "\n", -1 }, |
| 289 { true, 0, "\n", -1 }, | 292 { true, 0, "\n", -1 }, |
| 290 { true, 0, "Q", -1 }, | 293 { true, 0, "Q", -1 }, |
| 291 { true, 0, "J", -1 }, | 294 { true, 0, "J", -1 }, |
| 292 { true, 0, "HTTP/1.0 404 Not Found\nServer: blah\n\nDATA", -1 }, | 295 { true, 0, "HTTP/1.0 404 Not Found\nServer: blah\n\nDATA", -1 }, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 int rv = trans->Start(&request, &callback); | 360 int rv = trans->Start(&request, &callback); |
| 358 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 361 EXPECT_EQ(net::ERR_IO_PENDING, rv); |
| 359 | 362 |
| 360 rv = callback.WaitForResult(); | 363 rv = callback.WaitForResult(); |
| 361 EXPECT_EQ(net::OK, rv); | 364 EXPECT_EQ(net::OK, rv); |
| 362 | 365 |
| 363 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 366 const net::HttpResponseInfo* response = trans->GetResponseInfo(); |
| 364 EXPECT_TRUE(response != NULL); | 367 EXPECT_TRUE(response != NULL); |
| 365 | 368 |
| 366 EXPECT_TRUE(response->headers != NULL); | 369 EXPECT_TRUE(response->headers != NULL); |
| 367 EXPECT_TRUE(response->headers->GetStatusLine() == "HTTP/1.1 200 OK"); | 370 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 368 | 371 |
| 369 std::string response_data; | 372 std::string response_data; |
| 370 rv = ReadTransaction(trans, &response_data); | 373 rv = ReadTransaction(trans, &response_data); |
| 371 EXPECT_EQ(net::OK, rv); | 374 EXPECT_EQ(net::OK, rv); |
| 372 EXPECT_TRUE(response_data == kExpectedResponseData[i]); | 375 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 373 | 376 |
| 374 trans->Destroy(); | 377 trans->Destroy(); |
| 375 | 378 |
| 376 // Empty the current queue. | 379 // Empty the current queue. |
| 377 MessageLoop::current()->RunAllPending(); | 380 MessageLoop::current()->RunAllPending(); |
| 378 } | 381 } |
| 379 } | 382 } |
| 380 | 383 |
| 381 TEST_F(HttpNetworkTransactionTest, Ignores100) { | 384 TEST_F(HttpNetworkTransactionTest, Ignores100) { |
| 382 net::HttpTransaction* trans = new net::HttpNetworkTransaction( | 385 net::HttpTransaction* trans = new net::HttpNetworkTransaction( |
| (...skipping 24 matching lines...) Expand all Loading... |
| 407 int rv = trans->Start(&request, &callback); | 410 int rv = trans->Start(&request, &callback); |
| 408 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 411 EXPECT_EQ(net::ERR_IO_PENDING, rv); |
| 409 | 412 |
| 410 rv = callback.WaitForResult(); | 413 rv = callback.WaitForResult(); |
| 411 EXPECT_EQ(net::OK, rv); | 414 EXPECT_EQ(net::OK, rv); |
| 412 | 415 |
| 413 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 416 const net::HttpResponseInfo* response = trans->GetResponseInfo(); |
| 414 EXPECT_TRUE(response != NULL); | 417 EXPECT_TRUE(response != NULL); |
| 415 | 418 |
| 416 EXPECT_TRUE(response->headers != NULL); | 419 EXPECT_TRUE(response->headers != NULL); |
| 417 EXPECT_TRUE(response->headers->GetStatusLine() == "HTTP/1.0 200 OK"); | 420 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); |
| 418 | 421 |
| 419 std::string response_data; | 422 std::string response_data; |
| 420 rv = ReadTransaction(trans, &response_data); | 423 rv = ReadTransaction(trans, &response_data); |
| 421 EXPECT_EQ(net::OK, rv); | 424 EXPECT_EQ(net::OK, rv); |
| 422 EXPECT_TRUE(response_data == "hello world"); | 425 EXPECT_EQ("hello world", response_data); |
| 423 | 426 |
| 424 trans->Destroy(); | 427 trans->Destroy(); |
| 425 | 428 |
| 426 // Empty the current queue. | 429 // Empty the current queue. |
| 427 MessageLoop::current()->RunAllPending(); | 430 MessageLoop::current()->RunAllPending(); |
| 428 } | 431 } |
| 429 | 432 |
| 430 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) { | 433 // read_failure specifies a read failure that should cause the network |
| 434 // transaction to resend the request. |
| 435 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest( |
| 436 const MockRead& read_failure) { |
| 431 scoped_refptr<net::HttpNetworkSession> session = CreateSession(); | 437 scoped_refptr<net::HttpNetworkSession> session = CreateSession(); |
| 432 | 438 |
| 433 net::HttpRequestInfo request; | 439 net::HttpRequestInfo request; |
| 434 request.method = "GET"; | 440 request.method = "GET"; |
| 435 request.url = GURL("http://www.foo.com/"); | 441 request.url = GURL("http://www.foo.com/"); |
| 436 request.load_flags = 0; | 442 request.load_flags = 0; |
| 437 | 443 |
| 438 MockRead data1_reads[] = { | 444 MockRead data1_reads[] = { |
| 439 { true, 0, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n", -1 }, | 445 { true, 0, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n", -1 }, |
| 440 { true, 0, "hello", -1 }, | 446 { true, 0, "hello", -1 }, |
| 441 { true, net::ERR_CONNECTION_RESET, NULL, 0 }, | 447 read_failure, // Now, we reuse the connection and fail the first read. |
| 442 }; | 448 }; |
| 443 MockSocket data1; | 449 MockSocket data1; |
| 444 data1.connect.async = true; | 450 data1.connect.async = true; |
| 445 data1.connect.result = net::OK; | 451 data1.connect.result = net::OK; |
| 446 data1.reads = data1_reads; | 452 data1.reads = data1_reads; |
| 447 mock_sockets[0] = &data1; | 453 mock_sockets[0] = &data1; |
| 448 | 454 |
| 449 MockRead data2_reads[] = { | 455 MockRead data2_reads[] = { |
| 450 { true, 0, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n", -1 }, | 456 { true, 0, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n", -1 }, |
| 451 { true, 0, "world", -1 }, | 457 { true, 0, "world", -1 }, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 470 int rv = trans->Start(&request, &callback); | 476 int rv = trans->Start(&request, &callback); |
| 471 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 477 EXPECT_EQ(net::ERR_IO_PENDING, rv); |
| 472 | 478 |
| 473 rv = callback.WaitForResult(); | 479 rv = callback.WaitForResult(); |
| 474 EXPECT_EQ(net::OK, rv); | 480 EXPECT_EQ(net::OK, rv); |
| 475 | 481 |
| 476 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 482 const net::HttpResponseInfo* response = trans->GetResponseInfo(); |
| 477 EXPECT_TRUE(response != NULL); | 483 EXPECT_TRUE(response != NULL); |
| 478 | 484 |
| 479 EXPECT_TRUE(response->headers != NULL); | 485 EXPECT_TRUE(response->headers != NULL); |
| 480 EXPECT_TRUE(response->headers->GetStatusLine() == "HTTP/1.1 200 OK"); | 486 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 481 | 487 |
| 482 std::string response_data; | 488 std::string response_data; |
| 483 rv = ReadTransaction(trans, &response_data); | 489 rv = ReadTransaction(trans, &response_data); |
| 484 EXPECT_EQ(net::OK, rv); | 490 EXPECT_EQ(net::OK, rv); |
| 485 EXPECT_TRUE(response_data == kExpectedResponseData[i]); | 491 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 486 | 492 |
| 487 trans->Destroy(); | 493 trans->Destroy(); |
| 488 | 494 |
| 489 // Empty the current queue. | 495 // Empty the current queue. |
| 490 MessageLoop::current()->RunAllPending(); | 496 MessageLoop::current()->RunAllPending(); |
| 491 } | 497 } |
| 492 } | 498 } |
| 499 |
| 500 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) { |
| 501 MockRead read_failure = { true, net::ERR_CONNECTION_RESET, NULL, 0 }; |
| 502 KeepAliveConnectionResendRequestTest(read_failure); |
| 503 } |
| 504 |
| 505 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { |
| 506 MockRead read_failure = { false, net::OK, NULL, 0 }; // EOF |
| 507 KeepAliveConnectionResendRequestTest(read_failure); |
| 508 } |
| 509 |
| 510 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { |
| 511 net::HttpTransaction* trans = new net::HttpNetworkTransaction( |
| 512 CreateSession(), &mock_socket_factory); |
| 513 |
| 514 net::HttpRequestInfo request; |
| 515 request.method = "GET"; |
| 516 request.url = GURL("http://www.google.com/"); |
| 517 request.load_flags = 0; |
| 518 |
| 519 MockRead data_reads[] = { |
| 520 { true, net::ERR_CONNECTION_RESET, NULL, 0 }, |
| 521 { true, 0, "HTTP/1.0 200 OK\r\n\r\n", -1 }, // Should not be used |
| 522 { true, 0, "hello world", -1 }, |
| 523 { false, net::OK, NULL, 0 }, |
| 524 }; |
| 525 MockSocket data; |
| 526 data.connect.async = true; |
| 527 data.connect.result = net::OK; |
| 528 data.reads = data_reads; |
| 529 mock_sockets[0] = &data; |
| 530 mock_sockets[1] = NULL; |
| 531 |
| 532 TestCompletionCallback callback; |
| 533 |
| 534 int rv = trans->Start(&request, &callback); |
| 535 EXPECT_EQ(net::ERR_IO_PENDING, rv); |
| 536 |
| 537 rv = callback.WaitForResult(); |
| 538 EXPECT_EQ(net::ERR_CONNECTION_RESET, rv); |
| 539 |
| 540 const net::HttpResponseInfo* response = trans->GetResponseInfo(); |
| 541 EXPECT_TRUE(response == NULL); |
| 542 |
| 543 trans->Destroy(); |
| 544 |
| 545 // Empty the current queue. |
| 546 MessageLoop::current()->RunAllPending(); |
| 547 } |
| 548 |
| 549 // What do various browsers do when the server closes a non-keepalive |
| 550 // connection without sending any response header or body? |
| 551 // |
| 552 // IE7: error page |
| 553 // Safari 3.1.2 (Windows): error page |
| 554 // Firefox 3.0.1: blank page |
| 555 // Opera 9.52: after five attempts, blank page |
| 556 // Us with WinHTTP: error page (net::ERR_INVALID_RESPONSE) |
| 557 // Us: blank page |
| 558 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { |
| 559 MockRead data_reads[] = { |
| 560 { false, net::OK, NULL, 0 }, // EOF |
| 561 { true, 0, "HTTP/1.0 200 OK\r\n\r\n", -1 }, // Should not be used |
| 562 { true, 0, "hello world", -1 }, |
| 563 { false, net::OK, NULL, 0 }, |
| 564 }; |
| 565 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 566 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); |
| 567 EXPECT_EQ("", out.response_data); |
| 568 } |
| OLD | NEW |