OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 CaptureGroupNameSOCKSSocketPool; | 320 CaptureGroupNameSOCKSSocketPool; |
321 typedef CaptureGroupNameSocketPool<SSLClientSocketPool> | 321 typedef CaptureGroupNameSocketPool<SSLClientSocketPool> |
322 CaptureGroupNameSSLSocketPool; | 322 CaptureGroupNameSSLSocketPool; |
323 | 323 |
324 template<typename ParentPool> | 324 template<typename ParentPool> |
325 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool( | 325 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool( |
326 HttpNetworkSession* session) | 326 HttpNetworkSession* session) |
327 : ParentPool(0, 0, NULL, session->host_resolver(), NULL, NULL) {} | 327 : ParentPool(0, 0, NULL, session->host_resolver(), NULL, NULL) {} |
328 | 328 |
329 template<> | 329 template<> |
| 330 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool( |
| 331 HttpNetworkSession* session) |
| 332 : HttpProxyClientSocketPool(0, 0, NULL, session->host_resolver(), NULL, |
| 333 NULL, NULL) {} |
| 334 |
| 335 template<> |
330 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool( | 336 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool( |
331 HttpNetworkSession* session) | 337 HttpNetworkSession* session) |
332 : SSLClientSocketPool(0, 0, NULL, session->host_resolver(), NULL, NULL, | 338 : SSLClientSocketPool(0, 0, NULL, session->host_resolver(), NULL, NULL, |
333 NULL, NULL, NULL) {} | 339 NULL, NULL, NULL) {} |
334 | 340 |
335 //----------------------------------------------------------------------------- | 341 //----------------------------------------------------------------------------- |
336 | 342 |
337 // This is the expected list of advertised protocols from the browser's NPN | 343 // This is the expected list of advertised protocols from the browser's NPN |
338 // list. | 344 // list. |
339 static const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2"; | 345 static const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2"; |
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1654 | 1660 |
1655 TestCompletionCallback callback; | 1661 TestCompletionCallback callback; |
1656 | 1662 |
1657 int rv = trans->Start(&request, &callback, BoundNetLog()); | 1663 int rv = trans->Start(&request, &callback, BoundNetLog()); |
1658 EXPECT_EQ(ERR_IO_PENDING, rv); | 1664 EXPECT_EQ(ERR_IO_PENDING, rv); |
1659 | 1665 |
1660 rv = callback.WaitForResult(); | 1666 rv = callback.WaitForResult(); |
1661 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); | 1667 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); |
1662 } | 1668 } |
1663 | 1669 |
| 1670 |
| 1671 // Test a simple get through an HTTPS Proxy. |
| 1672 TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { |
| 1673 // Configure against https proxy server "proxy:70". |
| 1674 SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); |
| 1675 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
| 1676 session_deps.net_log = log.bound().net_log(); |
| 1677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 1678 |
| 1679 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
| 1680 |
| 1681 HttpRequestInfo request; |
| 1682 request.method = "GET"; |
| 1683 request.url = GURL("http://www.google.com/"); |
| 1684 |
| 1685 // Since we have proxy, should use full url |
| 1686 MockWrite data_writes1[] = { |
| 1687 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 1688 "Host: www.google.com\r\n" |
| 1689 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 1690 }; |
| 1691 |
| 1692 MockRead data_reads1[] = { |
| 1693 MockRead("HTTP/1.1 200 OK\r\n"), |
| 1694 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1695 MockRead("Content-Length: 100\r\n\r\n"), |
| 1696 MockRead(false, OK), |
| 1697 }; |
| 1698 |
| 1699 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 1700 data_writes1, arraysize(data_writes1)); |
| 1701 session_deps.socket_factory.AddSocketDataProvider(&data1); |
| 1702 SSLSocketDataProvider ssl(true, OK); |
| 1703 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 1704 |
| 1705 TestCompletionCallback callback1; |
| 1706 |
| 1707 int rv = trans->Start(&request, &callback1, log.bound()); |
| 1708 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1709 |
| 1710 rv = callback1.WaitForResult(); |
| 1711 EXPECT_EQ(OK, rv); |
| 1712 |
| 1713 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1714 ASSERT_FALSE(response == NULL); |
| 1715 |
| 1716 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 1717 EXPECT_EQ(200, response->headers->response_code()); |
| 1718 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 1719 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 1720 |
| 1721 // The password prompt info should not be set. |
| 1722 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1723 } |
| 1724 |
| 1725 // Test the challenge-response-retry sequence through an HTTPS Proxy |
| 1726 TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { |
| 1727 // Configure against https proxy server "proxy:70". |
| 1728 SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); |
| 1729 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
| 1730 session_deps.net_log = log.bound().net_log(); |
| 1731 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 1732 |
| 1733 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
| 1734 |
| 1735 HttpRequestInfo request; |
| 1736 request.method = "GET"; |
| 1737 request.url = GURL("http://www.google.com/"); |
| 1738 // when the no authentication data flag is set. |
| 1739 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; |
| 1740 |
| 1741 // Since we have proxy, should use full url |
| 1742 MockWrite data_writes1[] = { |
| 1743 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 1744 "Host: www.google.com\r\n" |
| 1745 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 1746 |
| 1747 // After calling trans->RestartWithAuth(), this is the request we should |
| 1748 // be issuing -- the final header line contains the credentials. |
| 1749 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n" |
| 1750 "Host: www.google.com\r\n" |
| 1751 "Proxy-Connection: keep-alive\r\n" |
| 1752 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 1753 }; |
| 1754 |
| 1755 // The proxy responds to the GET with a 407, using a persistent |
| 1756 // connection. |
| 1757 MockRead data_reads1[] = { |
| 1758 // No credentials. |
| 1759 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), |
| 1760 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 1761 MockRead("Proxy-Connection: keep-alive\r\n"), |
| 1762 MockRead("Content-Length: 0\r\n\r\n"), |
| 1763 |
| 1764 MockRead("HTTP/1.1 200 OK\r\n"), |
| 1765 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 1766 MockRead("Content-Length: 100\r\n\r\n"), |
| 1767 MockRead(false, OK), |
| 1768 }; |
| 1769 |
| 1770 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), |
| 1771 data_writes1, arraysize(data_writes1)); |
| 1772 session_deps.socket_factory.AddSocketDataProvider(&data1); |
| 1773 SSLSocketDataProvider ssl(true, OK); |
| 1774 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 1775 |
| 1776 TestCompletionCallback callback1; |
| 1777 |
| 1778 int rv = trans->Start(&request, &callback1, log.bound()); |
| 1779 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1780 |
| 1781 rv = callback1.WaitForResult(); |
| 1782 EXPECT_EQ(OK, rv); |
| 1783 |
| 1784 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1785 ASSERT_FALSE(response == NULL); |
| 1786 |
| 1787 EXPECT_EQ(407, response->headers->response_code()); |
| 1788 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 1789 |
| 1790 // The password prompt info should have been set in response->auth_challenge. |
| 1791 ASSERT_FALSE(response->auth_challenge.get() == NULL); |
| 1792 |
| 1793 EXPECT_EQ(L"proxy:70", response->auth_challenge->host_and_port); |
| 1794 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 1795 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 1796 |
| 1797 TestCompletionCallback callback2; |
| 1798 |
| 1799 rv = trans->RestartWithAuth(kFoo, kBar, &callback2); |
| 1800 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1801 |
| 1802 rv = callback2.WaitForResult(); |
| 1803 EXPECT_EQ(OK, rv); |
| 1804 |
| 1805 response = trans->GetResponseInfo(); |
| 1806 ASSERT_FALSE(response == NULL); |
| 1807 |
| 1808 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 1809 EXPECT_EQ(200, response->headers->response_code()); |
| 1810 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 1811 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 1812 |
| 1813 // The password prompt info should not be set. |
| 1814 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1815 } |
| 1816 |
1664 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( | 1817 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( |
1665 const MockRead& status, int expected_status) { | 1818 const MockRead& status, int expected_status) { |
1666 // Configure against proxy server "myproxy:70". | 1819 // Configure against proxy server "myproxy:70". |
1667 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); | 1820 SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); |
1668 | 1821 |
1669 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); | 1822 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
1670 | 1823 |
1671 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); | 1824 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
1672 | 1825 |
1673 HttpRequestInfo request; | 1826 HttpRequestInfo request; |
(...skipping 2010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3684 rv = callback.WaitForResult(); | 3837 rv = callback.WaitForResult(); |
3685 EXPECT_EQ(OK, rv); | 3838 EXPECT_EQ(OK, rv); |
3686 | 3839 |
3687 const HttpResponseInfo* response = trans->GetResponseInfo(); | 3840 const HttpResponseInfo* response = trans->GetResponseInfo(); |
3688 | 3841 |
3689 EXPECT_FALSE(response == NULL); | 3842 EXPECT_FALSE(response == NULL); |
3690 EXPECT_EQ(100, response->headers->GetContentLength()); | 3843 EXPECT_EQ(100, response->headers->GetContentLength()); |
3691 } | 3844 } |
3692 } | 3845 } |
3693 | 3846 |
| 3847 |
| 3848 // Test HTTPS connections to a site, going through an HTTPS proxy |
| 3849 TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { |
| 3850 SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); |
| 3851 |
| 3852 HttpRequestInfo request; |
| 3853 request.method = "GET"; |
| 3854 request.url = GURL("https://www.google.com/"); |
| 3855 request.load_flags = 0; |
| 3856 |
| 3857 MockWrite data_writes[] = { |
| 3858 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 3859 "Host: www.google.com\r\n" |
| 3860 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 3861 MockWrite("GET / HTTP/1.1\r\n" |
| 3862 "Host: www.google.com\r\n" |
| 3863 "Connection: keep-alive\r\n\r\n"), |
| 3864 }; |
| 3865 |
| 3866 MockRead data_reads[] = { |
| 3867 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), |
| 3868 MockRead("HTTP/1.1 200 OK\r\n"), |
| 3869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3870 MockRead("Content-Length: 100\r\n\r\n"), |
| 3871 MockRead(false, OK), |
| 3872 }; |
| 3873 |
| 3874 StaticSocketDataProvider data(data_reads, arraysize(data_reads), |
| 3875 data_writes, arraysize(data_writes)); |
| 3876 SSLSocketDataProvider proxy_ssl(true, OK); // SSL to the proxy |
| 3877 SSLSocketDataProvider tunnel_ssl(true, OK); // SSL through the tunnel |
| 3878 |
| 3879 session_deps.socket_factory.AddSocketDataProvider(&data); |
| 3880 session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl); |
| 3881 session_deps.socket_factory.AddSSLSocketDataProvider(&tunnel_ssl); |
| 3882 |
| 3883 TestCompletionCallback callback; |
| 3884 |
| 3885 scoped_ptr<HttpTransaction> trans( |
| 3886 new HttpNetworkTransaction(CreateSession(&session_deps))); |
| 3887 |
| 3888 int rv = trans->Start(&request, &callback, BoundNetLog()); |
| 3889 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3890 |
| 3891 rv = callback.WaitForResult(); |
| 3892 EXPECT_EQ(OK, rv); |
| 3893 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 3894 |
| 3895 ASSERT_FALSE(response == NULL); |
| 3896 |
| 3897 EXPECT_TRUE(response->headers->IsKeepAlive()); |
| 3898 EXPECT_EQ(200, response->headers->response_code()); |
| 3899 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 3900 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); |
| 3901 } |
| 3902 |
| 3903 // Test HTTPS connections to a site with a bad certificate, going through an |
| 3904 // HTTPS proxy |
| 3905 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) { |
| 3906 SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); |
| 3907 |
| 3908 HttpRequestInfo request; |
| 3909 request.method = "GET"; |
| 3910 request.url = GURL("https://www.google.com/"); |
| 3911 request.load_flags = 0; |
| 3912 |
| 3913 // Attempt to fetch the URL from a server with a bad cert |
| 3914 MockWrite bad_cert_writes[] = { |
| 3915 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 3916 "Host: www.google.com\r\n" |
| 3917 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 3918 }; |
| 3919 |
| 3920 MockRead bad_cert_reads[] = { |
| 3921 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), |
| 3922 MockRead(false, OK) |
| 3923 }; |
| 3924 |
| 3925 // Attempt to fetch the URL with a good cert |
| 3926 MockWrite good_data_writes[] = { |
| 3927 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" |
| 3928 "Host: www.google.com\r\n" |
| 3929 "Proxy-Connection: keep-alive\r\n\r\n"), |
| 3930 MockWrite("GET / HTTP/1.1\r\n" |
| 3931 "Host: www.google.com\r\n" |
| 3932 "Connection: keep-alive\r\n\r\n"), |
| 3933 }; |
| 3934 |
| 3935 MockRead good_cert_reads[] = { |
| 3936 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), |
| 3937 MockRead("HTTP/1.0 200 OK\r\n"), |
| 3938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), |
| 3939 MockRead("Content-Length: 100\r\n\r\n"), |
| 3940 MockRead(false, OK), |
| 3941 }; |
| 3942 |
| 3943 StaticSocketDataProvider ssl_bad_certificate( |
| 3944 bad_cert_reads, arraysize(bad_cert_reads), |
| 3945 bad_cert_writes, arraysize(bad_cert_writes)); |
| 3946 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads), |
| 3947 good_data_writes, arraysize(good_data_writes)); |
| 3948 SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID); |
| 3949 SSLSocketDataProvider ssl(true, OK); |
| 3950 |
| 3951 // SSL to the proxy, then CONNECT request, then SSL with bad certificate |
| 3952 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 3953 session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate); |
| 3954 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad); |
| 3955 |
| 3956 // SSL to the proxy, then CONNECT request, then valid SSL certificate |
| 3957 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 3958 session_deps.socket_factory.AddSocketDataProvider(&data); |
| 3959 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); |
| 3960 |
| 3961 TestCompletionCallback callback; |
| 3962 |
| 3963 scoped_ptr<HttpTransaction> trans( |
| 3964 new HttpNetworkTransaction(CreateSession(&session_deps))); |
| 3965 |
| 3966 int rv = trans->Start(&request, &callback, BoundNetLog()); |
| 3967 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3968 |
| 3969 rv = callback.WaitForResult(); |
| 3970 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); |
| 3971 |
| 3972 rv = trans->RestartIgnoringLastError(&callback); |
| 3973 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 3974 |
| 3975 rv = callback.WaitForResult(); |
| 3976 EXPECT_EQ(OK, rv); |
| 3977 |
| 3978 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 3979 |
| 3980 EXPECT_FALSE(response == NULL); |
| 3981 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 3982 } |
| 3983 |
3694 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) { | 3984 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) { |
3695 SessionDependencies session_deps; | 3985 SessionDependencies session_deps; |
3696 scoped_ptr<HttpTransaction> trans( | 3986 scoped_ptr<HttpTransaction> trans( |
3697 new HttpNetworkTransaction(CreateSession(&session_deps))); | 3987 new HttpNetworkTransaction(CreateSession(&session_deps))); |
3698 | 3988 |
3699 HttpRequestInfo request; | 3989 HttpRequestInfo request; |
3700 request.method = "GET"; | 3990 request.method = "GET"; |
3701 request.url = GURL("http://www.google.com/"); | 3991 request.url = GURL("http://www.google.com/"); |
3702 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, | 3992 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, |
3703 "Chromium Ultra Awesome X Edition"); | 3993 "Chromium Ultra Awesome X Edition"); |
(...skipping 3205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6909 size_t pos = ExpectLogContainsSomewhere( | 7199 size_t pos = ExpectLogContainsSomewhere( |
6910 log.entries(), 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, | 7200 log.entries(), 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, |
6911 NetLog::PHASE_NONE); | 7201 NetLog::PHASE_NONE); |
6912 ExpectLogContainsSomewhere( | 7202 ExpectLogContainsSomewhere( |
6913 log.entries(), pos, | 7203 log.entries(), pos, |
6914 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, | 7204 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, |
6915 NetLog::PHASE_NONE); | 7205 NetLog::PHASE_NONE); |
6916 } | 7206 } |
6917 | 7207 |
6918 } // namespace net | 7208 } // namespace net |
OLD | NEW |