| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
| 6 | 6 |
| 7 #include <math.h> // ceil | 7 #include <math.h> // ceil |
| 8 #include <stdarg.h> | 8 #include <stdarg.h> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 3700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3711 | 3711 |
| 3712 std::string response_data; | 3712 std::string response_data; |
| 3713 rv = ReadTransaction(trans.get(), &response_data); | 3713 rv = ReadTransaction(trans.get(), &response_data); |
| 3714 EXPECT_EQ(OK, rv); | 3714 EXPECT_EQ(OK, rv); |
| 3715 EXPECT_EQ(kExpectedResponseData[i], response_data); | 3715 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 3716 } | 3716 } |
| 3717 } | 3717 } |
| 3718 | 3718 |
| 3719 // Test the request-challenge-retry sequence for basic auth when there is | 3719 // Test the request-challenge-retry sequence for basic auth when there is |
| 3720 // an identity in the URL. The request should be sent as normal, but when | 3720 // an identity in the URL. The request should be sent as normal, but when |
| 3721 // it fails the identity from the URL is used to answer the challenge. | 3721 // it fails the identity from the URL is no longer used. |
| 3722 TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) { | 3722 TEST_F(HttpNetworkTransactionTest, IgnoreAuthIdentityInURL) { |
| 3723 HttpRequestInfo request; | 3723 HttpRequestInfo request; |
| 3724 request.method = "GET"; | 3724 request.method = "GET"; |
| 3725 // Note: the URL has a username:password in it. | |
| 3726 request.url = GURL("http://foo:b@r@www.google.com/"); | 3725 request.url = GURL("http://foo:b@r@www.google.com/"); |
| 3726 request.load_flags = LOAD_NORMAL; |
| 3727 | 3727 |
| 3728 SessionDependencies session_deps; | 3728 SessionDependencies session_deps; |
| 3729 scoped_ptr<HttpTransaction> trans( | 3729 scoped_ptr<HttpTransaction> trans( |
| 3730 new HttpNetworkTransaction(CreateSession(&session_deps))); | 3730 new HttpNetworkTransaction(CreateSession(&session_deps))); |
| 3731 | 3731 |
| 3732 // The password contains an escaped character -- for this test to pass it | 3732 // The password contains an escaped character -- for this test to pass it |
| 3733 // will need to be unescaped by HttpNetworkTransaction. | 3733 // will need to be unescaped by HttpNetworkTransaction. |
| 3734 EXPECT_EQ("b%40r", request.url.password()); | 3734 EXPECT_EQ("b%40r", request.url.password()); |
| 3735 | 3735 |
| 3736 request.load_flags = LOAD_NORMAL; | |
| 3737 | |
| 3738 MockWrite data_writes1[] = { | 3736 MockWrite data_writes1[] = { |
| 3739 MockWrite("GET / HTTP/1.1\r\n" | 3737 MockWrite("GET / HTTP/1.1\r\n" |
| 3740 "Host: www.google.com\r\n" | 3738 "Host: www.google.com\r\n" |
| 3741 "Connection: keep-alive\r\n\r\n"), | 3739 "Connection: keep-alive\r\n\r\n"), |
| 3742 }; | 3740 }; |
| 3743 | 3741 |
| 3744 MockRead data_reads1[] = { | 3742 MockRead data_reads1[] = { |
| 3745 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 3743 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 3746 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 3744 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 3747 MockRead("Content-Length: 10\r\n\r\n"), | 3745 MockRead("Content-Length: 10\r\n\r\n"), |
| 3748 MockRead(false, ERR_FAILED), | 3746 MockRead(false, ERR_FAILED), |
| 3749 }; | 3747 }; |
| 3750 | 3748 |
| 3751 // After the challenge above, the transaction will be restarted using the | |
| 3752 // identity from the url (foo, b@r) to answer the challenge. | |
| 3753 MockWrite data_writes2[] = { | |
| 3754 MockWrite("GET / HTTP/1.1\r\n" | |
| 3755 "Host: www.google.com\r\n" | |
| 3756 "Connection: keep-alive\r\n" | |
| 3757 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"), | |
| 3758 }; | |
| 3759 | |
| 3760 MockRead data_reads2[] = { | |
| 3761 MockRead("HTTP/1.0 200 OK\r\n"), | |
| 3762 MockRead("Content-Length: 100\r\n\r\n"), | |
| 3763 MockRead(false, OK), | |
| 3764 }; | |
| 3765 | |
| 3766 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), | 3749 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 3767 data_writes1, arraysize(data_writes1)); | 3750 data_writes1, arraysize(data_writes1)); |
| 3768 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), | |
| 3769 data_writes2, arraysize(data_writes2)); | |
| 3770 session_deps.socket_factory.AddSocketDataProvider(&data1); | 3751 session_deps.socket_factory.AddSocketDataProvider(&data1); |
| 3771 session_deps.socket_factory.AddSocketDataProvider(&data2); | |
| 3772 | 3752 |
| 3773 TestCompletionCallback callback1; | 3753 TestCompletionCallback callback1; |
| 3774 | |
| 3775 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); | 3754 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); |
| 3776 EXPECT_EQ(ERR_IO_PENDING, rv); | 3755 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3777 | |
| 3778 rv = callback1.WaitForResult(); | 3756 rv = callback1.WaitForResult(); |
| 3779 EXPECT_EQ(OK, rv); | 3757 EXPECT_EQ(OK, rv); |
| 3780 | |
| 3781 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | |
| 3782 TestCompletionCallback callback2; | |
| 3783 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); | |
| 3784 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 3785 rv = callback2.WaitForResult(); | |
| 3786 EXPECT_EQ(OK, rv); | |
| 3787 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | 3758 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 3788 | 3759 |
| 3789 const HttpResponseInfo* response = trans->GetResponseInfo(); | |
| 3790 ASSERT_TRUE(response != NULL); | |
| 3791 | |
| 3792 // There is no challenge info, since the identity in URL worked. | |
| 3793 EXPECT_TRUE(response->auth_challenge.get() == NULL); | |
| 3794 | |
| 3795 EXPECT_EQ(100, response->headers->GetContentLength()); | |
| 3796 | |
| 3797 // Empty the current queue. | |
| 3798 MessageLoop::current()->RunAllPending(); | |
| 3799 } | |
| 3800 | |
| 3801 // Test the request-challenge-retry sequence for basic auth when there is | |
| 3802 // an incorrect identity in the URL. The identity from the URL should be used | |
| 3803 // only once. | |
| 3804 TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) { | |
| 3805 HttpRequestInfo request; | |
| 3806 request.method = "GET"; | |
| 3807 // Note: the URL has a username:password in it. The password "baz" is | |
| 3808 // wrong (should be "bar"). | |
| 3809 request.url = GURL("http://foo:baz@www.google.com/"); | |
| 3810 | |
| 3811 request.load_flags = LOAD_NORMAL; | |
| 3812 | |
| 3813 SessionDependencies session_deps; | |
| 3814 scoped_ptr<HttpTransaction> trans( | |
| 3815 new HttpNetworkTransaction(CreateSession(&session_deps))); | |
| 3816 | |
| 3817 MockWrite data_writes1[] = { | |
| 3818 MockWrite("GET / HTTP/1.1\r\n" | |
| 3819 "Host: www.google.com\r\n" | |
| 3820 "Connection: keep-alive\r\n\r\n"), | |
| 3821 }; | |
| 3822 | |
| 3823 MockRead data_reads1[] = { | |
| 3824 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | |
| 3825 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | |
| 3826 MockRead("Content-Length: 10\r\n\r\n"), | |
| 3827 MockRead(false, ERR_FAILED), | |
| 3828 }; | |
| 3829 | |
| 3830 // After the challenge above, the transaction will be restarted using the | |
| 3831 // identity from the url (foo, baz) to answer the challenge. | |
| 3832 MockWrite data_writes2[] = { | |
| 3833 MockWrite("GET / HTTP/1.1\r\n" | |
| 3834 "Host: www.google.com\r\n" | |
| 3835 "Connection: keep-alive\r\n" | |
| 3836 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"), | |
| 3837 }; | |
| 3838 | |
| 3839 MockRead data_reads2[] = { | |
| 3840 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | |
| 3841 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | |
| 3842 MockRead("Content-Length: 10\r\n\r\n"), | |
| 3843 MockRead(false, ERR_FAILED), | |
| 3844 }; | |
| 3845 | |
| 3846 // After the challenge above, the transaction will be restarted using the | |
| 3847 // identity supplied by the user (foo, bar) to answer the challenge. | |
| 3848 MockWrite data_writes3[] = { | |
| 3849 MockWrite("GET / HTTP/1.1\r\n" | |
| 3850 "Host: www.google.com\r\n" | |
| 3851 "Connection: keep-alive\r\n" | |
| 3852 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | |
| 3853 }; | |
| 3854 | |
| 3855 MockRead data_reads3[] = { | |
| 3856 MockRead("HTTP/1.0 200 OK\r\n"), | |
| 3857 MockRead("Content-Length: 100\r\n\r\n"), | |
| 3858 MockRead(false, OK), | |
| 3859 }; | |
| 3860 | |
| 3861 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), | |
| 3862 data_writes1, arraysize(data_writes1)); | |
| 3863 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), | |
| 3864 data_writes2, arraysize(data_writes2)); | |
| 3865 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3), | |
| 3866 data_writes3, arraysize(data_writes3)); | |
| 3867 session_deps.socket_factory.AddSocketDataProvider(&data1); | |
| 3868 session_deps.socket_factory.AddSocketDataProvider(&data2); | |
| 3869 session_deps.socket_factory.AddSocketDataProvider(&data3); | |
| 3870 | |
| 3871 TestCompletionCallback callback1; | |
| 3872 | |
| 3873 int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); | |
| 3874 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 3875 | |
| 3876 rv = callback1.WaitForResult(); | |
| 3877 EXPECT_EQ(OK, rv); | |
| 3878 | |
| 3879 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); | |
| 3880 TestCompletionCallback callback2; | |
| 3881 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); | |
| 3882 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 3883 rv = callback2.WaitForResult(); | |
| 3884 EXPECT_EQ(OK, rv); | |
| 3885 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | |
| 3886 | |
| 3887 const HttpResponseInfo* response = trans->GetResponseInfo(); | |
| 3888 ASSERT_TRUE(response != NULL); | |
| 3889 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); | |
| 3890 | |
| 3891 TestCompletionCallback callback3; | |
| 3892 rv = trans->RestartWithAuth( | |
| 3893 AuthCredentials(kFoo, kBar), callback3.callback()); | |
| 3894 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 3895 rv = callback3.WaitForResult(); | |
| 3896 EXPECT_EQ(OK, rv); | |
| 3897 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); | |
| 3898 | |
| 3899 response = trans->GetResponseInfo(); | |
| 3900 ASSERT_TRUE(response != NULL); | |
| 3901 | |
| 3902 // There is no challenge info, since the identity worked. | |
| 3903 EXPECT_TRUE(response->auth_challenge.get() == NULL); | |
| 3904 | |
| 3905 EXPECT_EQ(100, response->headers->GetContentLength()); | |
| 3906 | |
| 3907 // Empty the current queue. | 3760 // Empty the current queue. |
| 3908 MessageLoop::current()->RunAllPending(); | 3761 MessageLoop::current()->RunAllPending(); |
| 3909 } | 3762 } |
| 3910 | 3763 |
| 3911 // Test that previously tried username/passwords for a realm get re-used. | 3764 // Test that previously tried username/passwords for a realm get re-used. |
| 3912 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { | 3765 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { |
| 3913 SessionDependencies session_deps; | 3766 SessionDependencies session_deps; |
| 3914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); | 3767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 3915 | 3768 |
| 3916 // Transaction 1: authenticate (foo, bar) on MyRealm1 | 3769 // Transaction 1: authenticate (foo, bar) on MyRealm1 |
| (...skipping 5468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9385 StaticSocketDataProvider* data[] = { &data1, &data2 }; | 9238 StaticSocketDataProvider* data[] = { &data1, &data2 }; |
| 9386 | 9239 |
| 9387 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data)); | 9240 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data)); |
| 9388 | 9241 |
| 9389 EXPECT_EQ(OK, out.rv); | 9242 EXPECT_EQ(OK, out.rv); |
| 9390 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); | 9243 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line); |
| 9391 EXPECT_EQ("hello world", out.response_data); | 9244 EXPECT_EQ("hello world", out.response_data); |
| 9392 } | 9245 } |
| 9393 | 9246 |
| 9394 } // namespace net | 9247 } // namespace net |
| OLD | NEW |