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

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

Issue 249031: Refactor HttpNetworkTransaction: Parse stream in HttpStream (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_network_transaction.cc ('k') | net/http/http_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/completion_callback.h" 8 #include "net/base/completion_callback.h"
9 #include "net/base/mock_host_resolver.h" 9 #include "net/base/mock_host_resolver.h"
10 #include "net/base/ssl_config_service_defaults.h" 10 #include "net/base/ssl_config_service_defaults.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_basic_stream.h"
15 #include "net/http/http_network_session.h" 16 #include "net/http/http_network_session.h"
16 #include "net/http/http_network_transaction.h" 17 #include "net/http/http_network_transaction.h"
18 #include "net/http/http_stream.h"
17 #include "net/http/http_transaction_unittest.h" 19 #include "net/http/http_transaction_unittest.h"
18 #include "net/proxy/proxy_config_service_fixed.h" 20 #include "net/proxy/proxy_config_service_fixed.h"
19 #include "net/socket/client_socket_factory.h" 21 #include "net/socket/client_socket_factory.h"
20 #include "net/socket/socket_test_util.h" 22 #include "net/socket/socket_test_util.h"
21 #include "net/socket/ssl_client_socket.h" 23 #include "net/socket/ssl_client_socket.h"
22 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
23 #include "testing/platform_test.h" 25 #include "testing/platform_test.h"
24 26
25 //----------------------------------------------------------------------------- 27 //-----------------------------------------------------------------------------
26 28
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 MockRead("HTTP/1.1 204 No Content\r\n\r\n"), 315 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
314 MockRead("junk"), // Should not be read!! 316 MockRead("junk"), // Should not be read!!
315 MockRead(false, OK), 317 MockRead(false, OK),
316 }; 318 };
317 SimpleGetHelperResult out = SimpleGetHelper(data_reads); 319 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
318 EXPECT_EQ(OK, out.rv); 320 EXPECT_EQ(OK, out.rv);
319 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line); 321 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
320 EXPECT_EQ("", out.response_data); 322 EXPECT_EQ("", out.response_data);
321 } 323 }
322 324
325 // A simple request using chunked encoding with some extra data after.
326 // (Like might be seen in a pipelined response.)
327 TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
328 MockRead data_reads[] = {
329 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
330 MockRead("5\r\nHello\r\n"),
331 MockRead("1\r\n"),
332 MockRead(" \r\n"),
333 MockRead("5\r\nworld\r\n"),
334 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
335 MockRead(false, OK),
336 };
337 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
338 EXPECT_EQ(OK, out.rv);
339 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
340 EXPECT_EQ("Hello world", out.response_data);
341 }
342
323 // Do a request using the HEAD method. Verify that we don't try to read the 343 // Do a request using the HEAD method. Verify that we don't try to read the
324 // message body (since HEAD has none). 344 // message body (since HEAD has none).
325 TEST_F(HttpNetworkTransactionTest, Head) { 345 TEST_F(HttpNetworkTransactionTest, Head) {
326 SessionDependencies session_deps; 346 SessionDependencies session_deps;
327 scoped_ptr<HttpTransaction> trans( 347 scoped_ptr<HttpTransaction> trans(
328 new HttpNetworkTransaction(CreateSession(&session_deps))); 348 new HttpNetworkTransaction(CreateSession(&session_deps)));
329 349
330 HttpRequestInfo request; 350 HttpRequestInfo request;
331 request.method = "HEAD"; 351 request.method = "HEAD";
332 request.url = GURL("http://www.google.com/"); 352 request.url = GURL("http://www.google.com/");
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); 484 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
465 485
466 std::string response_data; 486 std::string response_data;
467 rv = ReadTransaction(trans.get(), &response_data); 487 rv = ReadTransaction(trans.get(), &response_data);
468 EXPECT_EQ(OK, rv); 488 EXPECT_EQ(OK, rv);
469 EXPECT_EQ("hello world", response_data); 489 EXPECT_EQ("hello world", response_data);
470 } 490 }
471 491
472 // This test is almost the same as Ignores100 above, but the response contains 492 // This test is almost the same as Ignores100 above, but the response contains
473 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is 493 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
474 // HTTP/1.1. 494 // HTTP/1.1 and the two status headers are read in one read.
475 TEST_F(HttpNetworkTransactionTest, Ignores1xx) { 495 TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
476 SessionDependencies session_deps; 496 SessionDependencies session_deps;
477 scoped_ptr<HttpTransaction> trans( 497 scoped_ptr<HttpTransaction> trans(
478 new HttpNetworkTransaction(CreateSession(&session_deps))); 498 new HttpNetworkTransaction(CreateSession(&session_deps)));
479 499
480 HttpRequestInfo request; 500 HttpRequestInfo request;
481 request.method = "GET"; 501 request.method = "GET";
482 request.url = GURL("http://www.foo.com/"); 502 request.url = GURL("http://www.foo.com/");
483 request.load_flags = 0; 503 request.load_flags = 0;
484 504
485 MockRead data_reads[] = { 505 MockRead data_reads[] = {
486 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"), 506 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
487 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 507 "HTTP/1.1 200 OK\r\n\r\n"),
488 MockRead("hello world"), 508 MockRead("hello world"),
489 MockRead(false, OK), 509 MockRead(false, OK),
490 }; 510 };
491 StaticMockSocket data(data_reads, NULL); 511 StaticMockSocket data(data_reads, NULL);
492 session_deps.socket_factory.AddMockSocket(&data); 512 session_deps.socket_factory.AddMockSocket(&data);
493 513
494 TestCompletionCallback callback; 514 TestCompletionCallback callback;
495 515
496 int rv = trans->Start(&request, &callback, NULL); 516 int rv = trans->Start(&request, &callback, NULL);
497 EXPECT_EQ(ERR_IO_PENDING, rv); 517 EXPECT_EQ(ERR_IO_PENDING, rv);
(...skipping 2173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 } 2691 }
2672 2692
2673 // Test the ResetStateForRestart() private method. 2693 // Test the ResetStateForRestart() private method.
2674 TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { 2694 TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
2675 // Create a transaction (the dependencies aren't important). 2695 // Create a transaction (the dependencies aren't important).
2676 SessionDependencies session_deps; 2696 SessionDependencies session_deps;
2677 scoped_ptr<HttpNetworkTransaction> trans( 2697 scoped_ptr<HttpNetworkTransaction> trans(
2678 new HttpNetworkTransaction(CreateSession(&session_deps))); 2698 new HttpNetworkTransaction(CreateSession(&session_deps)));
2679 2699
2680 // Setup some state (which we expect ResetStateForRestart() will clear). 2700 // Setup some state (which we expect ResetStateForRestart() will clear).
2681 trans->header_buf_->Realloc(10);
2682 trans->header_buf_capacity_ = 10;
2683 trans->header_buf_len_ = 3;
2684 trans->header_buf_body_offset_ = 11;
2685 trans->header_buf_http_offset_ = 0;
2686 trans->response_body_length_ = 100;
2687 trans->response_body_read_ = 1;
2688 trans->read_buf_ = new IOBuffer(15); 2701 trans->read_buf_ = new IOBuffer(15);
2689 trans->read_buf_len_ = 15; 2702 trans->read_buf_len_ = 15;
2690 trans->request_headers_->headers_ = "Authorization: NTLM"; 2703 trans->request_headers_ = "Authorization: NTLM";
2691 trans->request_headers_bytes_sent_ = 3;
2692 2704
2693 // Setup state in response_ 2705 // Setup state in response_
2694 trans->response_.auth_challenge = new AuthChallengeInfo(); 2706 trans->http_stream_.reset(new HttpBasicStream(NULL));
2695 trans->response_.ssl_info.cert_status = -15; 2707 HttpResponseInfo* response = trans->http_stream_->GetResponseInfo();
2696 trans->response_.response_time = base::Time::Now(); 2708 response->auth_challenge = new AuthChallengeInfo();
2697 trans->response_.was_cached = true; // (Wouldn't ever actually be true...) 2709 response->ssl_info.cert_status = -15;
2710 response->response_time = base::Time::Now();
2711 response->was_cached = true; // (Wouldn't ever actually be true...)
2698 2712
2699 { // Setup state for response_.vary_data 2713 { // Setup state for response_.vary_data
2700 HttpRequestInfo request; 2714 HttpRequestInfo request;
2701 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n"); 2715 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
2702 std::replace(temp.begin(), temp.end(), '\n', '\0'); 2716 std::replace(temp.begin(), temp.end(), '\n', '\0');
2703 scoped_refptr<HttpResponseHeaders> response = new HttpResponseHeaders(temp); 2717 scoped_refptr<HttpResponseHeaders> headers = new HttpResponseHeaders(temp);
2704 request.extra_headers = "Foo: 1\nbar: 23"; 2718 request.extra_headers = "Foo: 1\nbar: 23";
2705 EXPECT_TRUE(trans->response_.vary_data.Init(request, *response)); 2719 EXPECT_TRUE(response->vary_data.Init(request, *headers));
2706 } 2720 }
2707 2721
2708 // Cause the above state to be reset. 2722 // Cause the above state to be reset.
2709 trans->ResetStateForRestart(); 2723 trans->ResetStateForRestart();
2710 2724
2711 // Verify that the state that needed to be reset, has been reset. 2725 // Verify that the state that needed to be reset, has been reset.
2712 EXPECT_TRUE(trans->header_buf_->headers() == NULL); 2726 response = trans->http_stream_->GetResponseInfo();
2713 EXPECT_EQ(0, trans->header_buf_capacity_);
2714 EXPECT_EQ(0, trans->header_buf_len_);
2715 EXPECT_EQ(-1, trans->header_buf_body_offset_);
2716 EXPECT_EQ(-1, trans->header_buf_http_offset_);
2717 EXPECT_EQ(-1, trans->response_body_length_);
2718 EXPECT_EQ(0, trans->response_body_read_);
2719 EXPECT_TRUE(trans->read_buf_.get() == NULL); 2727 EXPECT_TRUE(trans->read_buf_.get() == NULL);
2720 EXPECT_EQ(0, trans->read_buf_len_); 2728 EXPECT_EQ(0, trans->read_buf_len_);
2721 EXPECT_EQ("", trans->request_headers_->headers_); 2729 EXPECT_EQ(0U, trans->request_headers_.size());
2722 EXPECT_EQ(0U, trans->request_headers_bytes_sent_); 2730 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2723 EXPECT_TRUE(trans->response_.auth_challenge.get() == NULL); 2731 EXPECT_TRUE(response->headers.get() == NULL);
2724 EXPECT_TRUE(trans->response_.headers.get() == NULL); 2732 EXPECT_EQ(false, response->was_cached);
2725 EXPECT_EQ(false, trans->response_.was_cached); 2733 EXPECT_EQ(0, response->ssl_info.cert_status);
2726 EXPECT_EQ(0, trans->response_.ssl_info.cert_status); 2734 EXPECT_FALSE(response->vary_data.is_valid());
2727 EXPECT_FALSE(trans->response_.vary_data.is_valid());
2728 } 2735 }
2729 2736
2730 // Test HTTPS connections to a site with a bad certificate 2737 // Test HTTPS connections to a site with a bad certificate
2731 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) { 2738 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
2732 SessionDependencies session_deps; 2739 SessionDependencies session_deps;
2733 scoped_ptr<HttpTransaction> trans( 2740 scoped_ptr<HttpTransaction> trans(
2734 new HttpNetworkTransaction(CreateSession(&session_deps))); 2741 new HttpNetworkTransaction(CreateSession(&session_deps)));
2735 2742
2736 HttpRequestInfo request; 2743 HttpRequestInfo request;
2737 request.method = "GET"; 2744 request.method = "GET";
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
3588 TestCompletionCallback callback; 3595 TestCompletionCallback callback;
3589 rv = trans->Start(&request, &callback, NULL); 3596 rv = trans->Start(&request, &callback, NULL);
3590 ASSERT_EQ(ERR_IO_PENDING, rv); 3597 ASSERT_EQ(ERR_IO_PENDING, rv);
3591 rv = callback.WaitForResult(); 3598 rv = callback.WaitForResult();
3592 3599
3593 // If we bypassed the cache, we would have gotten a failure while resolving 3600 // If we bypassed the cache, we would have gotten a failure while resolving
3594 // "www.google.com". 3601 // "www.google.com".
3595 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); 3602 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
3596 } 3603 }
3597 3604
3605 // Make sure we can handle an error when writing the request.
3606 TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
3607 SessionDependencies session_deps;
3608 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
3609
3610 HttpRequestInfo request;
3611 request.method = "GET";
3612 request.url = GURL("http://www.foo.com/");
3613 request.load_flags = 0;
3614
3615 MockWrite write_failure[] = {
3616 MockWrite(true, ERR_CONNECTION_RESET),
3617 };
3618 StaticMockSocket data(NULL, write_failure);
3619 session_deps.socket_factory.AddMockSocket(&data);
3620
3621 TestCompletionCallback callback;
3622
3623 scoped_ptr<HttpTransaction> trans(
3624 new HttpNetworkTransaction(CreateSession(&session_deps)));
3625
3626 int rv = trans->Start(&request, &callback, NULL);
3627 EXPECT_EQ(ERR_IO_PENDING, rv);
3628
3629 rv = callback.WaitForResult();
3630 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
3631 }
3632
3633 // Check that a connection closed after the start of the headers finishes ok.
3634 TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
3635 SessionDependencies session_deps;
3636 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
3637
3638 HttpRequestInfo request;
3639 request.method = "GET";
3640 request.url = GURL("http://www.foo.com/");
3641 request.load_flags = 0;
3642
3643 MockRead data_reads[] = {
3644 MockRead("HTTP/1."),
3645 MockRead(false, OK),
3646 };
3647
3648 StaticMockSocket data(data_reads, NULL);
3649 session_deps.socket_factory.AddMockSocket(&data);
3650
3651 TestCompletionCallback callback;
3652
3653 scoped_ptr<HttpTransaction> trans(
3654 new HttpNetworkTransaction(CreateSession(&session_deps)));
3655
3656 int rv = trans->Start(&request, &callback, NULL);
3657 EXPECT_EQ(ERR_IO_PENDING, rv);
3658
3659 rv = callback.WaitForResult();
3660 EXPECT_EQ(OK, rv);
3661
3662 const HttpResponseInfo* response = trans->GetResponseInfo();
3663 EXPECT_TRUE(response != NULL);
3664
3665 EXPECT_TRUE(response->headers != NULL);
3666 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
3667
3668 std::string response_data;
3669 rv = ReadTransaction(trans.get(), &response_data);
3670 EXPECT_EQ(OK, rv);
3671 EXPECT_EQ("", response_data);
3672 }
3673
3674 // Make sure that a dropped connection while draining the body for auth
3675 // restart does the right thing.
3676 TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
3677 SessionDependencies session_deps;
3678 scoped_ptr<HttpTransaction> trans(
3679 new HttpNetworkTransaction(CreateSession(&session_deps)));
3680
3681 HttpRequestInfo request;
3682 request.method = "GET";
3683 request.url = GURL("http://www.google.com/");
3684 request.load_flags = 0;
3685
3686 MockWrite data_writes1[] = {
3687 MockWrite("GET / HTTP/1.1\r\n"
3688 "Host: www.google.com\r\n"
3689 "Connection: keep-alive\r\n\r\n"),
3690 };
3691
3692 MockRead data_reads1[] = {
3693 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3694 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3695 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3696 MockRead("Content-Length: 14\r\n\r\n"),
3697 MockRead("Unauth"),
3698 MockRead(true, ERR_CONNECTION_RESET),
3699 };
3700
3701 StaticMockSocket data1(data_reads1, data_writes1);
3702 session_deps.socket_factory.AddMockSocket(&data1);
3703
3704 // After calling trans->RestartWithAuth(), this is the request we should
3705 // be issuing -- the final header line contains the credentials.
3706 MockWrite data_writes2[] = {
3707 MockWrite("GET / HTTP/1.1\r\n"
3708 "Host: www.google.com\r\n"
3709 "Connection: keep-alive\r\n"
3710 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3711 };
3712
3713 // Lastly, the server responds with the actual content.
3714 MockRead data_reads2[] = {
3715 MockRead("HTTP/1.1 200 OK\r\n"),
3716 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3717 MockRead("Content-Length: 100\r\n\r\n"),
3718 MockRead(false, OK),
3719 };
3720
3721 StaticMockSocket data2(data_reads2, data_writes2);
3722 session_deps.socket_factory.AddMockSocket(&data2);
3723
3724 TestCompletionCallback callback1;
3725
3726 int rv = trans->Start(&request, &callback1, NULL);
3727 EXPECT_EQ(ERR_IO_PENDING, rv);
3728
3729 rv = callback1.WaitForResult();
3730 EXPECT_EQ(OK, rv);
3731
3732 const HttpResponseInfo* response = trans->GetResponseInfo();
3733 EXPECT_FALSE(response == NULL);
3734
3735 // The password prompt info should have been set in response->auth_challenge.
3736 EXPECT_FALSE(response->auth_challenge.get() == NULL);
3737
3738 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
3739 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
3740 EXPECT_EQ(L"basic", response->auth_challenge->scheme);
3741
3742 TestCompletionCallback callback2;
3743
3744 rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
3745 EXPECT_EQ(ERR_IO_PENDING, rv);
3746
3747 rv = callback2.WaitForResult();
3748 EXPECT_EQ(OK, rv);
3749
3750 response = trans->GetResponseInfo();
3751 EXPECT_FALSE(response == NULL);
3752 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3753 EXPECT_EQ(100, response->headers->GetContentLength());
3754 }
3755
3756 // Test HTTPS connections going through a proxy that sends extra data.
3757 TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
3758 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
3759
3760 HttpRequestInfo request;
3761 request.method = "GET";
3762 request.url = GURL("https://www.google.com/");
3763 request.load_flags = 0;
3764
3765 MockRead proxy_reads[] = {
3766 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
3767 MockRead(false, OK)
3768 };
3769
3770 StaticMockSocket data(proxy_reads, NULL);
3771 MockSSLSocket ssl(true, OK);
3772
3773 session_deps.socket_factory.AddMockSocket(&data);
3774 session_deps.socket_factory.AddMockSSLSocket(&ssl);
3775
3776 TestCompletionCallback callback;
3777
3778 session_deps.socket_factory.ResetNextMockIndexes();
3779
3780 scoped_ptr<HttpTransaction> trans(
3781 new HttpNetworkTransaction(CreateSession(&session_deps)));
3782
3783 int rv = trans->Start(&request, &callback, NULL);
3784 EXPECT_EQ(ERR_IO_PENDING, rv);
3785
3786 rv = callback.WaitForResult();
3787 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3788 }
3789
3598 } // namespace net 3790 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_network_transaction.cc ('k') | net/http/http_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698