| 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 <math.h> // ceil | 5 #include <math.h> // ceil |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "net/base/client_socket_factory.h" | 8 #include "net/base/client_socket_factory.h" |
| 9 #include "net/base/completion_callback.h" | 9 #include "net/base/completion_callback.h" |
| 10 #include "net/base/ssl_client_socket.h" | 10 #include "net/base/ssl_client_socket.h" |
| 11 #include "net/base/ssl_info.h" | 11 #include "net/base/ssl_info.h" |
| 12 #include "net/base/test_completion_callback.h" | 12 #include "net/base/test_completion_callback.h" |
| 13 #include "net/base/upload_data.h" | 13 #include "net/base/upload_data.h" |
| 14 #include "net/http/http_auth_handler_ntlm.h" | 14 #include "net/http/http_auth_handler_ntlm.h" |
| 15 #include "net/http/http_network_session.h" | 15 #include "net/http/http_network_session.h" |
| 16 #include "net/http/http_network_transaction.h" | 16 #include "net/http/http_network_transaction.h" |
| 17 #include "net/http/http_transaction_unittest.h" | 17 #include "net/http/http_transaction_unittest.h" |
| 18 #include "net/proxy/proxy_config_service_fixed.h" | 18 #include "net/proxy/proxy_config_service_fixed.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 #include "testing/platform_test.h" | 20 #include "testing/platform_test.h" |
| 21 | 21 |
| 22 //----------------------------------------------------------------------------- | 22 //----------------------------------------------------------------------------- |
| 23 | 23 |
| 24 namespace net { | 24 namespace net { |
| 25 | 25 |
| 26 // TODO(eroman): Now that this is inside the net namespace, remove the redundant | |
| 27 // net:: qualifiers. | |
| 28 | |
| 29 struct MockConnect { | 26 struct MockConnect { |
| 30 // Asynchronous connection success. | 27 // Asynchronous connection success. |
| 31 MockConnect() : async(true), result(OK) { } | 28 MockConnect() : async(true), result(OK) { } |
| 32 MockConnect(bool a, int r) : async(a), result(r) { } | 29 MockConnect(bool a, int r) : async(a), result(r) { } |
| 33 | 30 |
| 34 bool async; | 31 bool async; |
| 35 int result; | 32 int result; |
| 36 }; | 33 }; |
| 37 | 34 |
| 38 struct MockRead { | 35 struct MockRead { |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 ClientSocket* transport_socket, | 333 ClientSocket* transport_socket, |
| 337 const std::string& hostname, | 334 const std::string& hostname, |
| 338 const SSLConfig& ssl_config) { | 335 const SSLConfig& ssl_config) { |
| 339 return new MockSSLClientSocket(transport_socket, hostname, ssl_config); | 336 return new MockSSLClientSocket(transport_socket, hostname, ssl_config); |
| 340 } | 337 } |
| 341 }; | 338 }; |
| 342 | 339 |
| 343 MockClientSocketFactory mock_socket_factory; | 340 MockClientSocketFactory mock_socket_factory; |
| 344 | 341 |
| 345 // Create a proxy service which fails on all requests (falls back to direct). | 342 // Create a proxy service which fails on all requests (falls back to direct). |
| 346 net::ProxyService* CreateNullProxyService() { | 343 ProxyService* CreateNullProxyService() { |
| 347 return net::ProxyService::CreateNull(); | 344 return ProxyService::CreateNull(); |
| 348 } | 345 } |
| 349 | 346 |
| 350 net::ProxyService* CreateFixedProxyService(const std::string& proxy) { | 347 ProxyService* CreateFixedProxyService(const std::string& proxy) { |
| 351 net::ProxyInfo proxy_info; | 348 ProxyInfo proxy_info; |
| 352 proxy_info.UseNamedProxy(proxy); | 349 proxy_info.UseNamedProxy(proxy); |
| 353 return net::ProxyService::Create(&proxy_info); | 350 return ProxyService::Create(&proxy_info); |
| 354 } | 351 } |
| 355 | 352 |
| 356 | 353 |
| 357 net::HttpNetworkSession* CreateSession(net::ProxyService* proxy_service) { | 354 HttpNetworkSession* CreateSession(ProxyService* proxy_service) { |
| 358 return new net::HttpNetworkSession(proxy_service); | 355 return new HttpNetworkSession(proxy_service); |
| 359 } | 356 } |
| 360 | 357 |
| 361 class HttpNetworkTransactionTest : public PlatformTest { | 358 class HttpNetworkTransactionTest : public PlatformTest { |
| 362 public: | 359 public: |
| 363 virtual void SetUp() { | 360 virtual void SetUp() { |
| 364 PlatformTest::SetUp(); | 361 PlatformTest::SetUp(); |
| 365 mock_sockets[0] = NULL; | 362 mock_sockets[0] = NULL; |
| 366 mock_sockets_index = 0; | 363 mock_sockets_index = 0; |
| 367 mock_ssl_sockets_index = 0; | 364 mock_ssl_sockets_index = 0; |
| 368 } | 365 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 379 | 376 |
| 380 struct SimpleGetHelperResult { | 377 struct SimpleGetHelperResult { |
| 381 int rv; | 378 int rv; |
| 382 std::string status_line; | 379 std::string status_line; |
| 383 std::string response_data; | 380 std::string response_data; |
| 384 }; | 381 }; |
| 385 | 382 |
| 386 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) { | 383 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) { |
| 387 SimpleGetHelperResult out; | 384 SimpleGetHelperResult out; |
| 388 | 385 |
| 389 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 386 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 390 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 387 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 391 CreateSession(proxy_service.get()), &mock_socket_factory)); | 388 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 392 | 389 |
| 393 net::HttpRequestInfo request; | 390 HttpRequestInfo request; |
| 394 request.method = "GET"; | 391 request.method = "GET"; |
| 395 request.url = GURL("http://www.google.com/"); | 392 request.url = GURL("http://www.google.com/"); |
| 396 request.load_flags = 0; | 393 request.load_flags = 0; |
| 397 | 394 |
| 398 MockSocket data; | 395 MockSocket data; |
| 399 data.reads = data_reads; | 396 data.reads = data_reads; |
| 400 mock_sockets[0] = &data; | 397 mock_sockets[0] = &data; |
| 401 mock_sockets[1] = NULL; | 398 mock_sockets[1] = NULL; |
| 402 | 399 |
| 403 TestCompletionCallback callback; | 400 TestCompletionCallback callback; |
| 404 | 401 |
| 405 int rv = trans->Start(&request, &callback); | 402 int rv = trans->Start(&request, &callback); |
| 406 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 403 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 407 | 404 |
| 408 out.rv = callback.WaitForResult(); | 405 out.rv = callback.WaitForResult(); |
| 409 if (out.rv != net::OK) | 406 if (out.rv != OK) |
| 410 return out; | 407 return out; |
| 411 | 408 |
| 412 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 409 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 413 EXPECT_TRUE(response != NULL); | 410 EXPECT_TRUE(response != NULL); |
| 414 | 411 |
| 415 EXPECT_TRUE(response->headers != NULL); | 412 EXPECT_TRUE(response->headers != NULL); |
| 416 out.status_line = response->headers->GetStatusLine(); | 413 out.status_line = response->headers->GetStatusLine(); |
| 417 | 414 |
| 418 rv = ReadTransaction(trans.get(), &out.response_data); | 415 rv = ReadTransaction(trans.get(), &out.response_data); |
| 419 EXPECT_EQ(net::OK, rv); | 416 EXPECT_EQ(OK, rv); |
| 420 | 417 |
| 421 return out; | 418 return out; |
| 422 } | 419 } |
| 423 | 420 |
| 424 // Fill |str| with a long header list that consumes >= |size| bytes. | 421 // Fill |str| with a long header list that consumes >= |size| bytes. |
| 425 void FillLargeHeadersString(std::string* str, int size) { | 422 void FillLargeHeadersString(std::string* str, int size) { |
| 426 const char* row = | 423 const char* row = |
| 427 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; | 424 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; |
| 428 const int sizeof_row = strlen(row); | 425 const int sizeof_row = strlen(row); |
| 429 const int num_rows = static_cast<int>( | 426 const int num_rows = static_cast<int>( |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 } | 458 } |
| 462 } | 459 } |
| 463 | 460 |
| 464 std::string MockGetHostName() { | 461 std::string MockGetHostName() { |
| 465 return "WTC-WIN7"; | 462 return "WTC-WIN7"; |
| 466 } | 463 } |
| 467 | 464 |
| 468 //----------------------------------------------------------------------------- | 465 //----------------------------------------------------------------------------- |
| 469 | 466 |
| 470 TEST_F(HttpNetworkTransactionTest, Basic) { | 467 TEST_F(HttpNetworkTransactionTest, Basic) { |
| 471 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 468 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 472 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 469 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 473 CreateSession(proxy_service.get()), &mock_socket_factory)); | 470 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 474 } | 471 } |
| 475 | 472 |
| 476 TEST_F(HttpNetworkTransactionTest, SimpleGET) { | 473 TEST_F(HttpNetworkTransactionTest, SimpleGET) { |
| 477 MockRead data_reads[] = { | 474 MockRead data_reads[] = { |
| 478 MockRead("HTTP/1.0 200 OK\r\n\r\n"), | 475 MockRead("HTTP/1.0 200 OK\r\n\r\n"), |
| 479 MockRead("hello world"), | 476 MockRead("hello world"), |
| 480 MockRead(false, net::OK), | 477 MockRead(false, OK), |
| 481 }; | 478 }; |
| 482 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 479 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 483 EXPECT_EQ(net::OK, out.rv); | 480 EXPECT_EQ(OK, out.rv); |
| 484 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); | 481 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); |
| 485 EXPECT_EQ("hello world", out.response_data); | 482 EXPECT_EQ("hello world", out.response_data); |
| 486 } | 483 } |
| 487 | 484 |
| 488 // Response with no status line. | 485 // Response with no status line. |
| 489 TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) { | 486 TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) { |
| 490 MockRead data_reads[] = { | 487 MockRead data_reads[] = { |
| 491 MockRead("hello world"), | 488 MockRead("hello world"), |
| 492 MockRead(false, net::OK), | 489 MockRead(false, OK), |
| 493 }; | 490 }; |
| 494 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 491 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 495 EXPECT_EQ(net::OK, out.rv); | 492 EXPECT_EQ(OK, out.rv); |
| 496 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); | 493 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); |
| 497 EXPECT_EQ("hello world", out.response_data); | 494 EXPECT_EQ("hello world", out.response_data); |
| 498 } | 495 } |
| 499 | 496 |
| 500 // Allow up to 4 bytes of junk to precede status line. | 497 // Allow up to 4 bytes of junk to precede status line. |
| 501 TEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) { | 498 TEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) { |
| 502 MockRead data_reads[] = { | 499 MockRead data_reads[] = { |
| 503 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), | 500 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), |
| 504 MockRead(false, net::OK), | 501 MockRead(false, OK), |
| 505 }; | 502 }; |
| 506 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 503 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 507 EXPECT_EQ(net::OK, out.rv); | 504 EXPECT_EQ(OK, out.rv); |
| 508 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); | 505 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); |
| 509 EXPECT_EQ("DATA", out.response_data); | 506 EXPECT_EQ("DATA", out.response_data); |
| 510 } | 507 } |
| 511 | 508 |
| 512 // Allow up to 4 bytes of junk to precede status line. | 509 // Allow up to 4 bytes of junk to precede status line. |
| 513 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { | 510 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) { |
| 514 MockRead data_reads[] = { | 511 MockRead data_reads[] = { |
| 515 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), | 512 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), |
| 516 MockRead(false, net::OK), | 513 MockRead(false, OK), |
| 517 }; | 514 }; |
| 518 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 515 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 519 EXPECT_EQ(net::OK, out.rv); | 516 EXPECT_EQ(OK, out.rv); |
| 520 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); | 517 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); |
| 521 EXPECT_EQ("DATA", out.response_data); | 518 EXPECT_EQ("DATA", out.response_data); |
| 522 } | 519 } |
| 523 | 520 |
| 524 // Beyond 4 bytes of slop and it should fail to find a status line. | 521 // Beyond 4 bytes of slop and it should fail to find a status line. |
| 525 TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { | 522 TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) { |
| 526 MockRead data_reads[] = { | 523 MockRead data_reads[] = { |
| 527 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"), | 524 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"), |
| 528 MockRead(false, net::OK), | 525 MockRead(false, OK), |
| 529 }; | 526 }; |
| 530 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 527 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 531 EXPECT_EQ(net::OK, out.rv); | 528 EXPECT_EQ(OK, out.rv); |
| 532 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); | 529 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); |
| 533 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); | 530 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data); |
| 534 } | 531 } |
| 535 | 532 |
| 536 // Same as StatusLineJunk4Bytes, except the read chunks are smaller. | 533 // Same as StatusLineJunk4Bytes, except the read chunks are smaller. |
| 537 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { | 534 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) { |
| 538 MockRead data_reads[] = { | 535 MockRead data_reads[] = { |
| 539 MockRead("\n"), | 536 MockRead("\n"), |
| 540 MockRead("\n"), | 537 MockRead("\n"), |
| 541 MockRead("Q"), | 538 MockRead("Q"), |
| 542 MockRead("J"), | 539 MockRead("J"), |
| 543 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), | 540 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"), |
| 544 MockRead(false, net::OK), | 541 MockRead(false, OK), |
| 545 }; | 542 }; |
| 546 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 543 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 547 EXPECT_EQ(net::OK, out.rv); | 544 EXPECT_EQ(OK, out.rv); |
| 548 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); | 545 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line); |
| 549 EXPECT_EQ("DATA", out.response_data); | 546 EXPECT_EQ("DATA", out.response_data); |
| 550 } | 547 } |
| 551 | 548 |
| 552 // Close the connection before enough bytes to have a status line. | 549 // Close the connection before enough bytes to have a status line. |
| 553 TEST_F(HttpNetworkTransactionTest, StatusLinePartial) { | 550 TEST_F(HttpNetworkTransactionTest, StatusLinePartial) { |
| 554 MockRead data_reads[] = { | 551 MockRead data_reads[] = { |
| 555 MockRead("HTT"), | 552 MockRead("HTT"), |
| 556 MockRead(false, net::OK), | 553 MockRead(false, OK), |
| 557 }; | 554 }; |
| 558 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 555 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 559 EXPECT_EQ(net::OK, out.rv); | 556 EXPECT_EQ(OK, out.rv); |
| 560 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); | 557 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line); |
| 561 EXPECT_EQ("HTT", out.response_data); | 558 EXPECT_EQ("HTT", out.response_data); |
| 562 } | 559 } |
| 563 | 560 |
| 564 // Simulate a 204 response, lacking a Content-Length header, sent over a | 561 // Simulate a 204 response, lacking a Content-Length header, sent over a |
| 565 // persistent connection. The response should still terminate since a 204 | 562 // persistent connection. The response should still terminate since a 204 |
| 566 // cannot have a response body. | 563 // cannot have a response body. |
| 567 TEST_F(HttpNetworkTransactionTest, StopsReading204) { | 564 TEST_F(HttpNetworkTransactionTest, StopsReading204) { |
| 568 MockRead data_reads[] = { | 565 MockRead data_reads[] = { |
| 569 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), | 566 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), |
| 570 MockRead("junk"), // Should not be read!! | 567 MockRead("junk"), // Should not be read!! |
| 571 MockRead(false, net::OK), | 568 MockRead(false, OK), |
| 572 }; | 569 }; |
| 573 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 570 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 574 EXPECT_EQ(net::OK, out.rv); | 571 EXPECT_EQ(OK, out.rv); |
| 575 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); | 572 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); |
| 576 EXPECT_EQ("", out.response_data); | 573 EXPECT_EQ("", out.response_data); |
| 577 } | 574 } |
| 578 | 575 |
| 579 // Do a request using the HEAD method. Verify that we don't try to read the | 576 // Do a request using the HEAD method. Verify that we don't try to read the |
| 580 // message body (since HEAD has none). | 577 // message body (since HEAD has none). |
| 581 TEST_F(HttpNetworkTransactionTest, Head) { | 578 TEST_F(HttpNetworkTransactionTest, Head) { |
| 582 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 579 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 583 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 580 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 584 CreateSession(proxy_service.get()), &mock_socket_factory)); | 581 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 585 | 582 |
| 586 net::HttpRequestInfo request; | 583 HttpRequestInfo request; |
| 587 request.method = "HEAD"; | 584 request.method = "HEAD"; |
| 588 request.url = GURL("http://www.google.com/"); | 585 request.url = GURL("http://www.google.com/"); |
| 589 request.load_flags = 0; | 586 request.load_flags = 0; |
| 590 | 587 |
| 591 MockWrite data_writes1[] = { | 588 MockWrite data_writes1[] = { |
| 592 MockWrite("HEAD / HTTP/1.1\r\n" | 589 MockWrite("HEAD / HTTP/1.1\r\n" |
| 593 "Host: www.google.com\r\n" | 590 "Host: www.google.com\r\n" |
| 594 "Connection: keep-alive\r\n" | 591 "Connection: keep-alive\r\n" |
| 595 "Content-Length: 0\r\n\r\n"), | 592 "Content-Length: 0\r\n\r\n"), |
| 596 }; | 593 }; |
| 597 MockRead data_reads1[] = { | 594 MockRead data_reads1[] = { |
| 598 MockRead("HTTP/1.1 404 Not Found\r\n"), | 595 MockRead("HTTP/1.1 404 Not Found\r\n"), |
| 599 MockRead("Server: Blah\r\n"), | 596 MockRead("Server: Blah\r\n"), |
| 600 MockRead("Content-Length: 1234\r\n\r\n"), | 597 MockRead("Content-Length: 1234\r\n\r\n"), |
| 601 | 598 |
| 602 // No response body because the test stops reading here. | 599 // No response body because the test stops reading here. |
| 603 MockRead(false, net::ERR_UNEXPECTED), // Should not be reached. | 600 MockRead(false, ERR_UNEXPECTED), // Should not be reached. |
| 604 }; | 601 }; |
| 605 | 602 |
| 606 MockSocket data1; | 603 MockSocket data1; |
| 607 data1.reads = data_reads1; | 604 data1.reads = data_reads1; |
| 608 data1.writes = data_writes1; | 605 data1.writes = data_writes1; |
| 609 mock_sockets[0] = &data1; | 606 mock_sockets[0] = &data1; |
| 610 mock_sockets[1] = NULL; | 607 mock_sockets[1] = NULL; |
| 611 | 608 |
| 612 TestCompletionCallback callback1; | 609 TestCompletionCallback callback1; |
| 613 | 610 |
| 614 int rv = trans->Start(&request, &callback1); | 611 int rv = trans->Start(&request, &callback1); |
| 615 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 612 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 616 | 613 |
| 617 rv = callback1.WaitForResult(); | 614 rv = callback1.WaitForResult(); |
| 618 EXPECT_EQ(net::OK, rv); | 615 EXPECT_EQ(OK, rv); |
| 619 | 616 |
| 620 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 617 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 621 EXPECT_FALSE(response == NULL); | 618 EXPECT_FALSE(response == NULL); |
| 622 | 619 |
| 623 // Check that the headers got parsed. | 620 // Check that the headers got parsed. |
| 624 EXPECT_TRUE(response->headers != NULL); | 621 EXPECT_TRUE(response->headers != NULL); |
| 625 EXPECT_EQ(1234, response->headers->GetContentLength()); | 622 EXPECT_EQ(1234, response->headers->GetContentLength()); |
| 626 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine()); | 623 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine()); |
| 627 | 624 |
| 628 std::string server_header; | 625 std::string server_header; |
| 629 void* iter = NULL; | 626 void* iter = NULL; |
| 630 bool has_server_header = response->headers->EnumerateHeader( | 627 bool has_server_header = response->headers->EnumerateHeader( |
| 631 &iter, "Server", &server_header); | 628 &iter, "Server", &server_header); |
| 632 EXPECT_TRUE(has_server_header); | 629 EXPECT_TRUE(has_server_header); |
| 633 EXPECT_EQ("Blah", server_header); | 630 EXPECT_EQ("Blah", server_header); |
| 634 | 631 |
| 635 // Reading should give EOF right away, since there is no message body | 632 // Reading should give EOF right away, since there is no message body |
| 636 // (despite non-zero content-length). | 633 // (despite non-zero content-length). |
| 637 std::string response_data; | 634 std::string response_data; |
| 638 rv = ReadTransaction(trans.get(), &response_data); | 635 rv = ReadTransaction(trans.get(), &response_data); |
| 639 EXPECT_EQ(net::OK, rv); | 636 EXPECT_EQ(OK, rv); |
| 640 EXPECT_EQ("", response_data); | 637 EXPECT_EQ("", response_data); |
| 641 } | 638 } |
| 642 | 639 |
| 643 TEST_F(HttpNetworkTransactionTest, ReuseConnection) { | 640 TEST_F(HttpNetworkTransactionTest, ReuseConnection) { |
| 644 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 641 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 645 scoped_refptr<net::HttpNetworkSession> session = | 642 scoped_refptr<HttpNetworkSession> session = |
| 646 CreateSession(proxy_service.get()); | 643 CreateSession(proxy_service.get()); |
| 647 | 644 |
| 648 MockRead data_reads[] = { | 645 MockRead data_reads[] = { |
| 649 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), | 646 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), |
| 650 MockRead("hello"), | 647 MockRead("hello"), |
| 651 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), | 648 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), |
| 652 MockRead("world"), | 649 MockRead("world"), |
| 653 MockRead(false, net::OK), | 650 MockRead(false, OK), |
| 654 }; | 651 }; |
| 655 MockSocket data; | 652 MockSocket data; |
| 656 data.reads = data_reads; | 653 data.reads = data_reads; |
| 657 mock_sockets[0] = &data; | 654 mock_sockets[0] = &data; |
| 658 mock_sockets[1] = NULL; | 655 mock_sockets[1] = NULL; |
| 659 | 656 |
| 660 const char* kExpectedResponseData[] = { | 657 const char* kExpectedResponseData[] = { |
| 661 "hello", "world" | 658 "hello", "world" |
| 662 }; | 659 }; |
| 663 | 660 |
| 664 for (int i = 0; i < 2; ++i) { | 661 for (int i = 0; i < 2; ++i) { |
| 665 scoped_ptr<net::HttpTransaction> trans( | 662 scoped_ptr<HttpTransaction> trans( |
| 666 new net::HttpNetworkTransaction(session, &mock_socket_factory)); | 663 new HttpNetworkTransaction(session, &mock_socket_factory)); |
| 667 | 664 |
| 668 net::HttpRequestInfo request; | 665 HttpRequestInfo request; |
| 669 request.method = "GET"; | 666 request.method = "GET"; |
| 670 request.url = GURL("http://www.google.com/"); | 667 request.url = GURL("http://www.google.com/"); |
| 671 request.load_flags = 0; | 668 request.load_flags = 0; |
| 672 | 669 |
| 673 TestCompletionCallback callback; | 670 TestCompletionCallback callback; |
| 674 | 671 |
| 675 int rv = trans->Start(&request, &callback); | 672 int rv = trans->Start(&request, &callback); |
| 676 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 673 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 677 | 674 |
| 678 rv = callback.WaitForResult(); | 675 rv = callback.WaitForResult(); |
| 679 EXPECT_EQ(net::OK, rv); | 676 EXPECT_EQ(OK, rv); |
| 680 | 677 |
| 681 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 678 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 682 EXPECT_TRUE(response != NULL); | 679 EXPECT_TRUE(response != NULL); |
| 683 | 680 |
| 684 EXPECT_TRUE(response->headers != NULL); | 681 EXPECT_TRUE(response->headers != NULL); |
| 685 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); | 682 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 686 | 683 |
| 687 std::string response_data; | 684 std::string response_data; |
| 688 rv = ReadTransaction(trans.get(), &response_data); | 685 rv = ReadTransaction(trans.get(), &response_data); |
| 689 EXPECT_EQ(net::OK, rv); | 686 EXPECT_EQ(OK, rv); |
| 690 EXPECT_EQ(kExpectedResponseData[i], response_data); | 687 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 691 } | 688 } |
| 692 } | 689 } |
| 693 | 690 |
| 694 TEST_F(HttpNetworkTransactionTest, Ignores100) { | 691 TEST_F(HttpNetworkTransactionTest, Ignores100) { |
| 695 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 692 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 696 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 693 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 697 CreateSession(proxy_service.get()), &mock_socket_factory)); | 694 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 698 | 695 |
| 699 net::HttpRequestInfo request; | 696 HttpRequestInfo request; |
| 700 request.method = "POST"; | 697 request.method = "POST"; |
| 701 request.url = GURL("http://www.foo.com/"); | 698 request.url = GURL("http://www.foo.com/"); |
| 702 request.upload_data = new net::UploadData; | 699 request.upload_data = new UploadData; |
| 703 request.upload_data->AppendBytes("foo", 3); | 700 request.upload_data->AppendBytes("foo", 3); |
| 704 request.load_flags = 0; | 701 request.load_flags = 0; |
| 705 | 702 |
| 706 MockRead data_reads[] = { | 703 MockRead data_reads[] = { |
| 707 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), | 704 MockRead("HTTP/1.0 100 Continue\r\n\r\n"), |
| 708 MockRead("HTTP/1.0 200 OK\r\n\r\n"), | 705 MockRead("HTTP/1.0 200 OK\r\n\r\n"), |
| 709 MockRead("hello world"), | 706 MockRead("hello world"), |
| 710 MockRead(false, net::OK), | 707 MockRead(false, OK), |
| 711 }; | 708 }; |
| 712 MockSocket data; | 709 MockSocket data; |
| 713 data.reads = data_reads; | 710 data.reads = data_reads; |
| 714 mock_sockets[0] = &data; | 711 mock_sockets[0] = &data; |
| 715 mock_sockets[1] = NULL; | 712 mock_sockets[1] = NULL; |
| 716 | 713 |
| 717 TestCompletionCallback callback; | 714 TestCompletionCallback callback; |
| 718 | 715 |
| 719 int rv = trans->Start(&request, &callback); | 716 int rv = trans->Start(&request, &callback); |
| 720 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 717 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 721 | 718 |
| 722 rv = callback.WaitForResult(); | 719 rv = callback.WaitForResult(); |
| 723 EXPECT_EQ(net::OK, rv); | 720 EXPECT_EQ(OK, rv); |
| 724 | 721 |
| 725 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 722 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 726 EXPECT_TRUE(response != NULL); | 723 EXPECT_TRUE(response != NULL); |
| 727 | 724 |
| 728 EXPECT_TRUE(response->headers != NULL); | 725 EXPECT_TRUE(response->headers != NULL); |
| 729 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); | 726 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); |
| 730 | 727 |
| 731 std::string response_data; | 728 std::string response_data; |
| 732 rv = ReadTransaction(trans.get(), &response_data); | 729 rv = ReadTransaction(trans.get(), &response_data); |
| 733 EXPECT_EQ(net::OK, rv); | 730 EXPECT_EQ(OK, rv); |
| 734 EXPECT_EQ("hello world", response_data); | 731 EXPECT_EQ("hello world", response_data); |
| 735 } | 732 } |
| 736 | 733 |
| 737 // This test is almost the same as Ignores100 above, but the response contains | 734 // This test is almost the same as Ignores100 above, but the response contains |
| 738 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is | 735 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is |
| 739 // HTTP/1.1. | 736 // HTTP/1.1. |
| 740 TEST_F(HttpNetworkTransactionTest, Ignores1xx) { | 737 TEST_F(HttpNetworkTransactionTest, Ignores1xx) { |
| 741 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 738 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 742 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 739 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 743 CreateSession(proxy_service.get()), &mock_socket_factory)); | 740 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 744 | 741 |
| 745 net::HttpRequestInfo request; | 742 HttpRequestInfo request; |
| 746 request.method = "GET"; | 743 request.method = "GET"; |
| 747 request.url = GURL("http://www.foo.com/"); | 744 request.url = GURL("http://www.foo.com/"); |
| 748 request.load_flags = 0; | 745 request.load_flags = 0; |
| 749 | 746 |
| 750 MockRead data_reads[] = { | 747 MockRead data_reads[] = { |
| 751 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"), | 748 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"), |
| 752 MockRead("HTTP/1.1 200 OK\r\n\r\n"), | 749 MockRead("HTTP/1.1 200 OK\r\n\r\n"), |
| 753 MockRead("hello world"), | 750 MockRead("hello world"), |
| 754 MockRead(false, net::OK), | 751 MockRead(false, OK), |
| 755 }; | 752 }; |
| 756 MockSocket data; | 753 MockSocket data; |
| 757 data.reads = data_reads; | 754 data.reads = data_reads; |
| 758 mock_sockets[0] = &data; | 755 mock_sockets[0] = &data; |
| 759 mock_sockets[1] = NULL; | 756 mock_sockets[1] = NULL; |
| 760 | 757 |
| 761 TestCompletionCallback callback; | 758 TestCompletionCallback callback; |
| 762 | 759 |
| 763 int rv = trans->Start(&request, &callback); | 760 int rv = trans->Start(&request, &callback); |
| 764 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 761 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 765 | 762 |
| 766 rv = callback.WaitForResult(); | 763 rv = callback.WaitForResult(); |
| 767 EXPECT_EQ(net::OK, rv); | 764 EXPECT_EQ(OK, rv); |
| 768 | 765 |
| 769 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 766 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 770 EXPECT_TRUE(response != NULL); | 767 EXPECT_TRUE(response != NULL); |
| 771 | 768 |
| 772 EXPECT_TRUE(response->headers != NULL); | 769 EXPECT_TRUE(response->headers != NULL); |
| 773 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); | 770 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 774 | 771 |
| 775 std::string response_data; | 772 std::string response_data; |
| 776 rv = ReadTransaction(trans.get(), &response_data); | 773 rv = ReadTransaction(trans.get(), &response_data); |
| 777 EXPECT_EQ(net::OK, rv); | 774 EXPECT_EQ(OK, rv); |
| 778 EXPECT_EQ("hello world", response_data); | 775 EXPECT_EQ("hello world", response_data); |
| 779 } | 776 } |
| 780 | 777 |
| 781 // read_failure specifies a read failure that should cause the network | 778 // read_failure specifies a read failure that should cause the network |
| 782 // transaction to resend the request. | 779 // transaction to resend the request. |
| 783 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest( | 780 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest( |
| 784 const MockRead& read_failure) { | 781 const MockRead& read_failure) { |
| 785 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 782 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 786 scoped_refptr<net::HttpNetworkSession> session = | 783 scoped_refptr<HttpNetworkSession> session = |
| 787 CreateSession(proxy_service.get()); | 784 CreateSession(proxy_service.get()); |
| 788 | 785 |
| 789 net::HttpRequestInfo request; | 786 HttpRequestInfo request; |
| 790 request.method = "GET"; | 787 request.method = "GET"; |
| 791 request.url = GURL("http://www.foo.com/"); | 788 request.url = GURL("http://www.foo.com/"); |
| 792 request.load_flags = 0; | 789 request.load_flags = 0; |
| 793 | 790 |
| 794 MockRead data1_reads[] = { | 791 MockRead data1_reads[] = { |
| 795 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), | 792 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), |
| 796 MockRead("hello"), | 793 MockRead("hello"), |
| 797 read_failure, // Now, we reuse the connection and fail the first read. | 794 read_failure, // Now, we reuse the connection and fail the first read. |
| 798 }; | 795 }; |
| 799 MockSocket data1; | 796 MockSocket data1; |
| 800 data1.reads = data1_reads; | 797 data1.reads = data1_reads; |
| 801 mock_sockets[0] = &data1; | 798 mock_sockets[0] = &data1; |
| 802 | 799 |
| 803 MockRead data2_reads[] = { | 800 MockRead data2_reads[] = { |
| 804 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), | 801 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"), |
| 805 MockRead("world"), | 802 MockRead("world"), |
| 806 MockRead(true, net::OK), | 803 MockRead(true, OK), |
| 807 }; | 804 }; |
| 808 MockSocket data2; | 805 MockSocket data2; |
| 809 data2.reads = data2_reads; | 806 data2.reads = data2_reads; |
| 810 mock_sockets[1] = &data2; | 807 mock_sockets[1] = &data2; |
| 811 | 808 |
| 812 const char* kExpectedResponseData[] = { | 809 const char* kExpectedResponseData[] = { |
| 813 "hello", "world" | 810 "hello", "world" |
| 814 }; | 811 }; |
| 815 | 812 |
| 816 for (int i = 0; i < 2; ++i) { | 813 for (int i = 0; i < 2; ++i) { |
| 817 TestCompletionCallback callback; | 814 TestCompletionCallback callback; |
| 818 | 815 |
| 819 scoped_ptr<net::HttpTransaction> trans( | 816 scoped_ptr<HttpTransaction> trans( |
| 820 new net::HttpNetworkTransaction(session, &mock_socket_factory)); | 817 new HttpNetworkTransaction(session, &mock_socket_factory)); |
| 821 | 818 |
| 822 int rv = trans->Start(&request, &callback); | 819 int rv = trans->Start(&request, &callback); |
| 823 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 820 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 824 | 821 |
| 825 rv = callback.WaitForResult(); | 822 rv = callback.WaitForResult(); |
| 826 EXPECT_EQ(net::OK, rv); | 823 EXPECT_EQ(OK, rv); |
| 827 | 824 |
| 828 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 825 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 829 EXPECT_TRUE(response != NULL); | 826 EXPECT_TRUE(response != NULL); |
| 830 | 827 |
| 831 EXPECT_TRUE(response->headers != NULL); | 828 EXPECT_TRUE(response->headers != NULL); |
| 832 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); | 829 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 833 | 830 |
| 834 std::string response_data; | 831 std::string response_data; |
| 835 rv = ReadTransaction(trans.get(), &response_data); | 832 rv = ReadTransaction(trans.get(), &response_data); |
| 836 EXPECT_EQ(net::OK, rv); | 833 EXPECT_EQ(OK, rv); |
| 837 EXPECT_EQ(kExpectedResponseData[i], response_data); | 834 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 838 } | 835 } |
| 839 } | 836 } |
| 840 | 837 |
| 841 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) { | 838 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) { |
| 842 MockRead read_failure(true, net::ERR_CONNECTION_RESET); | 839 MockRead read_failure(true, ERR_CONNECTION_RESET); |
| 843 KeepAliveConnectionResendRequestTest(read_failure); | 840 KeepAliveConnectionResendRequestTest(read_failure); |
| 844 } | 841 } |
| 845 | 842 |
| 846 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { | 843 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) { |
| 847 MockRead read_failure(false, net::OK); // EOF | 844 MockRead read_failure(false, OK); // EOF |
| 848 KeepAliveConnectionResendRequestTest(read_failure); | 845 KeepAliveConnectionResendRequestTest(read_failure); |
| 849 } | 846 } |
| 850 | 847 |
| 851 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { | 848 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) { |
| 852 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 849 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 853 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 850 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 854 CreateSession(proxy_service.get()), &mock_socket_factory)); | 851 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 855 | 852 |
| 856 net::HttpRequestInfo request; | 853 HttpRequestInfo request; |
| 857 request.method = "GET"; | 854 request.method = "GET"; |
| 858 request.url = GURL("http://www.google.com/"); | 855 request.url = GURL("http://www.google.com/"); |
| 859 request.load_flags = 0; | 856 request.load_flags = 0; |
| 860 | 857 |
| 861 MockRead data_reads[] = { | 858 MockRead data_reads[] = { |
| 862 MockRead(true, net::ERR_CONNECTION_RESET), | 859 MockRead(true, ERR_CONNECTION_RESET), |
| 863 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used | 860 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used |
| 864 MockRead("hello world"), | 861 MockRead("hello world"), |
| 865 MockRead(false, net::OK), | 862 MockRead(false, OK), |
| 866 }; | 863 }; |
| 867 MockSocket data; | 864 MockSocket data; |
| 868 data.reads = data_reads; | 865 data.reads = data_reads; |
| 869 mock_sockets[0] = &data; | 866 mock_sockets[0] = &data; |
| 870 mock_sockets[1] = NULL; | 867 mock_sockets[1] = NULL; |
| 871 | 868 |
| 872 TestCompletionCallback callback; | 869 TestCompletionCallback callback; |
| 873 | 870 |
| 874 int rv = trans->Start(&request, &callback); | 871 int rv = trans->Start(&request, &callback); |
| 875 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 872 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 876 | 873 |
| 877 rv = callback.WaitForResult(); | 874 rv = callback.WaitForResult(); |
| 878 EXPECT_EQ(net::ERR_CONNECTION_RESET, rv); | 875 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 879 | 876 |
| 880 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 877 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 881 EXPECT_TRUE(response == NULL); | 878 EXPECT_TRUE(response == NULL); |
| 882 } | 879 } |
| 883 | 880 |
| 884 // What do various browsers do when the server closes a non-keepalive | 881 // What do various browsers do when the server closes a non-keepalive |
| 885 // connection without sending any response header or body? | 882 // connection without sending any response header or body? |
| 886 // | 883 // |
| 887 // IE7: error page | 884 // IE7: error page |
| 888 // Safari 3.1.2 (Windows): error page | 885 // Safari 3.1.2 (Windows): error page |
| 889 // Firefox 3.0.1: blank page | 886 // Firefox 3.0.1: blank page |
| 890 // Opera 9.52: after five attempts, blank page | 887 // Opera 9.52: after five attempts, blank page |
| 891 // Us with WinHTTP: error page (net::ERR_INVALID_RESPONSE) | 888 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE) |
| 892 // Us: error page (net::EMPTY_RESPONSE) | 889 // Us: error page (EMPTY_RESPONSE) |
| 893 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { | 890 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { |
| 894 MockRead data_reads[] = { | 891 MockRead data_reads[] = { |
| 895 MockRead(false, net::OK), // EOF | 892 MockRead(false, OK), // EOF |
| 896 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used | 893 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used |
| 897 MockRead("hello world"), | 894 MockRead("hello world"), |
| 898 MockRead(false, net::OK), | 895 MockRead(false, OK), |
| 899 }; | 896 }; |
| 900 SimpleGetHelperResult out = SimpleGetHelper(data_reads); | 897 SimpleGetHelperResult out = SimpleGetHelper(data_reads); |
| 901 EXPECT_EQ(net::ERR_EMPTY_RESPONSE, out.rv); | 898 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); |
| 902 } | 899 } |
| 903 | 900 |
| 904 // Test the request-challenge-retry sequence for basic auth. | 901 // Test the request-challenge-retry sequence for basic auth. |
| 905 // (basic auth is the easiest to mock, because it has no randomness). | 902 // (basic auth is the easiest to mock, because it has no randomness). |
| 906 TEST_F(HttpNetworkTransactionTest, BasicAuth) { | 903 TEST_F(HttpNetworkTransactionTest, BasicAuth) { |
| 907 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 904 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 908 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 905 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 909 CreateSession(proxy_service.get()), &mock_socket_factory)); | 906 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 910 | 907 |
| 911 net::HttpRequestInfo request; | 908 HttpRequestInfo request; |
| 912 request.method = "GET"; | 909 request.method = "GET"; |
| 913 request.url = GURL("http://www.google.com/"); | 910 request.url = GURL("http://www.google.com/"); |
| 914 request.load_flags = 0; | 911 request.load_flags = 0; |
| 915 | 912 |
| 916 MockWrite data_writes1[] = { | 913 MockWrite data_writes1[] = { |
| 917 MockWrite("GET / HTTP/1.1\r\n" | 914 MockWrite("GET / HTTP/1.1\r\n" |
| 918 "Host: www.google.com\r\n" | 915 "Host: www.google.com\r\n" |
| 919 "Connection: keep-alive\r\n\r\n"), | 916 "Connection: keep-alive\r\n\r\n"), |
| 920 }; | 917 }; |
| 921 | 918 |
| 922 MockRead data_reads1[] = { | 919 MockRead data_reads1[] = { |
| 923 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 920 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 924 // Give a couple authenticate options (only the middle one is actually | 921 // Give a couple authenticate options (only the middle one is actually |
| 925 // supported). | 922 // supported). |
| 926 MockRead("WWW-Authenticate: Basic\r\n"), // Malformed | 923 MockRead("WWW-Authenticate: Basic\r\n"), // Malformed |
| 927 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 924 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 928 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), | 925 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), |
| 929 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 926 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 930 // Large content-length -- won't matter, as connection will be reset. | 927 // Large content-length -- won't matter, as connection will be reset. |
| 931 MockRead("Content-Length: 10000\r\n\r\n"), | 928 MockRead("Content-Length: 10000\r\n\r\n"), |
| 932 MockRead(false, net::ERR_FAILED), | 929 MockRead(false, ERR_FAILED), |
| 933 }; | 930 }; |
| 934 | 931 |
| 935 // After calling trans->RestartWithAuth(), this is the request we should | 932 // After calling trans->RestartWithAuth(), this is the request we should |
| 936 // be issuing -- the final header line contains the credentials. | 933 // be issuing -- the final header line contains the credentials. |
| 937 MockWrite data_writes2[] = { | 934 MockWrite data_writes2[] = { |
| 938 MockWrite("GET / HTTP/1.1\r\n" | 935 MockWrite("GET / HTTP/1.1\r\n" |
| 939 "Host: www.google.com\r\n" | 936 "Host: www.google.com\r\n" |
| 940 "Connection: keep-alive\r\n" | 937 "Connection: keep-alive\r\n" |
| 941 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 938 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 942 }; | 939 }; |
| 943 | 940 |
| 944 // Lastly, the server responds with the actual content. | 941 // Lastly, the server responds with the actual content. |
| 945 MockRead data_reads2[] = { | 942 MockRead data_reads2[] = { |
| 946 MockRead("HTTP/1.0 200 OK\r\n"), | 943 MockRead("HTTP/1.0 200 OK\r\n"), |
| 947 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 944 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 948 MockRead("Content-Length: 100\r\n\r\n"), | 945 MockRead("Content-Length: 100\r\n\r\n"), |
| 949 MockRead(false, net::OK), | 946 MockRead(false, OK), |
| 950 }; | 947 }; |
| 951 | 948 |
| 952 MockSocket data1; | 949 MockSocket data1; |
| 953 data1.reads = data_reads1; | 950 data1.reads = data_reads1; |
| 954 data1.writes = data_writes1; | 951 data1.writes = data_writes1; |
| 955 MockSocket data2; | 952 MockSocket data2; |
| 956 data2.reads = data_reads2; | 953 data2.reads = data_reads2; |
| 957 data2.writes = data_writes2; | 954 data2.writes = data_writes2; |
| 958 mock_sockets[0] = &data1; | 955 mock_sockets[0] = &data1; |
| 959 mock_sockets[1] = &data2; | 956 mock_sockets[1] = &data2; |
| 960 mock_sockets[2] = NULL; | 957 mock_sockets[2] = NULL; |
| 961 | 958 |
| 962 TestCompletionCallback callback1; | 959 TestCompletionCallback callback1; |
| 963 | 960 |
| 964 int rv = trans->Start(&request, &callback1); | 961 int rv = trans->Start(&request, &callback1); |
| 965 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 962 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 966 | 963 |
| 967 rv = callback1.WaitForResult(); | 964 rv = callback1.WaitForResult(); |
| 968 EXPECT_EQ(net::OK, rv); | 965 EXPECT_EQ(OK, rv); |
| 969 | 966 |
| 970 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 967 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 971 EXPECT_FALSE(response == NULL); | 968 EXPECT_FALSE(response == NULL); |
| 972 | 969 |
| 973 // The password prompt info should have been set in response->auth_challenge. | 970 // The password prompt info should have been set in response->auth_challenge. |
| 974 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 971 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 975 | 972 |
| 976 // TODO(eroman): this should really include the effective port (80) | 973 // TODO(eroman): this should really include the effective port (80) |
| 977 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 974 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 978 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 975 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 979 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 976 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 980 | 977 |
| 981 TestCompletionCallback callback2; | 978 TestCompletionCallback callback2; |
| 982 | 979 |
| 983 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); | 980 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); |
| 984 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 981 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 985 | 982 |
| 986 rv = callback2.WaitForResult(); | 983 rv = callback2.WaitForResult(); |
| 987 EXPECT_EQ(net::OK, rv); | 984 EXPECT_EQ(OK, rv); |
| 988 | 985 |
| 989 response = trans->GetResponseInfo(); | 986 response = trans->GetResponseInfo(); |
| 990 EXPECT_FALSE(response == NULL); | 987 EXPECT_FALSE(response == NULL); |
| 991 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 988 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 992 EXPECT_EQ(100, response->headers->GetContentLength()); | 989 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 993 } | 990 } |
| 994 | 991 |
| 995 // Test the request-challenge-retry sequence for basic auth, over a keep-alive | 992 // Test the request-challenge-retry sequence for basic auth, over a keep-alive |
| 996 // connection. | 993 // connection. |
| 997 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) { | 994 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) { |
| 998 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 995 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 999 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 996 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1000 CreateSession(proxy_service.get()), &mock_socket_factory)); | 997 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 1001 | 998 |
| 1002 net::HttpRequestInfo request; | 999 HttpRequestInfo request; |
| 1003 request.method = "GET"; | 1000 request.method = "GET"; |
| 1004 request.url = GURL("http://www.google.com/"); | 1001 request.url = GURL("http://www.google.com/"); |
| 1005 request.load_flags = 0; | 1002 request.load_flags = 0; |
| 1006 | 1003 |
| 1007 MockWrite data_writes1[] = { | 1004 MockWrite data_writes1[] = { |
| 1008 MockWrite("GET / HTTP/1.1\r\n" | 1005 MockWrite("GET / HTTP/1.1\r\n" |
| 1009 "Host: www.google.com\r\n" | 1006 "Host: www.google.com\r\n" |
| 1010 "Connection: keep-alive\r\n\r\n"), | 1007 "Connection: keep-alive\r\n\r\n"), |
| 1011 | 1008 |
| 1012 // After calling trans->RestartWithAuth(), this is the request we should | 1009 // After calling trans->RestartWithAuth(), this is the request we should |
| 1013 // be issuing -- the final header line contains the credentials. | 1010 // be issuing -- the final header line contains the credentials. |
| 1014 MockWrite("GET / HTTP/1.1\r\n" | 1011 MockWrite("GET / HTTP/1.1\r\n" |
| 1015 "Host: www.google.com\r\n" | 1012 "Host: www.google.com\r\n" |
| 1016 "Connection: keep-alive\r\n" | 1013 "Connection: keep-alive\r\n" |
| 1017 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 1014 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 1018 }; | 1015 }; |
| 1019 | 1016 |
| 1020 MockRead data_reads1[] = { | 1017 MockRead data_reads1[] = { |
| 1021 MockRead("HTTP/1.1 401 Unauthorized\r\n"), | 1018 MockRead("HTTP/1.1 401 Unauthorized\r\n"), |
| 1022 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1019 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1023 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1020 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1024 MockRead("Content-Length: 14\r\n\r\n"), | 1021 MockRead("Content-Length: 14\r\n\r\n"), |
| 1025 MockRead("Unauthorized\r\n"), | 1022 MockRead("Unauthorized\r\n"), |
| 1026 | 1023 |
| 1027 // Lastly, the server responds with the actual content. | 1024 // Lastly, the server responds with the actual content. |
| 1028 MockRead("HTTP/1.1 200 OK\r\n"), | 1025 MockRead("HTTP/1.1 200 OK\r\n"), |
| 1029 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1026 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1030 MockRead("Content-Length: 100\r\n\r\n"), | 1027 MockRead("Content-Length: 100\r\n\r\n"), |
| 1031 MockRead(false, net::OK), | 1028 MockRead(false, OK), |
| 1032 }; | 1029 }; |
| 1033 | 1030 |
| 1034 MockSocket data1; | 1031 MockSocket data1; |
| 1035 data1.reads = data_reads1; | 1032 data1.reads = data_reads1; |
| 1036 data1.writes = data_writes1; | 1033 data1.writes = data_writes1; |
| 1037 mock_sockets[0] = &data1; | 1034 mock_sockets[0] = &data1; |
| 1038 mock_sockets[1] = NULL; | 1035 mock_sockets[1] = NULL; |
| 1039 | 1036 |
| 1040 TestCompletionCallback callback1; | 1037 TestCompletionCallback callback1; |
| 1041 | 1038 |
| 1042 int rv = trans->Start(&request, &callback1); | 1039 int rv = trans->Start(&request, &callback1); |
| 1043 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1040 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1044 | 1041 |
| 1045 rv = callback1.WaitForResult(); | 1042 rv = callback1.WaitForResult(); |
| 1046 EXPECT_EQ(net::OK, rv); | 1043 EXPECT_EQ(OK, rv); |
| 1047 | 1044 |
| 1048 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 1045 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1049 EXPECT_FALSE(response == NULL); | 1046 EXPECT_FALSE(response == NULL); |
| 1050 | 1047 |
| 1051 // The password prompt info should have been set in response->auth_challenge. | 1048 // The password prompt info should have been set in response->auth_challenge. |
| 1052 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1049 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1053 | 1050 |
| 1054 // TODO(eroman): this should really include the effective port (80) | 1051 // TODO(eroman): this should really include the effective port (80) |
| 1055 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 1052 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 1056 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 1053 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1057 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 1054 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1058 | 1055 |
| 1059 TestCompletionCallback callback2; | 1056 TestCompletionCallback callback2; |
| 1060 | 1057 |
| 1061 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); | 1058 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); |
| 1062 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1059 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1063 | 1060 |
| 1064 rv = callback2.WaitForResult(); | 1061 rv = callback2.WaitForResult(); |
| 1065 EXPECT_EQ(net::OK, rv); | 1062 EXPECT_EQ(OK, rv); |
| 1066 | 1063 |
| 1067 response = trans->GetResponseInfo(); | 1064 response = trans->GetResponseInfo(); |
| 1068 EXPECT_FALSE(response == NULL); | 1065 EXPECT_FALSE(response == NULL); |
| 1069 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 1066 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1070 EXPECT_EQ(100, response->headers->GetContentLength()); | 1067 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 1071 } | 1068 } |
| 1072 | 1069 |
| 1073 // Test the request-challenge-retry sequence for basic auth, over a keep-alive | 1070 // Test the request-challenge-retry sequence for basic auth, over a keep-alive |
| 1074 // connection and with no response body to drain. | 1071 // connection and with no response body to drain. |
| 1075 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { | 1072 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) { |
| 1076 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 1073 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 1077 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1074 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1078 CreateSession(proxy_service.get()), &mock_socket_factory)); | 1075 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 1079 | 1076 |
| 1080 net::HttpRequestInfo request; | 1077 HttpRequestInfo request; |
| 1081 request.method = "GET"; | 1078 request.method = "GET"; |
| 1082 request.url = GURL("http://www.google.com/"); | 1079 request.url = GURL("http://www.google.com/"); |
| 1083 request.load_flags = 0; | 1080 request.load_flags = 0; |
| 1084 | 1081 |
| 1085 MockWrite data_writes1[] = { | 1082 MockWrite data_writes1[] = { |
| 1086 MockWrite("GET / HTTP/1.1\r\n" | 1083 MockWrite("GET / HTTP/1.1\r\n" |
| 1087 "Host: www.google.com\r\n" | 1084 "Host: www.google.com\r\n" |
| 1088 "Connection: keep-alive\r\n\r\n"), | 1085 "Connection: keep-alive\r\n\r\n"), |
| 1089 | 1086 |
| 1090 // After calling trans->RestartWithAuth(), this is the request we should | 1087 // After calling trans->RestartWithAuth(), this is the request we should |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1102 | 1099 |
| 1103 MockRead data_reads1[] = { | 1100 MockRead data_reads1[] = { |
| 1104 MockRead("HTTP/1.1 401 Unauthorized\r\n"), | 1101 MockRead("HTTP/1.1 401 Unauthorized\r\n"), |
| 1105 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1102 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1106 MockRead("Content-Length: 0\r\n\r\n"), | 1103 MockRead("Content-Length: 0\r\n\r\n"), |
| 1107 | 1104 |
| 1108 // Lastly, the server responds with the actual content. | 1105 // Lastly, the server responds with the actual content. |
| 1109 MockRead("HTTP/1.1 200 OK\r\n"), | 1106 MockRead("HTTP/1.1 200 OK\r\n"), |
| 1110 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1107 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1111 MockRead("Content-Length: 100\r\n\r\n"), | 1108 MockRead("Content-Length: 100\r\n\r\n"), |
| 1112 MockRead(false, net::OK), | 1109 MockRead(false, OK), |
| 1113 }; | 1110 }; |
| 1114 | 1111 |
| 1115 MockSocket data1; | 1112 MockSocket data1; |
| 1116 data1.reads = data_reads1; | 1113 data1.reads = data_reads1; |
| 1117 data1.writes = data_writes1; | 1114 data1.writes = data_writes1; |
| 1118 mock_sockets[0] = &data1; | 1115 mock_sockets[0] = &data1; |
| 1119 mock_sockets[1] = NULL; | 1116 mock_sockets[1] = NULL; |
| 1120 | 1117 |
| 1121 TestCompletionCallback callback1; | 1118 TestCompletionCallback callback1; |
| 1122 | 1119 |
| 1123 int rv = trans->Start(&request, &callback1); | 1120 int rv = trans->Start(&request, &callback1); |
| 1124 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1121 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1125 | 1122 |
| 1126 rv = callback1.WaitForResult(); | 1123 rv = callback1.WaitForResult(); |
| 1127 EXPECT_EQ(net::OK, rv); | 1124 EXPECT_EQ(OK, rv); |
| 1128 | 1125 |
| 1129 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 1126 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1130 EXPECT_FALSE(response == NULL); | 1127 EXPECT_FALSE(response == NULL); |
| 1131 | 1128 |
| 1132 // The password prompt info should have been set in response->auth_challenge. | 1129 // The password prompt info should have been set in response->auth_challenge. |
| 1133 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1130 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1134 | 1131 |
| 1135 // TODO(eroman): this should really include the effective port (80) | 1132 // TODO(eroman): this should really include the effective port (80) |
| 1136 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 1133 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 1137 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 1134 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1138 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 1135 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1139 | 1136 |
| 1140 TestCompletionCallback callback2; | 1137 TestCompletionCallback callback2; |
| 1141 | 1138 |
| 1142 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); | 1139 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); |
| 1143 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1140 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1144 | 1141 |
| 1145 rv = callback2.WaitForResult(); | 1142 rv = callback2.WaitForResult(); |
| 1146 EXPECT_EQ(net::OK, rv); | 1143 EXPECT_EQ(OK, rv); |
| 1147 | 1144 |
| 1148 response = trans->GetResponseInfo(); | 1145 response = trans->GetResponseInfo(); |
| 1149 EXPECT_FALSE(response == NULL); | 1146 EXPECT_FALSE(response == NULL); |
| 1150 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 1147 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1151 EXPECT_EQ(100, response->headers->GetContentLength()); | 1148 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 1152 } | 1149 } |
| 1153 | 1150 |
| 1154 // Test the request-challenge-retry sequence for basic auth, over a keep-alive | 1151 // Test the request-challenge-retry sequence for basic auth, over a keep-alive |
| 1155 // connection and with a large response body to drain. | 1152 // connection and with a large response body to drain. |
| 1156 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { | 1153 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) { |
| 1157 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 1154 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 1158 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1155 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1159 CreateSession(proxy_service.get()), &mock_socket_factory)); | 1156 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 1160 | 1157 |
| 1161 net::HttpRequestInfo request; | 1158 HttpRequestInfo request; |
| 1162 request.method = "GET"; | 1159 request.method = "GET"; |
| 1163 request.url = GURL("http://www.google.com/"); | 1160 request.url = GURL("http://www.google.com/"); |
| 1164 request.load_flags = 0; | 1161 request.load_flags = 0; |
| 1165 | 1162 |
| 1166 MockWrite data_writes1[] = { | 1163 MockWrite data_writes1[] = { |
| 1167 MockWrite("GET / HTTP/1.1\r\n" | 1164 MockWrite("GET / HTTP/1.1\r\n" |
| 1168 "Host: www.google.com\r\n" | 1165 "Host: www.google.com\r\n" |
| 1169 "Connection: keep-alive\r\n\r\n"), | 1166 "Connection: keep-alive\r\n\r\n"), |
| 1170 | 1167 |
| 1171 // After calling trans->RestartWithAuth(), this is the request we should | 1168 // After calling trans->RestartWithAuth(), this is the request we should |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1186 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1183 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1187 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1184 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1188 // 5134 = 12 + 5 * 1024 + 2 | 1185 // 5134 = 12 + 5 * 1024 + 2 |
| 1189 MockRead("Content-Length: 5134\r\n\r\n"), | 1186 MockRead("Content-Length: 5134\r\n\r\n"), |
| 1190 MockRead(true, large_body_string.data(), large_body_string.size()), | 1187 MockRead(true, large_body_string.data(), large_body_string.size()), |
| 1191 | 1188 |
| 1192 // Lastly, the server responds with the actual content. | 1189 // Lastly, the server responds with the actual content. |
| 1193 MockRead("HTTP/1.1 200 OK\r\n"), | 1190 MockRead("HTTP/1.1 200 OK\r\n"), |
| 1194 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1191 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1195 MockRead("Content-Length: 100\r\n\r\n"), | 1192 MockRead("Content-Length: 100\r\n\r\n"), |
| 1196 MockRead(false, net::OK), | 1193 MockRead(false, OK), |
| 1197 }; | 1194 }; |
| 1198 | 1195 |
| 1199 MockSocket data1; | 1196 MockSocket data1; |
| 1200 data1.reads = data_reads1; | 1197 data1.reads = data_reads1; |
| 1201 data1.writes = data_writes1; | 1198 data1.writes = data_writes1; |
| 1202 mock_sockets[0] = &data1; | 1199 mock_sockets[0] = &data1; |
| 1203 mock_sockets[1] = NULL; | 1200 mock_sockets[1] = NULL; |
| 1204 | 1201 |
| 1205 TestCompletionCallback callback1; | 1202 TestCompletionCallback callback1; |
| 1206 | 1203 |
| 1207 int rv = trans->Start(&request, &callback1); | 1204 int rv = trans->Start(&request, &callback1); |
| 1208 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1205 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1209 | 1206 |
| 1210 rv = callback1.WaitForResult(); | 1207 rv = callback1.WaitForResult(); |
| 1211 EXPECT_EQ(net::OK, rv); | 1208 EXPECT_EQ(OK, rv); |
| 1212 | 1209 |
| 1213 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 1210 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1214 EXPECT_FALSE(response == NULL); | 1211 EXPECT_FALSE(response == NULL); |
| 1215 | 1212 |
| 1216 // The password prompt info should have been set in response->auth_challenge. | 1213 // The password prompt info should have been set in response->auth_challenge. |
| 1217 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1214 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1218 | 1215 |
| 1219 // TODO(eroman): this should really include the effective port (80) | 1216 // TODO(eroman): this should really include the effective port (80) |
| 1220 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 1217 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 1221 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 1218 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1222 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 1219 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1223 | 1220 |
| 1224 TestCompletionCallback callback2; | 1221 TestCompletionCallback callback2; |
| 1225 | 1222 |
| 1226 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); | 1223 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); |
| 1227 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1224 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1228 | 1225 |
| 1229 rv = callback2.WaitForResult(); | 1226 rv = callback2.WaitForResult(); |
| 1230 EXPECT_EQ(net::OK, rv); | 1227 EXPECT_EQ(OK, rv); |
| 1231 | 1228 |
| 1232 response = trans->GetResponseInfo(); | 1229 response = trans->GetResponseInfo(); |
| 1233 EXPECT_FALSE(response == NULL); | 1230 EXPECT_FALSE(response == NULL); |
| 1234 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 1231 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1235 EXPECT_EQ(100, response->headers->GetContentLength()); | 1232 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 1236 } | 1233 } |
| 1237 | 1234 |
| 1238 // Test the request-challenge-retry sequence for basic auth, over a keep-alive | 1235 // Test the request-challenge-retry sequence for basic auth, over a keep-alive |
| 1239 // proxy connection, when setting up an SSL tunnel. | 1236 // proxy connection, when setting up an SSL tunnel. |
| 1240 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { | 1237 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { |
| 1241 // Configure against proxy server "myproxy:70". | 1238 // Configure against proxy server "myproxy:70". |
| 1242 scoped_ptr<net::ProxyService> proxy_service( | 1239 scoped_ptr<ProxyService> proxy_service( |
| 1243 CreateFixedProxyService("myproxy:70")); | 1240 CreateFixedProxyService("myproxy:70")); |
| 1244 | 1241 |
| 1245 scoped_refptr<net::HttpNetworkSession> session( | 1242 scoped_refptr<HttpNetworkSession> session( |
| 1246 CreateSession(proxy_service.get())); | 1243 CreateSession(proxy_service.get())); |
| 1247 | 1244 |
| 1248 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1245 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1249 session.get(), &mock_socket_factory)); | 1246 session.get(), &mock_socket_factory)); |
| 1250 | 1247 |
| 1251 net::HttpRequestInfo request; | 1248 HttpRequestInfo request; |
| 1252 request.method = "GET"; | 1249 request.method = "GET"; |
| 1253 request.url = GURL("https://www.google.com/"); | 1250 request.url = GURL("https://www.google.com/"); |
| 1254 request.load_flags = 0; | 1251 request.load_flags = 0; |
| 1255 | 1252 |
| 1256 // Since we have proxy, should try to establish tunnel. | 1253 // Since we have proxy, should try to establish tunnel. |
| 1257 MockWrite data_writes1[] = { | 1254 MockWrite data_writes1[] = { |
| 1258 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | 1255 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 1259 "Host: www.google.com\r\n\r\n"), | 1256 "Host: www.google.com\r\n\r\n"), |
| 1260 | 1257 |
| 1261 // After calling trans->RestartWithAuth(), this is the request we should | 1258 // After calling trans->RestartWithAuth(), this is the request we should |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1272 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), | 1269 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), |
| 1273 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1270 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1274 MockRead("Content-Length: 10\r\n\r\n"), | 1271 MockRead("Content-Length: 10\r\n\r\n"), |
| 1275 MockRead("0123456789"), | 1272 MockRead("0123456789"), |
| 1276 | 1273 |
| 1277 // Wrong credentials (wrong password). | 1274 // Wrong credentials (wrong password). |
| 1278 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), | 1275 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), |
| 1279 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1276 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1280 MockRead("Content-Length: 10\r\n\r\n"), | 1277 MockRead("Content-Length: 10\r\n\r\n"), |
| 1281 // No response body because the test stops reading here. | 1278 // No response body because the test stops reading here. |
| 1282 MockRead(false, net::ERR_UNEXPECTED), // Should not be reached. | 1279 MockRead(false, ERR_UNEXPECTED), // Should not be reached. |
| 1283 }; | 1280 }; |
| 1284 | 1281 |
| 1285 MockSocket data1; | 1282 MockSocket data1; |
| 1286 data1.writes = data_writes1; | 1283 data1.writes = data_writes1; |
| 1287 data1.reads = data_reads1; | 1284 data1.reads = data_reads1; |
| 1288 mock_sockets[0] = &data1; | 1285 mock_sockets[0] = &data1; |
| 1289 mock_sockets[1] = NULL; | 1286 mock_sockets[1] = NULL; |
| 1290 | 1287 |
| 1291 TestCompletionCallback callback1; | 1288 TestCompletionCallback callback1; |
| 1292 | 1289 |
| 1293 int rv = trans->Start(&request, &callback1); | 1290 int rv = trans->Start(&request, &callback1); |
| 1294 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1291 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1295 | 1292 |
| 1296 rv = callback1.WaitForResult(); | 1293 rv = callback1.WaitForResult(); |
| 1297 EXPECT_EQ(net::OK, rv); | 1294 EXPECT_EQ(OK, rv); |
| 1298 | 1295 |
| 1299 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 1296 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1300 EXPECT_FALSE(response == NULL); | 1297 EXPECT_FALSE(response == NULL); |
| 1301 | 1298 |
| 1302 EXPECT_TRUE(response->headers->IsKeepAlive()); | 1299 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 1303 EXPECT_EQ(407, response->headers->response_code()); | 1300 EXPECT_EQ(407, response->headers->response_code()); |
| 1304 EXPECT_EQ(10, response->headers->GetContentLength()); | 1301 EXPECT_EQ(10, response->headers->GetContentLength()); |
| 1305 EXPECT_TRUE(net::HttpVersion(1, 1) == response->headers->GetHttpVersion()); | 1302 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 1306 | 1303 |
| 1307 // The password prompt info should have been set in response->auth_challenge. | 1304 // The password prompt info should have been set in response->auth_challenge. |
| 1308 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1305 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1309 | 1306 |
| 1310 // TODO(eroman): this should really include the effective port (80) | 1307 // TODO(eroman): this should really include the effective port (80) |
| 1311 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host); | 1308 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host); |
| 1312 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 1309 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1313 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 1310 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1314 | 1311 |
| 1315 TestCompletionCallback callback2; | 1312 TestCompletionCallback callback2; |
| 1316 | 1313 |
| 1317 // Wrong password (should be "bar"). | 1314 // Wrong password (should be "bar"). |
| 1318 rv = trans->RestartWithAuth(L"foo", L"baz", &callback2); | 1315 rv = trans->RestartWithAuth(L"foo", L"baz", &callback2); |
| 1319 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1316 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1320 | 1317 |
| 1321 rv = callback2.WaitForResult(); | 1318 rv = callback2.WaitForResult(); |
| 1322 EXPECT_EQ(net::OK, rv); | 1319 EXPECT_EQ(OK, rv); |
| 1323 | 1320 |
| 1324 response = trans->GetResponseInfo(); | 1321 response = trans->GetResponseInfo(); |
| 1325 EXPECT_FALSE(response == NULL); | 1322 EXPECT_FALSE(response == NULL); |
| 1326 | 1323 |
| 1327 EXPECT_TRUE(response->headers->IsKeepAlive()); | 1324 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 1328 EXPECT_EQ(407, response->headers->response_code()); | 1325 EXPECT_EQ(407, response->headers->response_code()); |
| 1329 EXPECT_EQ(10, response->headers->GetContentLength()); | 1326 EXPECT_EQ(10, response->headers->GetContentLength()); |
| 1330 EXPECT_TRUE(net::HttpVersion(1, 1) == response->headers->GetHttpVersion()); | 1327 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 1331 | 1328 |
| 1332 // The password prompt info should have been set in response->auth_challenge. | 1329 // The password prompt info should have been set in response->auth_challenge. |
| 1333 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1330 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1334 | 1331 |
| 1335 // TODO(eroman): this should really include the effective port (80) | 1332 // TODO(eroman): this should really include the effective port (80) |
| 1336 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host); | 1333 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host); |
| 1337 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 1334 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1338 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 1335 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1339 } | 1336 } |
| 1340 | 1337 |
| 1341 // Test that we don't read the response body when we fail to establish a tunnel, | 1338 // Test that we don't read the response body when we fail to establish a tunnel, |
| 1342 // even if the user cancels the proxy's auth attempt. | 1339 // even if the user cancels the proxy's auth attempt. |
| 1343 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { | 1340 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { |
| 1344 // Configure against proxy server "myproxy:70". | 1341 // Configure against proxy server "myproxy:70". |
| 1345 scoped_ptr<net::ProxyService> proxy_service( | 1342 scoped_ptr<ProxyService> proxy_service( |
| 1346 CreateFixedProxyService("myproxy:70")); | 1343 CreateFixedProxyService("myproxy:70")); |
| 1347 | 1344 |
| 1348 scoped_refptr<net::HttpNetworkSession> session( | 1345 scoped_refptr<HttpNetworkSession> session( |
| 1349 CreateSession(proxy_service.get())); | 1346 CreateSession(proxy_service.get())); |
| 1350 | 1347 |
| 1351 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1348 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1352 session.get(), &mock_socket_factory)); | 1349 session.get(), &mock_socket_factory)); |
| 1353 | 1350 |
| 1354 net::HttpRequestInfo request; | 1351 HttpRequestInfo request; |
| 1355 request.method = "GET"; | 1352 request.method = "GET"; |
| 1356 request.url = GURL("https://www.google.com/"); | 1353 request.url = GURL("https://www.google.com/"); |
| 1357 request.load_flags = 0; | 1354 request.load_flags = 0; |
| 1358 | 1355 |
| 1359 // Since we have proxy, should try to establish tunnel. | 1356 // Since we have proxy, should try to establish tunnel. |
| 1360 MockWrite data_writes[] = { | 1357 MockWrite data_writes[] = { |
| 1361 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | 1358 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 1362 "Host: www.google.com\r\n\r\n"), | 1359 "Host: www.google.com\r\n\r\n"), |
| 1363 }; | 1360 }; |
| 1364 | 1361 |
| 1365 // The proxy responds to the connect with a 407. | 1362 // The proxy responds to the connect with a 407. |
| 1366 MockRead data_reads[] = { | 1363 MockRead data_reads[] = { |
| 1367 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), | 1364 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), |
| 1368 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1365 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1369 MockRead("Content-Length: 10\r\n\r\n"), | 1366 MockRead("Content-Length: 10\r\n\r\n"), |
| 1370 MockRead(false, net::ERR_UNEXPECTED), // Should not be reached. | 1367 MockRead(false, ERR_UNEXPECTED), // Should not be reached. |
| 1371 }; | 1368 }; |
| 1372 | 1369 |
| 1373 MockSocket data; | 1370 MockSocket data; |
| 1374 data.writes = data_writes; | 1371 data.writes = data_writes; |
| 1375 data.reads = data_reads; | 1372 data.reads = data_reads; |
| 1376 mock_sockets[0] = &data; | 1373 mock_sockets[0] = &data; |
| 1377 mock_sockets[1] = NULL; | 1374 mock_sockets[1] = NULL; |
| 1378 | 1375 |
| 1379 TestCompletionCallback callback; | 1376 TestCompletionCallback callback; |
| 1380 | 1377 |
| 1381 int rv = trans->Start(&request, &callback); | 1378 int rv = trans->Start(&request, &callback); |
| 1382 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1379 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1383 | 1380 |
| 1384 rv = callback.WaitForResult(); | 1381 rv = callback.WaitForResult(); |
| 1385 EXPECT_EQ(net::OK, rv); | 1382 EXPECT_EQ(OK, rv); |
| 1386 | 1383 |
| 1387 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 1384 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1388 EXPECT_FALSE(response == NULL); | 1385 EXPECT_FALSE(response == NULL); |
| 1389 | 1386 |
| 1390 EXPECT_TRUE(response->headers->IsKeepAlive()); | 1387 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 1391 EXPECT_EQ(407, response->headers->response_code()); | 1388 EXPECT_EQ(407, response->headers->response_code()); |
| 1392 EXPECT_EQ(10, response->headers->GetContentLength()); | 1389 EXPECT_EQ(10, response->headers->GetContentLength()); |
| 1393 EXPECT_TRUE(net::HttpVersion(1, 1) == response->headers->GetHttpVersion()); | 1390 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 1394 | 1391 |
| 1395 std::string response_data; | 1392 std::string response_data; |
| 1396 rv = ReadTransaction(trans.get(), &response_data); | 1393 rv = ReadTransaction(trans.get(), &response_data); |
| 1397 EXPECT_EQ(net::ERR_TUNNEL_CONNECTION_FAILED, rv); | 1394 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); |
| 1398 } | 1395 } |
| 1399 | 1396 |
| 1400 static void ConnectStatusHelperWithExpectedStatus( | 1397 static void ConnectStatusHelperWithExpectedStatus( |
| 1401 const MockRead& status, int expected_status) { | 1398 const MockRead& status, int expected_status) { |
| 1402 // Configure against proxy server "myproxy:70". | 1399 // Configure against proxy server "myproxy:70". |
| 1403 scoped_ptr<net::ProxyService> proxy_service( | 1400 scoped_ptr<ProxyService> proxy_service( |
| 1404 CreateFixedProxyService("myproxy:70")); | 1401 CreateFixedProxyService("myproxy:70")); |
| 1405 | 1402 |
| 1406 scoped_refptr<net::HttpNetworkSession> session( | 1403 scoped_refptr<HttpNetworkSession> session( |
| 1407 CreateSession(proxy_service.get())); | 1404 CreateSession(proxy_service.get())); |
| 1408 | 1405 |
| 1409 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1406 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1410 session.get(), &mock_socket_factory)); | 1407 session.get(), &mock_socket_factory)); |
| 1411 | 1408 |
| 1412 net::HttpRequestInfo request; | 1409 HttpRequestInfo request; |
| 1413 request.method = "GET"; | 1410 request.method = "GET"; |
| 1414 request.url = GURL("https://www.google.com/"); | 1411 request.url = GURL("https://www.google.com/"); |
| 1415 request.load_flags = 0; | 1412 request.load_flags = 0; |
| 1416 | 1413 |
| 1417 // Since we have proxy, should try to establish tunnel. | 1414 // Since we have proxy, should try to establish tunnel. |
| 1418 MockWrite data_writes[] = { | 1415 MockWrite data_writes[] = { |
| 1419 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | 1416 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 1420 "Host: www.google.com\r\n\r\n"), | 1417 "Host: www.google.com\r\n\r\n"), |
| 1421 }; | 1418 }; |
| 1422 | 1419 |
| 1423 MockRead data_reads[] = { | 1420 MockRead data_reads[] = { |
| 1424 status, | 1421 status, |
| 1425 MockRead("Content-Length: 10\r\n\r\n"), | 1422 MockRead("Content-Length: 10\r\n\r\n"), |
| 1426 // No response body because the test stops reading here. | 1423 // No response body because the test stops reading here. |
| 1427 MockRead(false, net::ERR_UNEXPECTED), // Should not be reached. | 1424 MockRead(false, ERR_UNEXPECTED), // Should not be reached. |
| 1428 }; | 1425 }; |
| 1429 | 1426 |
| 1430 MockSocket data; | 1427 MockSocket data; |
| 1431 data.writes = data_writes; | 1428 data.writes = data_writes; |
| 1432 data.reads = data_reads; | 1429 data.reads = data_reads; |
| 1433 mock_sockets[0] = &data; | 1430 mock_sockets[0] = &data; |
| 1434 mock_sockets[1] = NULL; | 1431 mock_sockets[1] = NULL; |
| 1435 | 1432 |
| 1436 TestCompletionCallback callback; | 1433 TestCompletionCallback callback; |
| 1437 | 1434 |
| 1438 int rv = trans->Start(&request, &callback); | 1435 int rv = trans->Start(&request, &callback); |
| 1439 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1436 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1440 | 1437 |
| 1441 rv = callback.WaitForResult(); | 1438 rv = callback.WaitForResult(); |
| 1442 EXPECT_EQ(expected_status, rv); | 1439 EXPECT_EQ(expected_status, rv); |
| 1443 } | 1440 } |
| 1444 | 1441 |
| 1445 static void ConnectStatusHelper(const MockRead& status) { | 1442 static void ConnectStatusHelper(const MockRead& status) { |
| 1446 ConnectStatusHelperWithExpectedStatus( | 1443 ConnectStatusHelperWithExpectedStatus( |
| 1447 status, net::ERR_TUNNEL_CONNECTION_FAILED); | 1444 status, ERR_TUNNEL_CONNECTION_FAILED); |
| 1448 } | 1445 } |
| 1449 | 1446 |
| 1450 TEST_F(HttpNetworkTransactionTest, ConnectStatus100) { | 1447 TEST_F(HttpNetworkTransactionTest, ConnectStatus100) { |
| 1451 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n")); | 1448 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n")); |
| 1452 } | 1449 } |
| 1453 | 1450 |
| 1454 TEST_F(HttpNetworkTransactionTest, ConnectStatus101) { | 1451 TEST_F(HttpNetworkTransactionTest, ConnectStatus101) { |
| 1455 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n")); | 1452 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n")); |
| 1456 } | 1453 } |
| 1457 | 1454 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1536 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n")); | 1533 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n")); |
| 1537 } | 1534 } |
| 1538 | 1535 |
| 1539 TEST_F(HttpNetworkTransactionTest, ConnectStatus406) { | 1536 TEST_F(HttpNetworkTransactionTest, ConnectStatus406) { |
| 1540 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n")); | 1537 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n")); |
| 1541 } | 1538 } |
| 1542 | 1539 |
| 1543 TEST_F(HttpNetworkTransactionTest, ConnectStatus407) { | 1540 TEST_F(HttpNetworkTransactionTest, ConnectStatus407) { |
| 1544 ConnectStatusHelperWithExpectedStatus( | 1541 ConnectStatusHelperWithExpectedStatus( |
| 1545 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), | 1542 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), |
| 1546 net::ERR_PROXY_AUTH_REQUESTED); | 1543 ERR_PROXY_AUTH_REQUESTED); |
| 1547 } | 1544 } |
| 1548 | 1545 |
| 1549 TEST_F(HttpNetworkTransactionTest, ConnectStatus408) { | 1546 TEST_F(HttpNetworkTransactionTest, ConnectStatus408) { |
| 1550 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n")); | 1547 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n")); |
| 1551 } | 1548 } |
| 1552 | 1549 |
| 1553 TEST_F(HttpNetworkTransactionTest, ConnectStatus409) { | 1550 TEST_F(HttpNetworkTransactionTest, ConnectStatus409) { |
| 1554 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n")); | 1551 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n")); |
| 1555 } | 1552 } |
| 1556 | 1553 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 } | 1605 } |
| 1609 | 1606 |
| 1610 TEST_F(HttpNetworkTransactionTest, ConnectStatus505) { | 1607 TEST_F(HttpNetworkTransactionTest, ConnectStatus505) { |
| 1611 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n")); | 1608 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n")); |
| 1612 } | 1609 } |
| 1613 | 1610 |
| 1614 // Test the flow when both the proxy server AND origin server require | 1611 // Test the flow when both the proxy server AND origin server require |
| 1615 // authentication. Again, this uses basic auth for both since that is | 1612 // authentication. Again, this uses basic auth for both since that is |
| 1616 // the simplest to mock. | 1613 // the simplest to mock. |
| 1617 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { | 1614 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { |
| 1618 scoped_ptr<net::ProxyService> proxy_service( | 1615 scoped_ptr<ProxyService> proxy_service( |
| 1619 CreateFixedProxyService("myproxy:70")); | 1616 CreateFixedProxyService("myproxy:70")); |
| 1620 | 1617 |
| 1621 // Configure against proxy server "myproxy:70". | 1618 // Configure against proxy server "myproxy:70". |
| 1622 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1619 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1623 CreateSession(proxy_service.get()), | 1620 CreateSession(proxy_service.get()), |
| 1624 &mock_socket_factory)); | 1621 &mock_socket_factory)); |
| 1625 | 1622 |
| 1626 net::HttpRequestInfo request; | 1623 HttpRequestInfo request; |
| 1627 request.method = "GET"; | 1624 request.method = "GET"; |
| 1628 request.url = GURL("http://www.google.com/"); | 1625 request.url = GURL("http://www.google.com/"); |
| 1629 request.load_flags = 0; | 1626 request.load_flags = 0; |
| 1630 | 1627 |
| 1631 MockWrite data_writes1[] = { | 1628 MockWrite data_writes1[] = { |
| 1632 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | 1629 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 1633 "Host: www.google.com\r\n" | 1630 "Host: www.google.com\r\n" |
| 1634 "Proxy-Connection: keep-alive\r\n\r\n"), | 1631 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 1635 }; | 1632 }; |
| 1636 | 1633 |
| 1637 MockRead data_reads1[] = { | 1634 MockRead data_reads1[] = { |
| 1638 MockRead("HTTP/1.0 407 Unauthorized\r\n"), | 1635 MockRead("HTTP/1.0 407 Unauthorized\r\n"), |
| 1639 // Give a couple authenticate options (only the middle one is actually | 1636 // Give a couple authenticate options (only the middle one is actually |
| 1640 // supported). | 1637 // supported). |
| 1641 MockRead("Proxy-Authenticate: Basic\r\n"), // Malformed | 1638 MockRead("Proxy-Authenticate: Basic\r\n"), // Malformed |
| 1642 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1639 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1643 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), | 1640 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"), |
| 1644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1641 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1645 // Large content-length -- won't matter, as connection will be reset. | 1642 // Large content-length -- won't matter, as connection will be reset. |
| 1646 MockRead("Content-Length: 10000\r\n\r\n"), | 1643 MockRead("Content-Length: 10000\r\n\r\n"), |
| 1647 MockRead(false, net::ERR_FAILED), | 1644 MockRead(false, ERR_FAILED), |
| 1648 }; | 1645 }; |
| 1649 | 1646 |
| 1650 // After calling trans->RestartWithAuth() the first time, this is the | 1647 // After calling trans->RestartWithAuth() the first time, this is the |
| 1651 // request we should be issuing -- the final header line contains the | 1648 // request we should be issuing -- the final header line contains the |
| 1652 // proxy's credentials. | 1649 // proxy's credentials. |
| 1653 MockWrite data_writes2[] = { | 1650 MockWrite data_writes2[] = { |
| 1654 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | 1651 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 1655 "Host: www.google.com\r\n" | 1652 "Host: www.google.com\r\n" |
| 1656 "Proxy-Connection: keep-alive\r\n" | 1653 "Proxy-Connection: keep-alive\r\n" |
| 1657 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 1654 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 1658 }; | 1655 }; |
| 1659 | 1656 |
| 1660 // Now the proxy server lets the request pass through to origin server. | 1657 // Now the proxy server lets the request pass through to origin server. |
| 1661 // The origin server responds with a 401. | 1658 // The origin server responds with a 401. |
| 1662 MockRead data_reads2[] = { | 1659 MockRead data_reads2[] = { |
| 1663 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 1660 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 1664 // Note: We are using the same realm-name as the proxy server. This is | 1661 // Note: We are using the same realm-name as the proxy server. This is |
| 1665 // completely valid, as realms are unique across hosts. | 1662 // completely valid, as realms are unique across hosts. |
| 1666 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 1663 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1667 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1664 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1668 MockRead("Content-Length: 2000\r\n\r\n"), | 1665 MockRead("Content-Length: 2000\r\n\r\n"), |
| 1669 MockRead(false, net::ERR_FAILED), // Won't be reached. | 1666 MockRead(false, ERR_FAILED), // Won't be reached. |
| 1670 }; | 1667 }; |
| 1671 | 1668 |
| 1672 // After calling trans->RestartWithAuth() the second time, we should send | 1669 // After calling trans->RestartWithAuth() the second time, we should send |
| 1673 // the credentials for both the proxy and origin server. | 1670 // the credentials for both the proxy and origin server. |
| 1674 MockWrite data_writes3[] = { | 1671 MockWrite data_writes3[] = { |
| 1675 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" | 1672 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 1676 "Host: www.google.com\r\n" | 1673 "Host: www.google.com\r\n" |
| 1677 "Proxy-Connection: keep-alive\r\n" | 1674 "Proxy-Connection: keep-alive\r\n" |
| 1678 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n" | 1675 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n" |
| 1679 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), | 1676 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), |
| 1680 }; | 1677 }; |
| 1681 | 1678 |
| 1682 // Lastly we get the desired content. | 1679 // Lastly we get the desired content. |
| 1683 MockRead data_reads3[] = { | 1680 MockRead data_reads3[] = { |
| 1684 MockRead("HTTP/1.0 200 OK\r\n"), | 1681 MockRead("HTTP/1.0 200 OK\r\n"), |
| 1685 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | 1682 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1686 MockRead("Content-Length: 100\r\n\r\n"), | 1683 MockRead("Content-Length: 100\r\n\r\n"), |
| 1687 MockRead(false, net::OK), | 1684 MockRead(false, OK), |
| 1688 }; | 1685 }; |
| 1689 | 1686 |
| 1690 MockSocket data1; | 1687 MockSocket data1; |
| 1691 data1.reads = data_reads1; | 1688 data1.reads = data_reads1; |
| 1692 data1.writes = data_writes1; | 1689 data1.writes = data_writes1; |
| 1693 MockSocket data2; | 1690 MockSocket data2; |
| 1694 data2.reads = data_reads2; | 1691 data2.reads = data_reads2; |
| 1695 data2.writes = data_writes2; | 1692 data2.writes = data_writes2; |
| 1696 MockSocket data3; | 1693 MockSocket data3; |
| 1697 data3.reads = data_reads3; | 1694 data3.reads = data_reads3; |
| 1698 data3.writes = data_writes3; | 1695 data3.writes = data_writes3; |
| 1699 mock_sockets[0] = &data1; | 1696 mock_sockets[0] = &data1; |
| 1700 mock_sockets[1] = &data2; | 1697 mock_sockets[1] = &data2; |
| 1701 mock_sockets[2] = &data3; | 1698 mock_sockets[2] = &data3; |
| 1702 mock_sockets[3] = NULL; | 1699 mock_sockets[3] = NULL; |
| 1703 | 1700 |
| 1704 TestCompletionCallback callback1; | 1701 TestCompletionCallback callback1; |
| 1705 | 1702 |
| 1706 int rv = trans->Start(&request, &callback1); | 1703 int rv = trans->Start(&request, &callback1); |
| 1707 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1704 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1708 | 1705 |
| 1709 rv = callback1.WaitForResult(); | 1706 rv = callback1.WaitForResult(); |
| 1710 EXPECT_EQ(net::OK, rv); | 1707 EXPECT_EQ(OK, rv); |
| 1711 | 1708 |
| 1712 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 1709 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1713 EXPECT_FALSE(response == NULL); | 1710 EXPECT_FALSE(response == NULL); |
| 1714 | 1711 |
| 1715 // The password prompt info should have been set in response->auth_challenge. | 1712 // The password prompt info should have been set in response->auth_challenge. |
| 1716 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1713 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1717 | 1714 |
| 1718 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host); | 1715 EXPECT_EQ(L"myproxy:70", response->auth_challenge->host); |
| 1719 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 1716 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1720 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 1717 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1721 | 1718 |
| 1722 TestCompletionCallback callback2; | 1719 TestCompletionCallback callback2; |
| 1723 | 1720 |
| 1724 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); | 1721 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); |
| 1725 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1722 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1726 | 1723 |
| 1727 rv = callback2.WaitForResult(); | 1724 rv = callback2.WaitForResult(); |
| 1728 EXPECT_EQ(net::OK, rv); | 1725 EXPECT_EQ(OK, rv); |
| 1729 | 1726 |
| 1730 response = trans->GetResponseInfo(); | 1727 response = trans->GetResponseInfo(); |
| 1731 EXPECT_FALSE(response == NULL); | 1728 EXPECT_FALSE(response == NULL); |
| 1732 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1729 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1733 | 1730 |
| 1734 // TODO(eroman): this should really include the effective port (80) | 1731 // TODO(eroman): this should really include the effective port (80) |
| 1735 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 1732 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 1736 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 1733 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1737 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 1734 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1738 | 1735 |
| 1739 TestCompletionCallback callback3; | 1736 TestCompletionCallback callback3; |
| 1740 | 1737 |
| 1741 rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback3); | 1738 rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback3); |
| 1742 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1739 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1743 | 1740 |
| 1744 rv = callback3.WaitForResult(); | 1741 rv = callback3.WaitForResult(); |
| 1745 EXPECT_EQ(net::OK, rv); | 1742 EXPECT_EQ(OK, rv); |
| 1746 | 1743 |
| 1747 response = trans->GetResponseInfo(); | 1744 response = trans->GetResponseInfo(); |
| 1748 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 1745 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1749 EXPECT_EQ(100, response->headers->GetContentLength()); | 1746 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 1750 } | 1747 } |
| 1751 | 1748 |
| 1752 // The NTLM authentication unit tests were generated by capturing the HTTP | 1749 // The NTLM authentication unit tests were generated by capturing the HTTP |
| 1753 // requests and responses using Fiddler 2 and inspecting the generated random | 1750 // requests and responses using Fiddler 2 and inspecting the generated random |
| 1754 // bytes in the debugger. | 1751 // bytes in the debugger. |
| 1755 | 1752 |
| 1756 // Enter the correct password and authenticate successfully. | 1753 // Enter the correct password and authenticate successfully. |
| 1757 TEST_F(HttpNetworkTransactionTest, NTLMAuth1) { | 1754 TEST_F(HttpNetworkTransactionTest, NTLMAuth1) { |
| 1758 net::HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, | 1755 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, |
| 1759 MockGetHostName); | 1756 MockGetHostName); |
| 1760 | 1757 |
| 1761 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 1758 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 1762 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1759 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1763 CreateSession(proxy_service.get()), &mock_socket_factory)); | 1760 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 1764 | 1761 |
| 1765 net::HttpRequestInfo request; | 1762 HttpRequestInfo request; |
| 1766 request.method = "GET"; | 1763 request.method = "GET"; |
| 1767 request.url = GURL("http://172.22.68.17/kids/login.aspx"); | 1764 request.url = GURL("http://172.22.68.17/kids/login.aspx"); |
| 1768 request.load_flags = 0; | 1765 request.load_flags = 0; |
| 1769 | 1766 |
| 1770 MockWrite data_writes1[] = { | 1767 MockWrite data_writes1[] = { |
| 1771 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" | 1768 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" |
| 1772 "Host: 172.22.68.17\r\n" | 1769 "Host: 172.22.68.17\r\n" |
| 1773 "Connection: keep-alive\r\n\r\n"), | 1770 "Connection: keep-alive\r\n\r\n"), |
| 1774 }; | 1771 }; |
| 1775 | 1772 |
| 1776 MockRead data_reads1[] = { | 1773 MockRead data_reads1[] = { |
| 1777 MockRead("HTTP/1.1 401 Access Denied\r\n"), | 1774 MockRead("HTTP/1.1 401 Access Denied\r\n"), |
| 1778 // Negotiate and NTLM are often requested together. We only support NTLM. | 1775 // Negotiate and NTLM are often requested together. We only support NTLM. |
| 1779 MockRead("WWW-Authenticate: Negotiate\r\n"), | 1776 MockRead("WWW-Authenticate: Negotiate\r\n"), |
| 1780 MockRead("WWW-Authenticate: NTLM\r\n"), | 1777 MockRead("WWW-Authenticate: NTLM\r\n"), |
| 1781 MockRead("Connection: close\r\n"), | 1778 MockRead("Connection: close\r\n"), |
| 1782 MockRead("Content-Length: 42\r\n"), | 1779 MockRead("Content-Length: 42\r\n"), |
| 1783 MockRead("Content-Type: text/html\r\n\r\n"), | 1780 MockRead("Content-Type: text/html\r\n\r\n"), |
| 1784 // Missing content -- won't matter, as connection will be reset. | 1781 // Missing content -- won't matter, as connection will be reset. |
| 1785 MockRead(false, net::ERR_UNEXPECTED), | 1782 MockRead(false, ERR_UNEXPECTED), |
| 1786 }; | 1783 }; |
| 1787 | 1784 |
| 1788 MockWrite data_writes2[] = { | 1785 MockWrite data_writes2[] = { |
| 1789 // After restarting with a null identity, this is the | 1786 // After restarting with a null identity, this is the |
| 1790 // request we should be issuing -- the final header line contains a Type | 1787 // request we should be issuing -- the final header line contains a Type |
| 1791 // 1 message. | 1788 // 1 message. |
| 1792 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" | 1789 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" |
| 1793 "Host: 172.22.68.17\r\n" | 1790 "Host: 172.22.68.17\r\n" |
| 1794 "Connection: keep-alive\r\n" | 1791 "Connection: keep-alive\r\n" |
| 1795 "Authorization: NTLM " | 1792 "Authorization: NTLM " |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1821 "BtAAAAAAA=\r\n"), | 1818 "BtAAAAAAA=\r\n"), |
| 1822 MockRead("Content-Length: 42\r\n"), | 1819 MockRead("Content-Length: 42\r\n"), |
| 1823 MockRead("Content-Type: text/html\r\n\r\n"), | 1820 MockRead("Content-Type: text/html\r\n\r\n"), |
| 1824 MockRead("You are not authorized to view this page\r\n"), | 1821 MockRead("You are not authorized to view this page\r\n"), |
| 1825 | 1822 |
| 1826 // Lastly we get the desired content. | 1823 // Lastly we get the desired content. |
| 1827 MockRead("HTTP/1.1 200 OK\r\n"), | 1824 MockRead("HTTP/1.1 200 OK\r\n"), |
| 1828 MockRead("Content-Type: text/html; charset=utf-8\r\n"), | 1825 MockRead("Content-Type: text/html; charset=utf-8\r\n"), |
| 1829 MockRead("Content-Length: 13\r\n\r\n"), | 1826 MockRead("Content-Length: 13\r\n\r\n"), |
| 1830 MockRead("Please Login\r\n"), | 1827 MockRead("Please Login\r\n"), |
| 1831 MockRead(false, net::OK), | 1828 MockRead(false, OK), |
| 1832 }; | 1829 }; |
| 1833 | 1830 |
| 1834 MockSocket data1; | 1831 MockSocket data1; |
| 1835 data1.reads = data_reads1; | 1832 data1.reads = data_reads1; |
| 1836 data1.writes = data_writes1; | 1833 data1.writes = data_writes1; |
| 1837 MockSocket data2; | 1834 MockSocket data2; |
| 1838 data2.reads = data_reads2; | 1835 data2.reads = data_reads2; |
| 1839 data2.writes = data_writes2; | 1836 data2.writes = data_writes2; |
| 1840 mock_sockets[0] = &data1; | 1837 mock_sockets[0] = &data1; |
| 1841 mock_sockets[1] = &data2; | 1838 mock_sockets[1] = &data2; |
| 1842 mock_sockets[2] = NULL; | 1839 mock_sockets[2] = NULL; |
| 1843 | 1840 |
| 1844 TestCompletionCallback callback1; | 1841 TestCompletionCallback callback1; |
| 1845 | 1842 |
| 1846 int rv = trans->Start(&request, &callback1); | 1843 int rv = trans->Start(&request, &callback1); |
| 1847 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1844 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1848 | 1845 |
| 1849 rv = callback1.WaitForResult(); | 1846 rv = callback1.WaitForResult(); |
| 1850 EXPECT_EQ(net::OK, rv); | 1847 EXPECT_EQ(OK, rv); |
| 1851 | 1848 |
| 1852 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | 1849 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); |
| 1853 TestCompletionCallback callback2; | 1850 TestCompletionCallback callback2; |
| 1854 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); | 1851 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); |
| 1855 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1852 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1856 rv = callback2.WaitForResult(); | 1853 rv = callback2.WaitForResult(); |
| 1857 EXPECT_EQ(net::OK, rv); | 1854 EXPECT_EQ(OK, rv); |
| 1858 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | 1855 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 1859 | 1856 |
| 1860 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 1857 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1861 EXPECT_FALSE(response == NULL); | 1858 EXPECT_FALSE(response == NULL); |
| 1862 | 1859 |
| 1863 // The password prompt info should have been set in response->auth_challenge. | 1860 // The password prompt info should have been set in response->auth_challenge. |
| 1864 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 1861 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 1865 | 1862 |
| 1866 // TODO(eroman): this should really include the effective port (80) | 1863 // TODO(eroman): this should really include the effective port (80) |
| 1867 EXPECT_EQ(L"172.22.68.17", response->auth_challenge->host); | 1864 EXPECT_EQ(L"172.22.68.17", response->auth_challenge->host); |
| 1868 EXPECT_EQ(L"", response->auth_challenge->realm); | 1865 EXPECT_EQ(L"", response->auth_challenge->realm); |
| 1869 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); | 1866 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); |
| 1870 | 1867 |
| 1871 TestCompletionCallback callback3; | 1868 TestCompletionCallback callback3; |
| 1872 | 1869 |
| 1873 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback3); | 1870 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback3); |
| 1874 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 1871 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1875 | 1872 |
| 1876 rv = callback3.WaitForResult(); | 1873 rv = callback3.WaitForResult(); |
| 1877 EXPECT_EQ(net::OK, rv); | 1874 EXPECT_EQ(OK, rv); |
| 1878 | 1875 |
| 1879 response = trans->GetResponseInfo(); | 1876 response = trans->GetResponseInfo(); |
| 1880 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 1877 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1881 EXPECT_EQ(13, response->headers->GetContentLength()); | 1878 EXPECT_EQ(13, response->headers->GetContentLength()); |
| 1882 } | 1879 } |
| 1883 | 1880 |
| 1884 // Enter a wrong password, and then the correct one. | 1881 // Enter a wrong password, and then the correct one. |
| 1885 TEST_F(HttpNetworkTransactionTest, NTLMAuth2) { | 1882 TEST_F(HttpNetworkTransactionTest, NTLMAuth2) { |
| 1886 net::HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2, | 1883 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2, |
| 1887 MockGetHostName); | 1884 MockGetHostName); |
| 1888 | 1885 |
| 1889 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 1886 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 1890 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 1887 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 1891 CreateSession(proxy_service.get()), &mock_socket_factory)); | 1888 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 1892 | 1889 |
| 1893 net::HttpRequestInfo request; | 1890 HttpRequestInfo request; |
| 1894 request.method = "GET"; | 1891 request.method = "GET"; |
| 1895 request.url = GURL("http://172.22.68.17/kids/login.aspx"); | 1892 request.url = GURL("http://172.22.68.17/kids/login.aspx"); |
| 1896 request.load_flags = 0; | 1893 request.load_flags = 0; |
| 1897 | 1894 |
| 1898 MockWrite data_writes1[] = { | 1895 MockWrite data_writes1[] = { |
| 1899 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" | 1896 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" |
| 1900 "Host: 172.22.68.17\r\n" | 1897 "Host: 172.22.68.17\r\n" |
| 1901 "Connection: keep-alive\r\n\r\n"), | 1898 "Connection: keep-alive\r\n\r\n"), |
| 1902 }; | 1899 }; |
| 1903 | 1900 |
| 1904 MockRead data_reads1[] = { | 1901 MockRead data_reads1[] = { |
| 1905 MockRead("HTTP/1.1 401 Access Denied\r\n"), | 1902 MockRead("HTTP/1.1 401 Access Denied\r\n"), |
| 1906 // Negotiate and NTLM are often requested together. We only support NTLM. | 1903 // Negotiate and NTLM are often requested together. We only support NTLM. |
| 1907 MockRead("WWW-Authenticate: Negotiate\r\n"), | 1904 MockRead("WWW-Authenticate: Negotiate\r\n"), |
| 1908 MockRead("WWW-Authenticate: NTLM\r\n"), | 1905 MockRead("WWW-Authenticate: NTLM\r\n"), |
| 1909 MockRead("Connection: close\r\n"), | 1906 MockRead("Connection: close\r\n"), |
| 1910 MockRead("Content-Length: 42\r\n"), | 1907 MockRead("Content-Length: 42\r\n"), |
| 1911 MockRead("Content-Type: text/html\r\n\r\n"), | 1908 MockRead("Content-Type: text/html\r\n\r\n"), |
| 1912 // Missing content -- won't matter, as connection will be reset. | 1909 // Missing content -- won't matter, as connection will be reset. |
| 1913 MockRead(false, net::ERR_UNEXPECTED), | 1910 MockRead(false, ERR_UNEXPECTED), |
| 1914 }; | 1911 }; |
| 1915 | 1912 |
| 1916 MockWrite data_writes2[] = { | 1913 MockWrite data_writes2[] = { |
| 1917 // After restarting with a null identity, this is the | 1914 // After restarting with a null identity, this is the |
| 1918 // request we should be issuing -- the final header line contains a Type | 1915 // request we should be issuing -- the final header line contains a Type |
| 1919 // 1 message. | 1916 // 1 message. |
| 1920 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" | 1917 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" |
| 1921 "Host: 172.22.68.17\r\n" | 1918 "Host: 172.22.68.17\r\n" |
| 1922 "Connection: keep-alive\r\n" | 1919 "Connection: keep-alive\r\n" |
| 1923 "Authorization: NTLM " | 1920 "Authorization: NTLM " |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1952 MockRead("You are not authorized to view this page\r\n"), | 1949 MockRead("You are not authorized to view this page\r\n"), |
| 1953 | 1950 |
| 1954 // Wrong password. | 1951 // Wrong password. |
| 1955 MockRead("HTTP/1.1 401 Access Denied\r\n"), | 1952 MockRead("HTTP/1.1 401 Access Denied\r\n"), |
| 1956 MockRead("WWW-Authenticate: Negotiate\r\n"), | 1953 MockRead("WWW-Authenticate: Negotiate\r\n"), |
| 1957 MockRead("WWW-Authenticate: NTLM\r\n"), | 1954 MockRead("WWW-Authenticate: NTLM\r\n"), |
| 1958 MockRead("Connection: close\r\n"), | 1955 MockRead("Connection: close\r\n"), |
| 1959 MockRead("Content-Length: 42\r\n"), | 1956 MockRead("Content-Length: 42\r\n"), |
| 1960 MockRead("Content-Type: text/html\r\n\r\n"), | 1957 MockRead("Content-Type: text/html\r\n\r\n"), |
| 1961 // Missing content -- won't matter, as connection will be reset. | 1958 // Missing content -- won't matter, as connection will be reset. |
| 1962 MockRead(false, net::ERR_UNEXPECTED), | 1959 MockRead(false, ERR_UNEXPECTED), |
| 1963 }; | 1960 }; |
| 1964 | 1961 |
| 1965 MockWrite data_writes3[] = { | 1962 MockWrite data_writes3[] = { |
| 1966 // After restarting with a null identity, this is the | 1963 // After restarting with a null identity, this is the |
| 1967 // request we should be issuing -- the final header line contains a Type | 1964 // request we should be issuing -- the final header line contains a Type |
| 1968 // 1 message. | 1965 // 1 message. |
| 1969 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" | 1966 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" |
| 1970 "Host: 172.22.68.17\r\n" | 1967 "Host: 172.22.68.17\r\n" |
| 1971 "Connection: keep-alive\r\n" | 1968 "Connection: keep-alive\r\n" |
| 1972 "Authorization: NTLM " | 1969 "Authorization: NTLM " |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1998 "BtAAAAAAA=\r\n"), | 1995 "BtAAAAAAA=\r\n"), |
| 1999 MockRead("Content-Length: 42\r\n"), | 1996 MockRead("Content-Length: 42\r\n"), |
| 2000 MockRead("Content-Type: text/html\r\n\r\n"), | 1997 MockRead("Content-Type: text/html\r\n\r\n"), |
| 2001 MockRead("You are not authorized to view this page\r\n"), | 1998 MockRead("You are not authorized to view this page\r\n"), |
| 2002 | 1999 |
| 2003 // Lastly we get the desired content. | 2000 // Lastly we get the desired content. |
| 2004 MockRead("HTTP/1.1 200 OK\r\n"), | 2001 MockRead("HTTP/1.1 200 OK\r\n"), |
| 2005 MockRead("Content-Type: text/html; charset=utf-8\r\n"), | 2002 MockRead("Content-Type: text/html; charset=utf-8\r\n"), |
| 2006 MockRead("Content-Length: 13\r\n\r\n"), | 2003 MockRead("Content-Length: 13\r\n\r\n"), |
| 2007 MockRead("Please Login\r\n"), | 2004 MockRead("Please Login\r\n"), |
| 2008 MockRead(false, net::OK), | 2005 MockRead(false, OK), |
| 2009 }; | 2006 }; |
| 2010 | 2007 |
| 2011 MockSocket data1; | 2008 MockSocket data1; |
| 2012 data1.reads = data_reads1; | 2009 data1.reads = data_reads1; |
| 2013 data1.writes = data_writes1; | 2010 data1.writes = data_writes1; |
| 2014 MockSocket data2; | 2011 MockSocket data2; |
| 2015 data2.reads = data_reads2; | 2012 data2.reads = data_reads2; |
| 2016 data2.writes = data_writes2; | 2013 data2.writes = data_writes2; |
| 2017 MockSocket data3; | 2014 MockSocket data3; |
| 2018 data3.reads = data_reads3; | 2015 data3.reads = data_reads3; |
| 2019 data3.writes = data_writes3; | 2016 data3.writes = data_writes3; |
| 2020 mock_sockets[0] = &data1; | 2017 mock_sockets[0] = &data1; |
| 2021 mock_sockets[1] = &data2; | 2018 mock_sockets[1] = &data2; |
| 2022 mock_sockets[2] = &data3; | 2019 mock_sockets[2] = &data3; |
| 2023 mock_sockets[3] = NULL; | 2020 mock_sockets[3] = NULL; |
| 2024 | 2021 |
| 2025 TestCompletionCallback callback1; | 2022 TestCompletionCallback callback1; |
| 2026 | 2023 |
| 2027 int rv = trans->Start(&request, &callback1); | 2024 int rv = trans->Start(&request, &callback1); |
| 2028 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2025 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2029 | 2026 |
| 2030 rv = callback1.WaitForResult(); | 2027 rv = callback1.WaitForResult(); |
| 2031 EXPECT_EQ(net::OK, rv); | 2028 EXPECT_EQ(OK, rv); |
| 2032 | 2029 |
| 2033 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | 2030 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); |
| 2034 TestCompletionCallback callback2; | 2031 TestCompletionCallback callback2; |
| 2035 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); | 2032 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); |
| 2036 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2033 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2037 rv = callback2.WaitForResult(); | 2034 rv = callback2.WaitForResult(); |
| 2038 EXPECT_EQ(net::OK, rv); | 2035 EXPECT_EQ(OK, rv); |
| 2039 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | 2036 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 2040 | 2037 |
| 2041 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2038 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2042 EXPECT_FALSE(response == NULL); | 2039 EXPECT_FALSE(response == NULL); |
| 2043 | 2040 |
| 2044 // The password prompt info should have been set in response->auth_challenge. | 2041 // The password prompt info should have been set in response->auth_challenge. |
| 2045 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 2042 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 2046 | 2043 |
| 2047 // TODO(eroman): this should really include the effective port (80) | 2044 // TODO(eroman): this should really include the effective port (80) |
| 2048 EXPECT_EQ(L"172.22.68.17", response->auth_challenge->host); | 2045 EXPECT_EQ(L"172.22.68.17", response->auth_challenge->host); |
| 2049 EXPECT_EQ(L"", response->auth_challenge->realm); | 2046 EXPECT_EQ(L"", response->auth_challenge->realm); |
| 2050 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); | 2047 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); |
| 2051 | 2048 |
| 2052 TestCompletionCallback callback3; | 2049 TestCompletionCallback callback3; |
| 2053 | 2050 |
| 2054 // Enter the wrong password. | 2051 // Enter the wrong password. |
| 2055 rv = trans->RestartWithAuth(L"testing-ntlm", L"wrongpassword", &callback3); | 2052 rv = trans->RestartWithAuth(L"testing-ntlm", L"wrongpassword", &callback3); |
| 2056 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2053 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2057 | 2054 |
| 2058 rv = callback3.WaitForResult(); | 2055 rv = callback3.WaitForResult(); |
| 2059 EXPECT_EQ(net::OK, rv); | 2056 EXPECT_EQ(OK, rv); |
| 2060 | 2057 |
| 2061 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | 2058 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); |
| 2062 TestCompletionCallback callback4; | 2059 TestCompletionCallback callback4; |
| 2063 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback4); | 2060 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback4); |
| 2064 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2061 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2065 rv = callback4.WaitForResult(); | 2062 rv = callback4.WaitForResult(); |
| 2066 EXPECT_EQ(net::OK, rv); | 2063 EXPECT_EQ(OK, rv); |
| 2067 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | 2064 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 2068 | 2065 |
| 2069 response = trans->GetResponseInfo(); | 2066 response = trans->GetResponseInfo(); |
| 2070 EXPECT_FALSE(response == NULL); | 2067 EXPECT_FALSE(response == NULL); |
| 2071 | 2068 |
| 2072 // The password prompt info should have been set in response->auth_challenge. | 2069 // The password prompt info should have been set in response->auth_challenge. |
| 2073 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 2070 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 2074 | 2071 |
| 2075 // TODO(eroman): this should really include the effective port (80) | 2072 // TODO(eroman): this should really include the effective port (80) |
| 2076 EXPECT_EQ(L"172.22.68.17", response->auth_challenge->host); | 2073 EXPECT_EQ(L"172.22.68.17", response->auth_challenge->host); |
| 2077 EXPECT_EQ(L"", response->auth_challenge->realm); | 2074 EXPECT_EQ(L"", response->auth_challenge->realm); |
| 2078 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); | 2075 EXPECT_EQ(L"ntlm", response->auth_challenge->scheme); |
| 2079 | 2076 |
| 2080 TestCompletionCallback callback5; | 2077 TestCompletionCallback callback5; |
| 2081 | 2078 |
| 2082 // Now enter the right password. | 2079 // Now enter the right password. |
| 2083 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback5); | 2080 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback5); |
| 2084 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2081 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2085 | 2082 |
| 2086 rv = callback5.WaitForResult(); | 2083 rv = callback5.WaitForResult(); |
| 2087 EXPECT_EQ(net::OK, rv); | 2084 EXPECT_EQ(OK, rv); |
| 2088 | 2085 |
| 2089 response = trans->GetResponseInfo(); | 2086 response = trans->GetResponseInfo(); |
| 2090 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2087 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2091 EXPECT_EQ(13, response->headers->GetContentLength()); | 2088 EXPECT_EQ(13, response->headers->GetContentLength()); |
| 2092 } | 2089 } |
| 2093 | 2090 |
| 2094 // Test reading a server response which has only headers, and no body. | 2091 // Test reading a server response which has only headers, and no body. |
| 2095 // After some maximum number of bytes is consumed, the transaction should | 2092 // After some maximum number of bytes is consumed, the transaction should |
| 2096 // fail with ERR_RESPONSE_HEADERS_TOO_BIG. | 2093 // fail with ERR_RESPONSE_HEADERS_TOO_BIG. |
| 2097 TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) { | 2094 TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) { |
| 2098 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 2095 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 2099 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2096 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2100 CreateSession(proxy_service.get()), &mock_socket_factory)); | 2097 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 2101 | 2098 |
| 2102 net::HttpRequestInfo request; | 2099 HttpRequestInfo request; |
| 2103 request.method = "GET"; | 2100 request.method = "GET"; |
| 2104 request.url = GURL("http://www.google.com/"); | 2101 request.url = GURL("http://www.google.com/"); |
| 2105 request.load_flags = 0; | 2102 request.load_flags = 0; |
| 2106 | 2103 |
| 2107 // Respond with 50 kb of headers (we should fail after 32 kb). | 2104 // Respond with 50 kb of headers (we should fail after 32 kb). |
| 2108 std::string large_headers_string; | 2105 std::string large_headers_string; |
| 2109 FillLargeHeadersString(&large_headers_string, 50 * 1024); | 2106 FillLargeHeadersString(&large_headers_string, 50 * 1024); |
| 2110 | 2107 |
| 2111 MockRead data_reads[] = { | 2108 MockRead data_reads[] = { |
| 2112 MockRead("HTTP/1.0 200 OK\r\n"), | 2109 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2113 MockRead(true, large_headers_string.data(), large_headers_string.size()), | 2110 MockRead(true, large_headers_string.data(), large_headers_string.size()), |
| 2114 MockRead("\r\nBODY"), | 2111 MockRead("\r\nBODY"), |
| 2115 MockRead(false, net::OK), | 2112 MockRead(false, OK), |
| 2116 }; | 2113 }; |
| 2117 MockSocket data; | 2114 MockSocket data; |
| 2118 data.reads = data_reads; | 2115 data.reads = data_reads; |
| 2119 mock_sockets[0] = &data; | 2116 mock_sockets[0] = &data; |
| 2120 mock_sockets[1] = NULL; | 2117 mock_sockets[1] = NULL; |
| 2121 | 2118 |
| 2122 TestCompletionCallback callback; | 2119 TestCompletionCallback callback; |
| 2123 | 2120 |
| 2124 int rv = trans->Start(&request, &callback); | 2121 int rv = trans->Start(&request, &callback); |
| 2125 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2122 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2126 | 2123 |
| 2127 rv = callback.WaitForResult(); | 2124 rv = callback.WaitForResult(); |
| 2128 EXPECT_EQ(net::ERR_RESPONSE_HEADERS_TOO_BIG, rv); | 2125 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv); |
| 2129 | 2126 |
| 2130 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2127 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2131 EXPECT_TRUE(response == NULL); | 2128 EXPECT_TRUE(response == NULL); |
| 2132 } | 2129 } |
| 2133 | 2130 |
| 2134 // Make sure that we don't try to reuse a TCPClientSocket when failing to | 2131 // Make sure that we don't try to reuse a TCPClientSocket when failing to |
| 2135 // establish tunnel. | 2132 // establish tunnel. |
| 2136 // http://code.google.com/p/chromium/issues/detail?id=3772 | 2133 // http://code.google.com/p/chromium/issues/detail?id=3772 |
| 2137 TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) { | 2134 TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) { |
| 2138 // Configure against proxy server "myproxy:70". | 2135 // Configure against proxy server "myproxy:70". |
| 2139 scoped_ptr<net::ProxyService> proxy_service( | 2136 scoped_ptr<ProxyService> proxy_service( |
| 2140 CreateFixedProxyService("myproxy:70")); | 2137 CreateFixedProxyService("myproxy:70")); |
| 2141 | 2138 |
| 2142 scoped_refptr<net::HttpNetworkSession> session( | 2139 scoped_refptr<HttpNetworkSession> session( |
| 2143 CreateSession(proxy_service.get())); | 2140 CreateSession(proxy_service.get())); |
| 2144 | 2141 |
| 2145 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2142 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2146 session.get(), &mock_socket_factory)); | 2143 session.get(), &mock_socket_factory)); |
| 2147 | 2144 |
| 2148 net::HttpRequestInfo request; | 2145 HttpRequestInfo request; |
| 2149 request.method = "GET"; | 2146 request.method = "GET"; |
| 2150 request.url = GURL("https://www.google.com/"); | 2147 request.url = GURL("https://www.google.com/"); |
| 2151 request.load_flags = 0; | 2148 request.load_flags = 0; |
| 2152 | 2149 |
| 2153 // Since we have proxy, should try to establish tunnel. | 2150 // Since we have proxy, should try to establish tunnel. |
| 2154 MockWrite data_writes1[] = { | 2151 MockWrite data_writes1[] = { |
| 2155 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | 2152 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 2156 "Host: www.google.com\r\n\r\n"), | 2153 "Host: www.google.com\r\n\r\n"), |
| 2157 }; | 2154 }; |
| 2158 | 2155 |
| 2159 // The proxy responds to the connect with a 404, using a persistent | 2156 // The proxy responds to the connect with a 404, using a persistent |
| 2160 // connection. Usually a proxy would return 501 (not implemented), | 2157 // connection. Usually a proxy would return 501 (not implemented), |
| 2161 // or 200 (tunnel established). | 2158 // or 200 (tunnel established). |
| 2162 MockRead data_reads1[] = { | 2159 MockRead data_reads1[] = { |
| 2163 MockRead("HTTP/1.1 404 Not Found\r\n"), | 2160 MockRead("HTTP/1.1 404 Not Found\r\n"), |
| 2164 MockRead("Content-Length: 10\r\n\r\n"), | 2161 MockRead("Content-Length: 10\r\n\r\n"), |
| 2165 MockRead(false, net::ERR_UNEXPECTED), // Should not be reached. | 2162 MockRead(false, ERR_UNEXPECTED), // Should not be reached. |
| 2166 }; | 2163 }; |
| 2167 | 2164 |
| 2168 MockSocket data1; | 2165 MockSocket data1; |
| 2169 data1.writes = data_writes1; | 2166 data1.writes = data_writes1; |
| 2170 data1.reads = data_reads1; | 2167 data1.reads = data_reads1; |
| 2171 mock_sockets[0] = &data1; | 2168 mock_sockets[0] = &data1; |
| 2172 mock_sockets[1] = NULL; | 2169 mock_sockets[1] = NULL; |
| 2173 | 2170 |
| 2174 TestCompletionCallback callback1; | 2171 TestCompletionCallback callback1; |
| 2175 | 2172 |
| 2176 int rv = trans->Start(&request, &callback1); | 2173 int rv = trans->Start(&request, &callback1); |
| 2177 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2174 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2178 | 2175 |
| 2179 rv = callback1.WaitForResult(); | 2176 rv = callback1.WaitForResult(); |
| 2180 EXPECT_EQ(net::ERR_TUNNEL_CONNECTION_FAILED, rv); | 2177 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); |
| 2181 | 2178 |
| 2182 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2179 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2183 EXPECT_TRUE(response == NULL); | 2180 EXPECT_TRUE(response == NULL); |
| 2184 | 2181 |
| 2185 // Empty the current queue. This is necessary because idle sockets are | 2182 // Empty the current queue. This is necessary because idle sockets are |
| 2186 // added to the connection pool asynchronously with a PostTask. | 2183 // added to the connection pool asynchronously with a PostTask. |
| 2187 MessageLoop::current()->RunAllPending(); | 2184 MessageLoop::current()->RunAllPending(); |
| 2188 | 2185 |
| 2189 // We now check to make sure the TCPClientSocket was not added back to | 2186 // We now check to make sure the TCPClientSocket was not added back to |
| 2190 // the pool. | 2187 // the pool. |
| 2191 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); | 2188 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); |
| 2192 trans.reset(); | 2189 trans.reset(); |
| 2193 MessageLoop::current()->RunAllPending(); | 2190 MessageLoop::current()->RunAllPending(); |
| 2194 // Make sure that the socket didn't get recycled after calling the destructor. | 2191 // Make sure that the socket didn't get recycled after calling the destructor. |
| 2195 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); | 2192 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); |
| 2196 } | 2193 } |
| 2197 | 2194 |
| 2198 // Make sure that we recycle a socket after reading all of the response body. | 2195 // Make sure that we recycle a socket after reading all of the response body. |
| 2199 TEST_F(HttpNetworkTransactionTest, RecycleSocket) { | 2196 TEST_F(HttpNetworkTransactionTest, RecycleSocket) { |
| 2200 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 2197 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 2201 scoped_refptr<net::HttpNetworkSession> session( | 2198 scoped_refptr<HttpNetworkSession> session( |
| 2202 CreateSession(proxy_service.get())); | 2199 CreateSession(proxy_service.get())); |
| 2203 | 2200 |
| 2204 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2201 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2205 session.get(), &mock_socket_factory)); | 2202 session.get(), &mock_socket_factory)); |
| 2206 | 2203 |
| 2207 net::HttpRequestInfo request; | 2204 HttpRequestInfo request; |
| 2208 request.method = "GET"; | 2205 request.method = "GET"; |
| 2209 request.url = GURL("http://www.google.com/"); | 2206 request.url = GURL("http://www.google.com/"); |
| 2210 request.load_flags = 0; | 2207 request.load_flags = 0; |
| 2211 | 2208 |
| 2212 MockRead data_reads[] = { | 2209 MockRead data_reads[] = { |
| 2213 // A part of the response body is received with the response headers. | 2210 // A part of the response body is received with the response headers. |
| 2214 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"), | 2211 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"), |
| 2215 // The rest of the response body is received in two parts. | 2212 // The rest of the response body is received in two parts. |
| 2216 MockRead("lo"), | 2213 MockRead("lo"), |
| 2217 MockRead(" world"), | 2214 MockRead(" world"), |
| 2218 MockRead("junk"), // Should not be read!! | 2215 MockRead("junk"), // Should not be read!! |
| 2219 MockRead(false, net::OK), | 2216 MockRead(false, OK), |
| 2220 }; | 2217 }; |
| 2221 | 2218 |
| 2222 MockSocket data; | 2219 MockSocket data; |
| 2223 data.reads = data_reads; | 2220 data.reads = data_reads; |
| 2224 mock_sockets[0] = &data; | 2221 mock_sockets[0] = &data; |
| 2225 mock_sockets[1] = NULL; | 2222 mock_sockets[1] = NULL; |
| 2226 | 2223 |
| 2227 TestCompletionCallback callback; | 2224 TestCompletionCallback callback; |
| 2228 | 2225 |
| 2229 int rv = trans->Start(&request, &callback); | 2226 int rv = trans->Start(&request, &callback); |
| 2230 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2227 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2231 | 2228 |
| 2232 rv = callback.WaitForResult(); | 2229 rv = callback.WaitForResult(); |
| 2233 EXPECT_EQ(net::OK, rv); | 2230 EXPECT_EQ(OK, rv); |
| 2234 | 2231 |
| 2235 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2232 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2236 EXPECT_TRUE(response != NULL); | 2233 EXPECT_TRUE(response != NULL); |
| 2237 | 2234 |
| 2238 EXPECT_TRUE(response->headers != NULL); | 2235 EXPECT_TRUE(response->headers != NULL); |
| 2239 std::string status_line = response->headers->GetStatusLine(); | 2236 std::string status_line = response->headers->GetStatusLine(); |
| 2240 EXPECT_EQ("HTTP/1.1 200 OK", status_line); | 2237 EXPECT_EQ("HTTP/1.1 200 OK", status_line); |
| 2241 | 2238 |
| 2242 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); | 2239 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); |
| 2243 | 2240 |
| 2244 std::string response_data; | 2241 std::string response_data; |
| 2245 rv = ReadTransaction(trans.get(), &response_data); | 2242 rv = ReadTransaction(trans.get(), &response_data); |
| 2246 EXPECT_EQ(net::OK, rv); | 2243 EXPECT_EQ(OK, rv); |
| 2247 EXPECT_EQ("hello world", response_data); | 2244 EXPECT_EQ("hello world", response_data); |
| 2248 | 2245 |
| 2249 // Empty the current queue. This is necessary because idle sockets are | 2246 // Empty the current queue. This is necessary because idle sockets are |
| 2250 // added to the connection pool asynchronously with a PostTask. | 2247 // added to the connection pool asynchronously with a PostTask. |
| 2251 MessageLoop::current()->RunAllPending(); | 2248 MessageLoop::current()->RunAllPending(); |
| 2252 | 2249 |
| 2253 // We now check to make sure the socket was added back to the pool. | 2250 // We now check to make sure the socket was added back to the pool. |
| 2254 EXPECT_EQ(1, session->connection_pool()->idle_socket_count()); | 2251 EXPECT_EQ(1, session->connection_pool()->idle_socket_count()); |
| 2255 } | 2252 } |
| 2256 | 2253 |
| 2257 // Make sure that we recycle a socket after a zero-length response. | 2254 // Make sure that we recycle a socket after a zero-length response. |
| 2258 // http://crbug.com/9880 | 2255 // http://crbug.com/9880 |
| 2259 TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { | 2256 TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) { |
| 2260 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 2257 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 2261 scoped_refptr<net::HttpNetworkSession> session( | 2258 scoped_refptr<HttpNetworkSession> session( |
| 2262 CreateSession(proxy_service.get())); | 2259 CreateSession(proxy_service.get())); |
| 2263 | 2260 |
| 2264 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2261 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2265 session.get(), &mock_socket_factory)); | 2262 session.get(), &mock_socket_factory)); |
| 2266 | 2263 |
| 2267 net::HttpRequestInfo request; | 2264 HttpRequestInfo request; |
| 2268 request.method = "GET"; | 2265 request.method = "GET"; |
| 2269 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&" | 2266 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&" |
| 2270 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&" | 2267 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&" |
| 2271 "e=17259,18167,19592,19773,19981,20133,20173,20233&" | 2268 "e=17259,18167,19592,19773,19981,20133,20173,20233&" |
| 2272 "rt=prt.2642,ol.2649,xjs.2951"); | 2269 "rt=prt.2642,ol.2649,xjs.2951"); |
| 2273 request.load_flags = 0; | 2270 request.load_flags = 0; |
| 2274 | 2271 |
| 2275 MockRead data_reads[] = { | 2272 MockRead data_reads[] = { |
| 2276 MockRead("HTTP/1.1 204 No Content\r\n" | 2273 MockRead("HTTP/1.1 204 No Content\r\n" |
| 2277 "Content-Length: 0\r\n" | 2274 "Content-Length: 0\r\n" |
| 2278 "Content-Type: text/html\r\n\r\n"), | 2275 "Content-Type: text/html\r\n\r\n"), |
| 2279 MockRead("junk"), // Should not be read!! | 2276 MockRead("junk"), // Should not be read!! |
| 2280 MockRead(false, net::OK), | 2277 MockRead(false, OK), |
| 2281 }; | 2278 }; |
| 2282 | 2279 |
| 2283 MockSocket data; | 2280 MockSocket data; |
| 2284 data.reads = data_reads; | 2281 data.reads = data_reads; |
| 2285 mock_sockets[0] = &data; | 2282 mock_sockets[0] = &data; |
| 2286 mock_sockets[1] = NULL; | 2283 mock_sockets[1] = NULL; |
| 2287 | 2284 |
| 2288 TestCompletionCallback callback; | 2285 TestCompletionCallback callback; |
| 2289 | 2286 |
| 2290 int rv = trans->Start(&request, &callback); | 2287 int rv = trans->Start(&request, &callback); |
| 2291 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2288 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2292 | 2289 |
| 2293 rv = callback.WaitForResult(); | 2290 rv = callback.WaitForResult(); |
| 2294 EXPECT_EQ(net::OK, rv); | 2291 EXPECT_EQ(OK, rv); |
| 2295 | 2292 |
| 2296 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2293 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2297 EXPECT_TRUE(response != NULL); | 2294 EXPECT_TRUE(response != NULL); |
| 2298 | 2295 |
| 2299 EXPECT_TRUE(response->headers != NULL); | 2296 EXPECT_TRUE(response->headers != NULL); |
| 2300 std::string status_line = response->headers->GetStatusLine(); | 2297 std::string status_line = response->headers->GetStatusLine(); |
| 2301 EXPECT_EQ("HTTP/1.1 204 No Content", status_line); | 2298 EXPECT_EQ("HTTP/1.1 204 No Content", status_line); |
| 2302 | 2299 |
| 2303 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); | 2300 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); |
| 2304 | 2301 |
| 2305 std::string response_data; | 2302 std::string response_data; |
| 2306 rv = ReadTransaction(trans.get(), &response_data); | 2303 rv = ReadTransaction(trans.get(), &response_data); |
| 2307 EXPECT_EQ(net::OK, rv); | 2304 EXPECT_EQ(OK, rv); |
| 2308 EXPECT_EQ("", response_data); | 2305 EXPECT_EQ("", response_data); |
| 2309 | 2306 |
| 2310 // Empty the current queue. This is necessary because idle sockets are | 2307 // Empty the current queue. This is necessary because idle sockets are |
| 2311 // added to the connection pool asynchronously with a PostTask. | 2308 // added to the connection pool asynchronously with a PostTask. |
| 2312 MessageLoop::current()->RunAllPending(); | 2309 MessageLoop::current()->RunAllPending(); |
| 2313 | 2310 |
| 2314 // We now check to make sure the socket was added back to the pool. | 2311 // We now check to make sure the socket was added back to the pool. |
| 2315 EXPECT_EQ(1, session->connection_pool()->idle_socket_count()); | 2312 EXPECT_EQ(1, session->connection_pool()->idle_socket_count()); |
| 2316 } | 2313 } |
| 2317 | 2314 |
| 2318 TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) { | 2315 TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) { |
| 2319 net::HttpRequestInfo request[2]; | 2316 HttpRequestInfo request[2]; |
| 2320 // Transaction 1: a GET request that succeeds. The socket is recycled | 2317 // Transaction 1: a GET request that succeeds. The socket is recycled |
| 2321 // after use. | 2318 // after use. |
| 2322 request[0].method = "GET"; | 2319 request[0].method = "GET"; |
| 2323 request[0].url = GURL("http://www.google.com/"); | 2320 request[0].url = GURL("http://www.google.com/"); |
| 2324 request[0].load_flags = 0; | 2321 request[0].load_flags = 0; |
| 2325 // Transaction 2: a POST request. Reuses the socket kept alive from | 2322 // Transaction 2: a POST request. Reuses the socket kept alive from |
| 2326 // transaction 1. The first attempts fails when writing the POST data. | 2323 // transaction 1. The first attempts fails when writing the POST data. |
| 2327 // This causes the transaction to retry with a new socket. The second | 2324 // This causes the transaction to retry with a new socket. The second |
| 2328 // attempt succeeds. | 2325 // attempt succeeds. |
| 2329 request[1].method = "POST"; | 2326 request[1].method = "POST"; |
| 2330 request[1].url = GURL("http://www.google.com/login.cgi"); | 2327 request[1].url = GURL("http://www.google.com/login.cgi"); |
| 2331 request[1].upload_data = new net::UploadData; | 2328 request[1].upload_data = new UploadData; |
| 2332 request[1].upload_data->AppendBytes("foo", 3); | 2329 request[1].upload_data->AppendBytes("foo", 3); |
| 2333 request[1].load_flags = 0; | 2330 request[1].load_flags = 0; |
| 2334 | 2331 |
| 2335 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 2332 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 2336 scoped_refptr<net::HttpNetworkSession> session = | 2333 scoped_refptr<HttpNetworkSession> session = |
| 2337 CreateSession(proxy_service.get()); | 2334 CreateSession(proxy_service.get()); |
| 2338 | 2335 |
| 2339 // The first socket is used for transaction 1 and the first attempt of | 2336 // The first socket is used for transaction 1 and the first attempt of |
| 2340 // transaction 2. | 2337 // transaction 2. |
| 2341 | 2338 |
| 2342 // The response of transaction 1. | 2339 // The response of transaction 1. |
| 2343 MockRead data_reads1[] = { | 2340 MockRead data_reads1[] = { |
| 2344 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"), | 2341 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"), |
| 2345 MockRead("hello world"), | 2342 MockRead("hello world"), |
| 2346 MockRead(false, net::OK), | 2343 MockRead(false, OK), |
| 2347 }; | 2344 }; |
| 2348 // The mock write results of transaction 1 and the first attempt of | 2345 // The mock write results of transaction 1 and the first attempt of |
| 2349 // transaction 2. | 2346 // transaction 2. |
| 2350 MockWrite data_writes1[] = { | 2347 MockWrite data_writes1[] = { |
| 2351 MockWrite(false, 64), // GET | 2348 MockWrite(false, 64), // GET |
| 2352 MockWrite(false, 93), // POST | 2349 MockWrite(false, 93), // POST |
| 2353 MockWrite(false, net::ERR_CONNECTION_ABORTED), // POST data | 2350 MockWrite(false, ERR_CONNECTION_ABORTED), // POST data |
| 2354 }; | 2351 }; |
| 2355 MockSocket data1; | 2352 MockSocket data1; |
| 2356 data1.reads = data_reads1; | 2353 data1.reads = data_reads1; |
| 2357 data1.writes = data_writes1; | 2354 data1.writes = data_writes1; |
| 2358 | 2355 |
| 2359 // The second socket is used for the second attempt of transaction 2. | 2356 // The second socket is used for the second attempt of transaction 2. |
| 2360 | 2357 |
| 2361 // The response of transaction 2. | 2358 // The response of transaction 2. |
| 2362 MockRead data_reads2[] = { | 2359 MockRead data_reads2[] = { |
| 2363 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"), | 2360 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"), |
| 2364 MockRead("welcome"), | 2361 MockRead("welcome"), |
| 2365 MockRead(false, net::OK), | 2362 MockRead(false, OK), |
| 2366 }; | 2363 }; |
| 2367 // The mock write results of the second attempt of transaction 2. | 2364 // The mock write results of the second attempt of transaction 2. |
| 2368 MockWrite data_writes2[] = { | 2365 MockWrite data_writes2[] = { |
| 2369 MockWrite(false, 93), // POST | 2366 MockWrite(false, 93), // POST |
| 2370 MockWrite(false, 3), // POST data | 2367 MockWrite(false, 3), // POST data |
| 2371 }; | 2368 }; |
| 2372 MockSocket data2; | 2369 MockSocket data2; |
| 2373 data2.reads = data_reads2; | 2370 data2.reads = data_reads2; |
| 2374 data2.writes = data_writes2; | 2371 data2.writes = data_writes2; |
| 2375 | 2372 |
| 2376 mock_sockets[0] = &data1; | 2373 mock_sockets[0] = &data1; |
| 2377 mock_sockets[1] = &data2; | 2374 mock_sockets[1] = &data2; |
| 2378 mock_sockets[2] = NULL; | 2375 mock_sockets[2] = NULL; |
| 2379 | 2376 |
| 2380 const char* kExpectedResponseData[] = { | 2377 const char* kExpectedResponseData[] = { |
| 2381 "hello world", "welcome" | 2378 "hello world", "welcome" |
| 2382 }; | 2379 }; |
| 2383 | 2380 |
| 2384 for (int i = 0; i < 2; ++i) { | 2381 for (int i = 0; i < 2; ++i) { |
| 2385 scoped_ptr<net::HttpTransaction> trans( | 2382 scoped_ptr<HttpTransaction> trans( |
| 2386 new net::HttpNetworkTransaction(session, &mock_socket_factory)); | 2383 new HttpNetworkTransaction(session, &mock_socket_factory)); |
| 2387 | 2384 |
| 2388 TestCompletionCallback callback; | 2385 TestCompletionCallback callback; |
| 2389 | 2386 |
| 2390 int rv = trans->Start(&request[i], &callback); | 2387 int rv = trans->Start(&request[i], &callback); |
| 2391 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2388 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2392 | 2389 |
| 2393 rv = callback.WaitForResult(); | 2390 rv = callback.WaitForResult(); |
| 2394 EXPECT_EQ(net::OK, rv); | 2391 EXPECT_EQ(OK, rv); |
| 2395 | 2392 |
| 2396 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2393 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2397 EXPECT_TRUE(response != NULL); | 2394 EXPECT_TRUE(response != NULL); |
| 2398 | 2395 |
| 2399 EXPECT_TRUE(response->headers != NULL); | 2396 EXPECT_TRUE(response->headers != NULL); |
| 2400 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); | 2397 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 2401 | 2398 |
| 2402 std::string response_data; | 2399 std::string response_data; |
| 2403 rv = ReadTransaction(trans.get(), &response_data); | 2400 rv = ReadTransaction(trans.get(), &response_data); |
| 2404 EXPECT_EQ(net::OK, rv); | 2401 EXPECT_EQ(OK, rv); |
| 2405 EXPECT_EQ(kExpectedResponseData[i], response_data); | 2402 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 2406 } | 2403 } |
| 2407 } | 2404 } |
| 2408 | 2405 |
| 2409 // Test the request-challenge-retry sequence for basic auth when there is | 2406 // Test the request-challenge-retry sequence for basic auth when there is |
| 2410 // an identity in the URL. The request should be sent as normal, but when | 2407 // an identity in the URL. The request should be sent as normal, but when |
| 2411 // it fails the identity from the URL is used to answer the challenge. | 2408 // it fails the identity from the URL is used to answer the challenge. |
| 2412 TEST_F(HttpNetworkTransactionTest, AuthIdentityInUrl) { | 2409 TEST_F(HttpNetworkTransactionTest, AuthIdentityInUrl) { |
| 2413 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 2410 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 2414 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2411 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2415 CreateSession(proxy_service.get()), &mock_socket_factory)); | 2412 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 2416 | 2413 |
| 2417 net::HttpRequestInfo request; | 2414 HttpRequestInfo request; |
| 2418 request.method = "GET"; | 2415 request.method = "GET"; |
| 2419 // Note: the URL has a username:password in it. | 2416 // Note: the URL has a username:password in it. |
| 2420 request.url = GURL("http://foo:bar@www.google.com/"); | 2417 request.url = GURL("http://foo:bar@www.google.com/"); |
| 2421 request.load_flags = 0; | 2418 request.load_flags = 0; |
| 2422 | 2419 |
| 2423 MockWrite data_writes1[] = { | 2420 MockWrite data_writes1[] = { |
| 2424 MockWrite("GET / HTTP/1.1\r\n" | 2421 MockWrite("GET / HTTP/1.1\r\n" |
| 2425 "Host: www.google.com\r\n" | 2422 "Host: www.google.com\r\n" |
| 2426 "Connection: keep-alive\r\n\r\n"), | 2423 "Connection: keep-alive\r\n\r\n"), |
| 2427 }; | 2424 }; |
| 2428 | 2425 |
| 2429 MockRead data_reads1[] = { | 2426 MockRead data_reads1[] = { |
| 2430 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 2427 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2431 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 2428 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2432 MockRead("Content-Length: 10\r\n\r\n"), | 2429 MockRead("Content-Length: 10\r\n\r\n"), |
| 2433 MockRead(false, net::ERR_FAILED), | 2430 MockRead(false, ERR_FAILED), |
| 2434 }; | 2431 }; |
| 2435 | 2432 |
| 2436 // After the challenge above, the transaction will be restarted using the | 2433 // After the challenge above, the transaction will be restarted using the |
| 2437 // identity from the url (foo, bar) to answer the challenge. | 2434 // identity from the url (foo, bar) to answer the challenge. |
| 2438 MockWrite data_writes2[] = { | 2435 MockWrite data_writes2[] = { |
| 2439 MockWrite("GET / HTTP/1.1\r\n" | 2436 MockWrite("GET / HTTP/1.1\r\n" |
| 2440 "Host: www.google.com\r\n" | 2437 "Host: www.google.com\r\n" |
| 2441 "Connection: keep-alive\r\n" | 2438 "Connection: keep-alive\r\n" |
| 2442 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 2439 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 2443 }; | 2440 }; |
| 2444 | 2441 |
| 2445 MockRead data_reads2[] = { | 2442 MockRead data_reads2[] = { |
| 2446 MockRead("HTTP/1.0 200 OK\r\n"), | 2443 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2447 MockRead("Content-Length: 100\r\n\r\n"), | 2444 MockRead("Content-Length: 100\r\n\r\n"), |
| 2448 MockRead(false, net::OK), | 2445 MockRead(false, OK), |
| 2449 }; | 2446 }; |
| 2450 | 2447 |
| 2451 MockSocket data1; | 2448 MockSocket data1; |
| 2452 data1.reads = data_reads1; | 2449 data1.reads = data_reads1; |
| 2453 data1.writes = data_writes1; | 2450 data1.writes = data_writes1; |
| 2454 MockSocket data2; | 2451 MockSocket data2; |
| 2455 data2.reads = data_reads2; | 2452 data2.reads = data_reads2; |
| 2456 data2.writes = data_writes2; | 2453 data2.writes = data_writes2; |
| 2457 mock_sockets[0] = &data1; | 2454 mock_sockets[0] = &data1; |
| 2458 mock_sockets[1] = &data2; | 2455 mock_sockets[1] = &data2; |
| 2459 mock_sockets[2] = NULL; | 2456 mock_sockets[2] = NULL; |
| 2460 | 2457 |
| 2461 TestCompletionCallback callback1; | 2458 TestCompletionCallback callback1; |
| 2462 | 2459 |
| 2463 int rv = trans->Start(&request, &callback1); | 2460 int rv = trans->Start(&request, &callback1); |
| 2464 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2461 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2465 | 2462 |
| 2466 rv = callback1.WaitForResult(); | 2463 rv = callback1.WaitForResult(); |
| 2467 EXPECT_EQ(net::OK, rv); | 2464 EXPECT_EQ(OK, rv); |
| 2468 | 2465 |
| 2469 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | 2466 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); |
| 2470 TestCompletionCallback callback2; | 2467 TestCompletionCallback callback2; |
| 2471 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); | 2468 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); |
| 2472 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2469 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2473 rv = callback2.WaitForResult(); | 2470 rv = callback2.WaitForResult(); |
| 2474 EXPECT_EQ(net::OK, rv); | 2471 EXPECT_EQ(OK, rv); |
| 2475 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | 2472 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 2476 | 2473 |
| 2477 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2474 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2478 EXPECT_FALSE(response == NULL); | 2475 EXPECT_FALSE(response == NULL); |
| 2479 | 2476 |
| 2480 // There is no challenge info, since the identity in URL worked. | 2477 // There is no challenge info, since the identity in URL worked. |
| 2481 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2478 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2482 | 2479 |
| 2483 EXPECT_EQ(100, response->headers->GetContentLength()); | 2480 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2484 | 2481 |
| 2485 // Empty the current queue. | 2482 // Empty the current queue. |
| 2486 MessageLoop::current()->RunAllPending(); | 2483 MessageLoop::current()->RunAllPending(); |
| 2487 } | 2484 } |
| 2488 | 2485 |
| 2489 // Test that previously tried username/passwords for a realm get re-used. | 2486 // Test that previously tried username/passwords for a realm get re-used. |
| 2490 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { | 2487 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { |
| 2491 scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService()); | 2488 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 2492 scoped_refptr<net::HttpNetworkSession> session = | 2489 scoped_refptr<HttpNetworkSession> session = |
| 2493 CreateSession(proxy_service.get()); | 2490 CreateSession(proxy_service.get()); |
| 2494 | 2491 |
| 2495 // Transaction 1: authenticate (foo, bar) on MyRealm1 | 2492 // Transaction 1: authenticate (foo, bar) on MyRealm1 |
| 2496 { | 2493 { |
| 2497 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2494 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2498 session, &mock_socket_factory)); | 2495 session, &mock_socket_factory)); |
| 2499 | 2496 |
| 2500 net::HttpRequestInfo request; | 2497 HttpRequestInfo request; |
| 2501 request.method = "GET"; | 2498 request.method = "GET"; |
| 2502 request.url = GURL("http://www.google.com/x/y/z"); | 2499 request.url = GURL("http://www.google.com/x/y/z"); |
| 2503 request.load_flags = 0; | 2500 request.load_flags = 0; |
| 2504 | 2501 |
| 2505 MockWrite data_writes1[] = { | 2502 MockWrite data_writes1[] = { |
| 2506 MockWrite("GET /x/y/z HTTP/1.1\r\n" | 2503 MockWrite("GET /x/y/z HTTP/1.1\r\n" |
| 2507 "Host: www.google.com\r\n" | 2504 "Host: www.google.com\r\n" |
| 2508 "Connection: keep-alive\r\n\r\n"), | 2505 "Connection: keep-alive\r\n\r\n"), |
| 2509 }; | 2506 }; |
| 2510 | 2507 |
| 2511 MockRead data_reads1[] = { | 2508 MockRead data_reads1[] = { |
| 2512 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 2509 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2513 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 2510 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2514 MockRead("Content-Length: 10000\r\n\r\n"), | 2511 MockRead("Content-Length: 10000\r\n\r\n"), |
| 2515 MockRead(false, net::ERR_FAILED), | 2512 MockRead(false, ERR_FAILED), |
| 2516 }; | 2513 }; |
| 2517 | 2514 |
| 2518 // Resend with authorization (username=foo, password=bar) | 2515 // Resend with authorization (username=foo, password=bar) |
| 2519 MockWrite data_writes2[] = { | 2516 MockWrite data_writes2[] = { |
| 2520 MockWrite("GET /x/y/z HTTP/1.1\r\n" | 2517 MockWrite("GET /x/y/z HTTP/1.1\r\n" |
| 2521 "Host: www.google.com\r\n" | 2518 "Host: www.google.com\r\n" |
| 2522 "Connection: keep-alive\r\n" | 2519 "Connection: keep-alive\r\n" |
| 2523 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 2520 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 2524 }; | 2521 }; |
| 2525 | 2522 |
| 2526 // Sever accepts the authorization. | 2523 // Sever accepts the authorization. |
| 2527 MockRead data_reads2[] = { | 2524 MockRead data_reads2[] = { |
| 2528 MockRead("HTTP/1.0 200 OK\r\n"), | 2525 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2529 MockRead("Content-Length: 100\r\n\r\n"), | 2526 MockRead("Content-Length: 100\r\n\r\n"), |
| 2530 MockRead(false, net::OK), | 2527 MockRead(false, OK), |
| 2531 }; | 2528 }; |
| 2532 | 2529 |
| 2533 MockSocket data1; | 2530 MockSocket data1; |
| 2534 data1.reads = data_reads1; | 2531 data1.reads = data_reads1; |
| 2535 data1.writes = data_writes1; | 2532 data1.writes = data_writes1; |
| 2536 MockSocket data2; | 2533 MockSocket data2; |
| 2537 data2.reads = data_reads2; | 2534 data2.reads = data_reads2; |
| 2538 data2.writes = data_writes2; | 2535 data2.writes = data_writes2; |
| 2539 mock_sockets_index = 0; | 2536 mock_sockets_index = 0; |
| 2540 mock_sockets[0] = &data1; | 2537 mock_sockets[0] = &data1; |
| 2541 mock_sockets[1] = &data2; | 2538 mock_sockets[1] = &data2; |
| 2542 mock_sockets[2] = NULL; | 2539 mock_sockets[2] = NULL; |
| 2543 | 2540 |
| 2544 TestCompletionCallback callback1; | 2541 TestCompletionCallback callback1; |
| 2545 | 2542 |
| 2546 int rv = trans->Start(&request, &callback1); | 2543 int rv = trans->Start(&request, &callback1); |
| 2547 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2544 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2548 | 2545 |
| 2549 rv = callback1.WaitForResult(); | 2546 rv = callback1.WaitForResult(); |
| 2550 EXPECT_EQ(net::OK, rv); | 2547 EXPECT_EQ(OK, rv); |
| 2551 | 2548 |
| 2552 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2549 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2553 EXPECT_FALSE(response == NULL); | 2550 EXPECT_FALSE(response == NULL); |
| 2554 | 2551 |
| 2555 // The password prompt info should have been set in | 2552 // The password prompt info should have been set in |
| 2556 // response->auth_challenge. | 2553 // response->auth_challenge. |
| 2557 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 2554 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 2558 | 2555 |
| 2559 // TODO(eroman): this should really include the effective port (80) | 2556 // TODO(eroman): this should really include the effective port (80) |
| 2560 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 2557 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 2561 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 2558 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 2562 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 2559 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 2563 | 2560 |
| 2564 TestCompletionCallback callback2; | 2561 TestCompletionCallback callback2; |
| 2565 | 2562 |
| 2566 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); | 2563 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2); |
| 2567 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2564 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2568 | 2565 |
| 2569 rv = callback2.WaitForResult(); | 2566 rv = callback2.WaitForResult(); |
| 2570 EXPECT_EQ(net::OK, rv); | 2567 EXPECT_EQ(OK, rv); |
| 2571 | 2568 |
| 2572 response = trans->GetResponseInfo(); | 2569 response = trans->GetResponseInfo(); |
| 2573 EXPECT_FALSE(response == NULL); | 2570 EXPECT_FALSE(response == NULL); |
| 2574 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2571 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2575 EXPECT_EQ(100, response->headers->GetContentLength()); | 2572 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2576 } | 2573 } |
| 2577 | 2574 |
| 2578 // ------------------------------------------------------------------------ | 2575 // ------------------------------------------------------------------------ |
| 2579 | 2576 |
| 2580 // Transaction 2: authenticate (foo2, bar2) on MyRealm2 | 2577 // Transaction 2: authenticate (foo2, bar2) on MyRealm2 |
| 2581 { | 2578 { |
| 2582 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2579 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2583 session, &mock_socket_factory)); | 2580 session, &mock_socket_factory)); |
| 2584 | 2581 |
| 2585 net::HttpRequestInfo request; | 2582 HttpRequestInfo request; |
| 2586 request.method = "GET"; | 2583 request.method = "GET"; |
| 2587 // Note that Transaction 1 was at /x/y/z, so this is in the same | 2584 // Note that Transaction 1 was at /x/y/z, so this is in the same |
| 2588 // protection space as MyRealm1. | 2585 // protection space as MyRealm1. |
| 2589 request.url = GURL("http://www.google.com/x/y/a/b"); | 2586 request.url = GURL("http://www.google.com/x/y/a/b"); |
| 2590 request.load_flags = 0; | 2587 request.load_flags = 0; |
| 2591 | 2588 |
| 2592 MockWrite data_writes1[] = { | 2589 MockWrite data_writes1[] = { |
| 2593 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" | 2590 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" |
| 2594 "Host: www.google.com\r\n" | 2591 "Host: www.google.com\r\n" |
| 2595 "Connection: keep-alive\r\n" | 2592 "Connection: keep-alive\r\n" |
| 2596 // Send preemptive authorization for MyRealm1 | 2593 // Send preemptive authorization for MyRealm1 |
| 2597 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 2594 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 2598 }; | 2595 }; |
| 2599 | 2596 |
| 2600 // The server didn't like the preemptive authorization, and | 2597 // The server didn't like the preemptive authorization, and |
| 2601 // challenges us for a different realm (MyRealm2). | 2598 // challenges us for a different realm (MyRealm2). |
| 2602 MockRead data_reads1[] = { | 2599 MockRead data_reads1[] = { |
| 2603 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 2600 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2604 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"), | 2601 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"), |
| 2605 MockRead("Content-Length: 10000\r\n\r\n"), | 2602 MockRead("Content-Length: 10000\r\n\r\n"), |
| 2606 MockRead(false, net::ERR_FAILED), | 2603 MockRead(false, ERR_FAILED), |
| 2607 }; | 2604 }; |
| 2608 | 2605 |
| 2609 // Resend with authorization for MyRealm2 (username=foo2, password=bar2) | 2606 // Resend with authorization for MyRealm2 (username=foo2, password=bar2) |
| 2610 MockWrite data_writes2[] = { | 2607 MockWrite data_writes2[] = { |
| 2611 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" | 2608 MockWrite("GET /x/y/a/b HTTP/1.1\r\n" |
| 2612 "Host: www.google.com\r\n" | 2609 "Host: www.google.com\r\n" |
| 2613 "Connection: keep-alive\r\n" | 2610 "Connection: keep-alive\r\n" |
| 2614 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), | 2611 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), |
| 2615 }; | 2612 }; |
| 2616 | 2613 |
| 2617 // Sever accepts the authorization. | 2614 // Sever accepts the authorization. |
| 2618 MockRead data_reads2[] = { | 2615 MockRead data_reads2[] = { |
| 2619 MockRead("HTTP/1.0 200 OK\r\n"), | 2616 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2620 MockRead("Content-Length: 100\r\n\r\n"), | 2617 MockRead("Content-Length: 100\r\n\r\n"), |
| 2621 MockRead(false, net::OK), | 2618 MockRead(false, OK), |
| 2622 }; | 2619 }; |
| 2623 | 2620 |
| 2624 MockSocket data1; | 2621 MockSocket data1; |
| 2625 data1.reads = data_reads1; | 2622 data1.reads = data_reads1; |
| 2626 data1.writes = data_writes1; | 2623 data1.writes = data_writes1; |
| 2627 MockSocket data2; | 2624 MockSocket data2; |
| 2628 data2.reads = data_reads2; | 2625 data2.reads = data_reads2; |
| 2629 data2.writes = data_writes2; | 2626 data2.writes = data_writes2; |
| 2630 mock_sockets_index = 0; | 2627 mock_sockets_index = 0; |
| 2631 mock_sockets[0] = &data1; | 2628 mock_sockets[0] = &data1; |
| 2632 mock_sockets[1] = &data2; | 2629 mock_sockets[1] = &data2; |
| 2633 mock_sockets[2] = NULL; | 2630 mock_sockets[2] = NULL; |
| 2634 | 2631 |
| 2635 TestCompletionCallback callback1; | 2632 TestCompletionCallback callback1; |
| 2636 | 2633 |
| 2637 int rv = trans->Start(&request, &callback1); | 2634 int rv = trans->Start(&request, &callback1); |
| 2638 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2635 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2639 | 2636 |
| 2640 rv = callback1.WaitForResult(); | 2637 rv = callback1.WaitForResult(); |
| 2641 EXPECT_EQ(net::OK, rv); | 2638 EXPECT_EQ(OK, rv); |
| 2642 | 2639 |
| 2643 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2640 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2644 EXPECT_FALSE(response == NULL); | 2641 EXPECT_FALSE(response == NULL); |
| 2645 | 2642 |
| 2646 // The password prompt info should have been set in | 2643 // The password prompt info should have been set in |
| 2647 // response->auth_challenge. | 2644 // response->auth_challenge. |
| 2648 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 2645 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 2649 | 2646 |
| 2650 // TODO(eroman): this should really include the effective port (80) | 2647 // TODO(eroman): this should really include the effective port (80) |
| 2651 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 2648 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 2652 EXPECT_EQ(L"MyRealm2", response->auth_challenge->realm); | 2649 EXPECT_EQ(L"MyRealm2", response->auth_challenge->realm); |
| 2653 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 2650 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 2654 | 2651 |
| 2655 TestCompletionCallback callback2; | 2652 TestCompletionCallback callback2; |
| 2656 | 2653 |
| 2657 rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback2); | 2654 rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback2); |
| 2658 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2655 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2659 | 2656 |
| 2660 rv = callback2.WaitForResult(); | 2657 rv = callback2.WaitForResult(); |
| 2661 EXPECT_EQ(net::OK, rv); | 2658 EXPECT_EQ(OK, rv); |
| 2662 | 2659 |
| 2663 response = trans->GetResponseInfo(); | 2660 response = trans->GetResponseInfo(); |
| 2664 EXPECT_FALSE(response == NULL); | 2661 EXPECT_FALSE(response == NULL); |
| 2665 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2662 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2666 EXPECT_EQ(100, response->headers->GetContentLength()); | 2663 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2667 } | 2664 } |
| 2668 | 2665 |
| 2669 // ------------------------------------------------------------------------ | 2666 // ------------------------------------------------------------------------ |
| 2670 | 2667 |
| 2671 // Transaction 3: Resend a request in MyRealm's protection space -- | 2668 // Transaction 3: Resend a request in MyRealm's protection space -- |
| 2672 // succeed with preemptive authorization. | 2669 // succeed with preemptive authorization. |
| 2673 { | 2670 { |
| 2674 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2671 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2675 session, &mock_socket_factory)); | 2672 session, &mock_socket_factory)); |
| 2676 | 2673 |
| 2677 net::HttpRequestInfo request; | 2674 HttpRequestInfo request; |
| 2678 request.method = "GET"; | 2675 request.method = "GET"; |
| 2679 request.url = GURL("http://www.google.com/x/y/z2"); | 2676 request.url = GURL("http://www.google.com/x/y/z2"); |
| 2680 request.load_flags = 0; | 2677 request.load_flags = 0; |
| 2681 | 2678 |
| 2682 MockWrite data_writes1[] = { | 2679 MockWrite data_writes1[] = { |
| 2683 MockWrite("GET /x/y/z2 HTTP/1.1\r\n" | 2680 MockWrite("GET /x/y/z2 HTTP/1.1\r\n" |
| 2684 "Host: www.google.com\r\n" | 2681 "Host: www.google.com\r\n" |
| 2685 "Connection: keep-alive\r\n" | 2682 "Connection: keep-alive\r\n" |
| 2686 // The authorization for MyRealm1 gets sent preemptively | 2683 // The authorization for MyRealm1 gets sent preemptively |
| 2687 // (since the url is in the same protection space) | 2684 // (since the url is in the same protection space) |
| 2688 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 2685 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 2689 }; | 2686 }; |
| 2690 | 2687 |
| 2691 // Sever accepts the preemptive authorization | 2688 // Sever accepts the preemptive authorization |
| 2692 MockRead data_reads1[] = { | 2689 MockRead data_reads1[] = { |
| 2693 MockRead("HTTP/1.0 200 OK\r\n"), | 2690 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2694 MockRead("Content-Length: 100\r\n\r\n"), | 2691 MockRead("Content-Length: 100\r\n\r\n"), |
| 2695 MockRead(false, net::OK), | 2692 MockRead(false, OK), |
| 2696 }; | 2693 }; |
| 2697 | 2694 |
| 2698 MockSocket data1; | 2695 MockSocket data1; |
| 2699 data1.reads = data_reads1; | 2696 data1.reads = data_reads1; |
| 2700 data1.writes = data_writes1; | 2697 data1.writes = data_writes1; |
| 2701 mock_sockets_index = 0; | 2698 mock_sockets_index = 0; |
| 2702 mock_sockets[0] = &data1; | 2699 mock_sockets[0] = &data1; |
| 2703 mock_sockets[1] = NULL; | 2700 mock_sockets[1] = NULL; |
| 2704 | 2701 |
| 2705 TestCompletionCallback callback1; | 2702 TestCompletionCallback callback1; |
| 2706 | 2703 |
| 2707 int rv = trans->Start(&request, &callback1); | 2704 int rv = trans->Start(&request, &callback1); |
| 2708 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2705 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2709 | 2706 |
| 2710 rv = callback1.WaitForResult(); | 2707 rv = callback1.WaitForResult(); |
| 2711 EXPECT_EQ(net::OK, rv); | 2708 EXPECT_EQ(OK, rv); |
| 2712 | 2709 |
| 2713 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2710 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2714 EXPECT_FALSE(response == NULL); | 2711 EXPECT_FALSE(response == NULL); |
| 2715 | 2712 |
| 2716 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2713 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2717 EXPECT_EQ(100, response->headers->GetContentLength()); | 2714 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2718 } | 2715 } |
| 2719 | 2716 |
| 2720 // ------------------------------------------------------------------------ | 2717 // ------------------------------------------------------------------------ |
| 2721 | 2718 |
| 2722 // Transaction 4: request another URL in MyRealm (however the | 2719 // Transaction 4: request another URL in MyRealm (however the |
| 2723 // url is not known to belong to the protection space, so no pre-auth). | 2720 // url is not known to belong to the protection space, so no pre-auth). |
| 2724 { | 2721 { |
| 2725 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2722 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2726 session, &mock_socket_factory)); | 2723 session, &mock_socket_factory)); |
| 2727 | 2724 |
| 2728 net::HttpRequestInfo request; | 2725 HttpRequestInfo request; |
| 2729 request.method = "GET"; | 2726 request.method = "GET"; |
| 2730 request.url = GURL("http://www.google.com/x/1"); | 2727 request.url = GURL("http://www.google.com/x/1"); |
| 2731 request.load_flags = 0; | 2728 request.load_flags = 0; |
| 2732 | 2729 |
| 2733 MockWrite data_writes1[] = { | 2730 MockWrite data_writes1[] = { |
| 2734 MockWrite("GET /x/1 HTTP/1.1\r\n" | 2731 MockWrite("GET /x/1 HTTP/1.1\r\n" |
| 2735 "Host: www.google.com\r\n" | 2732 "Host: www.google.com\r\n" |
| 2736 "Connection: keep-alive\r\n\r\n"), | 2733 "Connection: keep-alive\r\n\r\n"), |
| 2737 }; | 2734 }; |
| 2738 | 2735 |
| 2739 MockRead data_reads1[] = { | 2736 MockRead data_reads1[] = { |
| 2740 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 2737 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2741 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 2738 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2742 MockRead("Content-Length: 10000\r\n\r\n"), | 2739 MockRead("Content-Length: 10000\r\n\r\n"), |
| 2743 MockRead(false, net::ERR_FAILED), | 2740 MockRead(false, ERR_FAILED), |
| 2744 }; | 2741 }; |
| 2745 | 2742 |
| 2746 // Resend with authorization from MyRealm's cache. | 2743 // Resend with authorization from MyRealm's cache. |
| 2747 MockWrite data_writes2[] = { | 2744 MockWrite data_writes2[] = { |
| 2748 MockWrite("GET /x/1 HTTP/1.1\r\n" | 2745 MockWrite("GET /x/1 HTTP/1.1\r\n" |
| 2749 "Host: www.google.com\r\n" | 2746 "Host: www.google.com\r\n" |
| 2750 "Connection: keep-alive\r\n" | 2747 "Connection: keep-alive\r\n" |
| 2751 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 2748 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 2752 }; | 2749 }; |
| 2753 | 2750 |
| 2754 // Sever accepts the authorization. | 2751 // Sever accepts the authorization. |
| 2755 MockRead data_reads2[] = { | 2752 MockRead data_reads2[] = { |
| 2756 MockRead("HTTP/1.0 200 OK\r\n"), | 2753 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2757 MockRead("Content-Length: 100\r\n\r\n"), | 2754 MockRead("Content-Length: 100\r\n\r\n"), |
| 2758 MockRead(false, net::OK), | 2755 MockRead(false, OK), |
| 2759 }; | 2756 }; |
| 2760 | 2757 |
| 2761 MockSocket data1; | 2758 MockSocket data1; |
| 2762 data1.reads = data_reads1; | 2759 data1.reads = data_reads1; |
| 2763 data1.writes = data_writes1; | 2760 data1.writes = data_writes1; |
| 2764 MockSocket data2; | 2761 MockSocket data2; |
| 2765 data2.reads = data_reads2; | 2762 data2.reads = data_reads2; |
| 2766 data2.writes = data_writes2; | 2763 data2.writes = data_writes2; |
| 2767 mock_sockets_index = 0; | 2764 mock_sockets_index = 0; |
| 2768 mock_sockets[0] = &data1; | 2765 mock_sockets[0] = &data1; |
| 2769 mock_sockets[1] = &data2; | 2766 mock_sockets[1] = &data2; |
| 2770 mock_sockets[2] = NULL; | 2767 mock_sockets[2] = NULL; |
| 2771 | 2768 |
| 2772 TestCompletionCallback callback1; | 2769 TestCompletionCallback callback1; |
| 2773 | 2770 |
| 2774 int rv = trans->Start(&request, &callback1); | 2771 int rv = trans->Start(&request, &callback1); |
| 2775 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2772 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2776 | 2773 |
| 2777 rv = callback1.WaitForResult(); | 2774 rv = callback1.WaitForResult(); |
| 2778 EXPECT_EQ(net::OK, rv); | 2775 EXPECT_EQ(OK, rv); |
| 2779 | 2776 |
| 2780 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | 2777 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); |
| 2781 TestCompletionCallback callback2; | 2778 TestCompletionCallback callback2; |
| 2782 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); | 2779 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); |
| 2783 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2780 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2784 rv = callback2.WaitForResult(); | 2781 rv = callback2.WaitForResult(); |
| 2785 EXPECT_EQ(net::OK, rv); | 2782 EXPECT_EQ(OK, rv); |
| 2786 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | 2783 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 2787 | 2784 |
| 2788 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2785 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2789 EXPECT_FALSE(response == NULL); | 2786 EXPECT_FALSE(response == NULL); |
| 2790 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2787 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2791 EXPECT_EQ(100, response->headers->GetContentLength()); | 2788 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2792 } | 2789 } |
| 2793 | 2790 |
| 2794 // ------------------------------------------------------------------------ | 2791 // ------------------------------------------------------------------------ |
| 2795 | 2792 |
| 2796 // Transaction 5: request a URL in MyRealm, but the server rejects the | 2793 // Transaction 5: request a URL in MyRealm, but the server rejects the |
| 2797 // cached identity. Should invalidate and re-prompt. | 2794 // cached identity. Should invalidate and re-prompt. |
| 2798 { | 2795 { |
| 2799 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 2796 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2800 session, &mock_socket_factory)); | 2797 session, &mock_socket_factory)); |
| 2801 | 2798 |
| 2802 net::HttpRequestInfo request; | 2799 HttpRequestInfo request; |
| 2803 request.method = "GET"; | 2800 request.method = "GET"; |
| 2804 request.url = GURL("http://www.google.com/p/q/t"); | 2801 request.url = GURL("http://www.google.com/p/q/t"); |
| 2805 request.load_flags = 0; | 2802 request.load_flags = 0; |
| 2806 | 2803 |
| 2807 MockWrite data_writes1[] = { | 2804 MockWrite data_writes1[] = { |
| 2808 MockWrite("GET /p/q/t HTTP/1.1\r\n" | 2805 MockWrite("GET /p/q/t HTTP/1.1\r\n" |
| 2809 "Host: www.google.com\r\n" | 2806 "Host: www.google.com\r\n" |
| 2810 "Connection: keep-alive\r\n\r\n"), | 2807 "Connection: keep-alive\r\n\r\n"), |
| 2811 }; | 2808 }; |
| 2812 | 2809 |
| 2813 MockRead data_reads1[] = { | 2810 MockRead data_reads1[] = { |
| 2814 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 2811 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2815 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 2812 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2816 MockRead("Content-Length: 10000\r\n\r\n"), | 2813 MockRead("Content-Length: 10000\r\n\r\n"), |
| 2817 MockRead(false, net::ERR_FAILED), | 2814 MockRead(false, ERR_FAILED), |
| 2818 }; | 2815 }; |
| 2819 | 2816 |
| 2820 // Resend with authorization from cache for MyRealm. | 2817 // Resend with authorization from cache for MyRealm. |
| 2821 MockWrite data_writes2[] = { | 2818 MockWrite data_writes2[] = { |
| 2822 MockWrite("GET /p/q/t HTTP/1.1\r\n" | 2819 MockWrite("GET /p/q/t HTTP/1.1\r\n" |
| 2823 "Host: www.google.com\r\n" | 2820 "Host: www.google.com\r\n" |
| 2824 "Connection: keep-alive\r\n" | 2821 "Connection: keep-alive\r\n" |
| 2825 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | 2822 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 2826 }; | 2823 }; |
| 2827 | 2824 |
| 2828 // Sever rejects the authorization. | 2825 // Sever rejects the authorization. |
| 2829 MockRead data_reads2[] = { | 2826 MockRead data_reads2[] = { |
| 2830 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 2827 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2831 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 2828 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2832 MockRead("Content-Length: 10000\r\n\r\n"), | 2829 MockRead("Content-Length: 10000\r\n\r\n"), |
| 2833 MockRead(false, net::ERR_FAILED), | 2830 MockRead(false, ERR_FAILED), |
| 2834 }; | 2831 }; |
| 2835 | 2832 |
| 2836 // At this point we should prompt for new credentials for MyRealm. | 2833 // At this point we should prompt for new credentials for MyRealm. |
| 2837 // Restart with username=foo3, password=foo4. | 2834 // Restart with username=foo3, password=foo4. |
| 2838 MockWrite data_writes3[] = { | 2835 MockWrite data_writes3[] = { |
| 2839 MockWrite("GET /p/q/t HTTP/1.1\r\n" | 2836 MockWrite("GET /p/q/t HTTP/1.1\r\n" |
| 2840 "Host: www.google.com\r\n" | 2837 "Host: www.google.com\r\n" |
| 2841 "Connection: keep-alive\r\n" | 2838 "Connection: keep-alive\r\n" |
| 2842 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"), | 2839 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"), |
| 2843 }; | 2840 }; |
| 2844 | 2841 |
| 2845 // Sever accepts the authorization. | 2842 // Sever accepts the authorization. |
| 2846 MockRead data_reads3[] = { | 2843 MockRead data_reads3[] = { |
| 2847 MockRead("HTTP/1.0 200 OK\r\n"), | 2844 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2848 MockRead("Content-Length: 100\r\n\r\n"), | 2845 MockRead("Content-Length: 100\r\n\r\n"), |
| 2849 MockRead(false, net::OK), | 2846 MockRead(false, OK), |
| 2850 }; | 2847 }; |
| 2851 | 2848 |
| 2852 MockSocket data1; | 2849 MockSocket data1; |
| 2853 data1.reads = data_reads1; | 2850 data1.reads = data_reads1; |
| 2854 data1.writes = data_writes1; | 2851 data1.writes = data_writes1; |
| 2855 MockSocket data2; | 2852 MockSocket data2; |
| 2856 data2.reads = data_reads2; | 2853 data2.reads = data_reads2; |
| 2857 data2.writes = data_writes2; | 2854 data2.writes = data_writes2; |
| 2858 MockSocket data3; | 2855 MockSocket data3; |
| 2859 data3.reads = data_reads3; | 2856 data3.reads = data_reads3; |
| 2860 data3.writes = data_writes3; | 2857 data3.writes = data_writes3; |
| 2861 mock_sockets_index = 0; | 2858 mock_sockets_index = 0; |
| 2862 mock_sockets[0] = &data1; | 2859 mock_sockets[0] = &data1; |
| 2863 mock_sockets[1] = &data2; | 2860 mock_sockets[1] = &data2; |
| 2864 mock_sockets[2] = &data3; | 2861 mock_sockets[2] = &data3; |
| 2865 mock_sockets[3] = NULL; | 2862 mock_sockets[3] = NULL; |
| 2866 | 2863 |
| 2867 TestCompletionCallback callback1; | 2864 TestCompletionCallback callback1; |
| 2868 | 2865 |
| 2869 int rv = trans->Start(&request, &callback1); | 2866 int rv = trans->Start(&request, &callback1); |
| 2870 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2867 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2871 | 2868 |
| 2872 rv = callback1.WaitForResult(); | 2869 rv = callback1.WaitForResult(); |
| 2873 EXPECT_EQ(net::OK, rv); | 2870 EXPECT_EQ(OK, rv); |
| 2874 | 2871 |
| 2875 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | 2872 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); |
| 2876 TestCompletionCallback callback2; | 2873 TestCompletionCallback callback2; |
| 2877 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); | 2874 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); |
| 2878 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2875 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2879 rv = callback2.WaitForResult(); | 2876 rv = callback2.WaitForResult(); |
| 2880 EXPECT_EQ(net::OK, rv); | 2877 EXPECT_EQ(OK, rv); |
| 2881 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | 2878 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 2882 | 2879 |
| 2883 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | 2880 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2884 EXPECT_FALSE(response == NULL); | 2881 EXPECT_FALSE(response == NULL); |
| 2885 | 2882 |
| 2886 // The password prompt info should have been set in | 2883 // The password prompt info should have been set in |
| 2887 // response->auth_challenge. | 2884 // response->auth_challenge. |
| 2888 EXPECT_FALSE(response->auth_challenge.get() == NULL); | 2885 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 2889 | 2886 |
| 2890 // TODO(eroman): this should really include the effective port (80) | 2887 // TODO(eroman): this should really include the effective port (80) |
| 2891 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); | 2888 EXPECT_EQ(L"www.google.com", response->auth_challenge->host); |
| 2892 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); | 2889 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 2893 EXPECT_EQ(L"basic", response->auth_challenge->scheme); | 2890 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 2894 | 2891 |
| 2895 TestCompletionCallback callback3; | 2892 TestCompletionCallback callback3; |
| 2896 | 2893 |
| 2897 rv = trans->RestartWithAuth(L"foo3", L"bar3", &callback3); | 2894 rv = trans->RestartWithAuth(L"foo3", L"bar3", &callback3); |
| 2898 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 2895 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2899 | 2896 |
| 2900 rv = callback3.WaitForResult(); | 2897 rv = callback3.WaitForResult(); |
| 2901 EXPECT_EQ(net::OK, rv); | 2898 EXPECT_EQ(OK, rv); |
| 2902 | 2899 |
| 2903 response = trans->GetResponseInfo(); | 2900 response = trans->GetResponseInfo(); |
| 2904 EXPECT_FALSE(response == NULL); | 2901 EXPECT_FALSE(response == NULL); |
| 2905 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2902 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2906 EXPECT_EQ(100, response->headers->GetContentLength()); | 2903 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2907 } | 2904 } |
| 2908 } | 2905 } |
| 2909 | 2906 |
| 2910 // Test the ResetStateForRestart() private method. | 2907 // Test the ResetStateForRestart() private method. |
| 2911 TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { | 2908 TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3034 request.url = GURL("https://www.google.com/"); | 3031 request.url = GURL("https://www.google.com/"); |
| 3035 request.load_flags = 0; | 3032 request.load_flags = 0; |
| 3036 | 3033 |
| 3037 MockWrite proxy_writes[] = { | 3034 MockWrite proxy_writes[] = { |
| 3038 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | 3035 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 3039 "Host: www.google.com\r\n\r\n"), | 3036 "Host: www.google.com\r\n\r\n"), |
| 3040 }; | 3037 }; |
| 3041 | 3038 |
| 3042 MockRead proxy_reads[] = { | 3039 MockRead proxy_reads[] = { |
| 3043 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), | 3040 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), |
| 3044 MockRead(false, net::OK) | 3041 MockRead(false, OK) |
| 3045 }; | 3042 }; |
| 3046 | 3043 |
| 3047 MockWrite data_writes[] = { | 3044 MockWrite data_writes[] = { |
| 3048 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | 3045 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 3049 "Host: www.google.com\r\n\r\n"), | 3046 "Host: www.google.com\r\n\r\n"), |
| 3050 MockWrite("GET / HTTP/1.1\r\n" | 3047 MockWrite("GET / HTTP/1.1\r\n" |
| 3051 "Host: www.google.com\r\n" | 3048 "Host: www.google.com\r\n" |
| 3052 "Connection: keep-alive\r\n\r\n"), | 3049 "Connection: keep-alive\r\n\r\n"), |
| 3053 }; | 3050 }; |
| 3054 | 3051 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3094 rv = callback.WaitForResult(); | 3091 rv = callback.WaitForResult(); |
| 3095 EXPECT_EQ(OK, rv); | 3092 EXPECT_EQ(OK, rv); |
| 3096 | 3093 |
| 3097 const HttpResponseInfo* response = trans->GetResponseInfo(); | 3094 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 3098 | 3095 |
| 3099 EXPECT_FALSE(response == NULL); | 3096 EXPECT_FALSE(response == NULL); |
| 3100 EXPECT_EQ(100, response->headers->GetContentLength()); | 3097 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 3101 } | 3098 } |
| 3102 } | 3099 } |
| 3103 | 3100 |
| 3101 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) { |
| 3102 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3103 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3104 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3105 |
| 3106 HttpRequestInfo request; |
| 3107 request.method = "GET"; |
| 3108 request.url = GURL("http://www.google.com/"); |
| 3109 request.user_agent = "Chromium Ultra Awesome X Edition"; |
| 3110 |
| 3111 MockWrite data_writes[] = { |
| 3112 MockWrite("GET / HTTP/1.1\r\n" |
| 3113 "Host: www.google.com\r\n" |
| 3114 "Connection: keep-alive\r\n" |
| 3115 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"), |
| 3116 }; |
| 3117 |
| 3118 // Lastly, the server responds with the actual content. |
| 3119 MockRead data_reads[] = { |
| 3120 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3121 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3122 MockRead("Content-Length: 100\r\n\r\n"), |
| 3123 MockRead(false, OK), |
| 3124 }; |
| 3125 |
| 3126 MockSocket data; |
| 3127 data.reads = data_reads; |
| 3128 data.writes = data_writes; |
| 3129 mock_sockets[0] = &data; |
| 3130 mock_sockets[1] = NULL; |
| 3131 |
| 3132 TestCompletionCallback callback; |
| 3133 |
| 3134 int rv = trans->Start(&request, &callback); |
| 3135 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3136 |
| 3137 rv = callback.WaitForResult(); |
| 3138 EXPECT_EQ(OK, rv); |
| 3139 } |
| 3140 |
| 3141 TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) { |
| 3142 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3143 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3144 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3145 |
| 3146 HttpRequestInfo request; |
| 3147 request.method = "GET"; |
| 3148 request.url = GURL("http://www.google.com/"); |
| 3149 request.load_flags = 0; |
| 3150 request.referrer = GURL("http://the.previous.site.com/"); |
| 3151 |
| 3152 MockWrite data_writes[] = { |
| 3153 MockWrite("GET / HTTP/1.1\r\n" |
| 3154 "Host: www.google.com\r\n" |
| 3155 "Connection: keep-alive\r\n" |
| 3156 "Referer: http://the.previous.site.com/\r\n\r\n"), |
| 3157 }; |
| 3158 |
| 3159 // Lastly, the server responds with the actual content. |
| 3160 MockRead data_reads[] = { |
| 3161 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3162 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3163 MockRead("Content-Length: 100\r\n\r\n"), |
| 3164 MockRead(false, OK), |
| 3165 }; |
| 3166 |
| 3167 MockSocket data; |
| 3168 data.reads = data_reads; |
| 3169 data.writes = data_writes; |
| 3170 mock_sockets[0] = &data; |
| 3171 mock_sockets[1] = NULL; |
| 3172 |
| 3173 TestCompletionCallback callback; |
| 3174 |
| 3175 int rv = trans->Start(&request, &callback); |
| 3176 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3177 |
| 3178 rv = callback.WaitForResult(); |
| 3179 EXPECT_EQ(OK, rv); |
| 3180 } |
| 3181 |
| 3182 TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) { |
| 3183 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3184 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3185 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3186 |
| 3187 HttpRequestInfo request; |
| 3188 request.method = "POST"; |
| 3189 request.url = GURL("http://www.google.com/"); |
| 3190 |
| 3191 MockWrite data_writes[] = { |
| 3192 MockWrite("POST / HTTP/1.1\r\n" |
| 3193 "Host: www.google.com\r\n" |
| 3194 "Connection: keep-alive\r\n" |
| 3195 "Content-Length: 0\r\n\r\n"), |
| 3196 }; |
| 3197 |
| 3198 // Lastly, the server responds with the actual content. |
| 3199 MockRead data_reads[] = { |
| 3200 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3201 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3202 MockRead("Content-Length: 100\r\n\r\n"), |
| 3203 MockRead(false, OK), |
| 3204 }; |
| 3205 |
| 3206 MockSocket data; |
| 3207 data.reads = data_reads; |
| 3208 data.writes = data_writes; |
| 3209 mock_sockets[0] = &data; |
| 3210 mock_sockets[1] = NULL; |
| 3211 |
| 3212 TestCompletionCallback callback; |
| 3213 |
| 3214 int rv = trans->Start(&request, &callback); |
| 3215 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3216 |
| 3217 rv = callback.WaitForResult(); |
| 3218 EXPECT_EQ(OK, rv); |
| 3219 } |
| 3220 |
| 3221 TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) { |
| 3222 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3223 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3224 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3225 |
| 3226 HttpRequestInfo request; |
| 3227 request.method = "PUT"; |
| 3228 request.url = GURL("http://www.google.com/"); |
| 3229 |
| 3230 MockWrite data_writes[] = { |
| 3231 MockWrite("PUT / HTTP/1.1\r\n" |
| 3232 "Host: www.google.com\r\n" |
| 3233 "Connection: keep-alive\r\n" |
| 3234 "Content-Length: 0\r\n\r\n"), |
| 3235 }; |
| 3236 |
| 3237 // Lastly, the server responds with the actual content. |
| 3238 MockRead data_reads[] = { |
| 3239 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3240 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3241 MockRead("Content-Length: 100\r\n\r\n"), |
| 3242 MockRead(false, OK), |
| 3243 }; |
| 3244 |
| 3245 MockSocket data; |
| 3246 data.reads = data_reads; |
| 3247 data.writes = data_writes; |
| 3248 mock_sockets[0] = &data; |
| 3249 mock_sockets[1] = NULL; |
| 3250 |
| 3251 TestCompletionCallback callback; |
| 3252 |
| 3253 int rv = trans->Start(&request, &callback); |
| 3254 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3255 |
| 3256 rv = callback.WaitForResult(); |
| 3257 EXPECT_EQ(OK, rv); |
| 3258 } |
| 3259 |
| 3260 TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) { |
| 3261 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3262 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3263 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3264 |
| 3265 HttpRequestInfo request; |
| 3266 request.method = "HEAD"; |
| 3267 request.url = GURL("http://www.google.com/"); |
| 3268 |
| 3269 MockWrite data_writes[] = { |
| 3270 MockWrite("HEAD / HTTP/1.1\r\n" |
| 3271 "Host: www.google.com\r\n" |
| 3272 "Connection: keep-alive\r\n" |
| 3273 "Content-Length: 0\r\n\r\n"), |
| 3274 }; |
| 3275 |
| 3276 // Lastly, the server responds with the actual content. |
| 3277 MockRead data_reads[] = { |
| 3278 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3279 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3280 MockRead("Content-Length: 100\r\n\r\n"), |
| 3281 MockRead(false, OK), |
| 3282 }; |
| 3283 |
| 3284 MockSocket data; |
| 3285 data.reads = data_reads; |
| 3286 data.writes = data_writes; |
| 3287 mock_sockets[0] = &data; |
| 3288 mock_sockets[1] = NULL; |
| 3289 |
| 3290 TestCompletionCallback callback; |
| 3291 |
| 3292 int rv = trans->Start(&request, &callback); |
| 3293 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3294 |
| 3295 rv = callback.WaitForResult(); |
| 3296 EXPECT_EQ(OK, rv); |
| 3297 } |
| 3298 |
| 3299 TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) { |
| 3300 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3301 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3302 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3303 |
| 3304 HttpRequestInfo request; |
| 3305 request.method = "GET"; |
| 3306 request.url = GURL("http://www.google.com/"); |
| 3307 request.load_flags = LOAD_BYPASS_CACHE; |
| 3308 |
| 3309 MockWrite data_writes[] = { |
| 3310 MockWrite("GET / HTTP/1.1\r\n" |
| 3311 "Host: www.google.com\r\n" |
| 3312 "Connection: keep-alive\r\n" |
| 3313 "Pragma: no-cache\r\n" |
| 3314 "Cache-Control: no-cache\r\n\r\n"), |
| 3315 }; |
| 3316 |
| 3317 // Lastly, the server responds with the actual content. |
| 3318 MockRead data_reads[] = { |
| 3319 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3321 MockRead("Content-Length: 100\r\n\r\n"), |
| 3322 MockRead(false, OK), |
| 3323 }; |
| 3324 |
| 3325 MockSocket data; |
| 3326 data.reads = data_reads; |
| 3327 data.writes = data_writes; |
| 3328 mock_sockets[0] = &data; |
| 3329 mock_sockets[1] = NULL; |
| 3330 |
| 3331 TestCompletionCallback callback; |
| 3332 |
| 3333 int rv = trans->Start(&request, &callback); |
| 3334 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3335 |
| 3336 rv = callback.WaitForResult(); |
| 3337 EXPECT_EQ(OK, rv); |
| 3338 } |
| 3339 |
| 3340 TEST_F(HttpNetworkTransactionTest, |
| 3341 BuildRequest_CacheControlValidateCache) { |
| 3342 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3343 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3344 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3345 |
| 3346 HttpRequestInfo request; |
| 3347 request.method = "GET"; |
| 3348 request.url = GURL("http://www.google.com/"); |
| 3349 request.load_flags = LOAD_VALIDATE_CACHE; |
| 3350 |
| 3351 MockWrite data_writes[] = { |
| 3352 MockWrite("GET / HTTP/1.1\r\n" |
| 3353 "Host: www.google.com\r\n" |
| 3354 "Connection: keep-alive\r\n" |
| 3355 "Cache-Control: max-age=0\r\n\r\n"), |
| 3356 }; |
| 3357 |
| 3358 // Lastly, the server responds with the actual content. |
| 3359 MockRead data_reads[] = { |
| 3360 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3361 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3362 MockRead("Content-Length: 100\r\n\r\n"), |
| 3363 MockRead(false, OK), |
| 3364 }; |
| 3365 |
| 3366 MockSocket data; |
| 3367 data.reads = data_reads; |
| 3368 data.writes = data_writes; |
| 3369 mock_sockets[0] = &data; |
| 3370 mock_sockets[1] = NULL; |
| 3371 |
| 3372 TestCompletionCallback callback; |
| 3373 |
| 3374 int rv = trans->Start(&request, &callback); |
| 3375 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3376 |
| 3377 rv = callback.WaitForResult(); |
| 3378 EXPECT_EQ(OK, rv); |
| 3379 } |
| 3380 |
| 3381 TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) { |
| 3382 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); |
| 3383 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 3384 CreateSession(proxy_service.get()), &mock_socket_factory)); |
| 3385 |
| 3386 HttpRequestInfo request; |
| 3387 request.method = "GET"; |
| 3388 request.url = GURL("http://www.google.com/"); |
| 3389 request.extra_headers = "FooHeader: Bar\r\n"; |
| 3390 |
| 3391 MockWrite data_writes[] = { |
| 3392 MockWrite("GET / HTTP/1.1\r\n" |
| 3393 "Host: www.google.com\r\n" |
| 3394 "Connection: keep-alive\r\n" |
| 3395 "FooHeader: Bar\r\n\r\n"), |
| 3396 }; |
| 3397 |
| 3398 // Lastly, the server responds with the actual content. |
| 3399 MockRead data_reads[] = { |
| 3400 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3401 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3402 MockRead("Content-Length: 100\r\n\r\n"), |
| 3403 MockRead(false, OK), |
| 3404 }; |
| 3405 |
| 3406 MockSocket data; |
| 3407 data.reads = data_reads; |
| 3408 data.writes = data_writes; |
| 3409 mock_sockets[0] = &data; |
| 3410 mock_sockets[1] = NULL; |
| 3411 |
| 3412 TestCompletionCallback callback; |
| 3413 |
| 3414 int rv = trans->Start(&request, &callback); |
| 3415 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3416 |
| 3417 rv = callback.WaitForResult(); |
| 3418 EXPECT_EQ(OK, rv); |
| 3419 } |
| 3420 |
| 3104 } // namespace net | 3421 } // namespace net |
| OLD | NEW |