OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
16 #include "base/json/json_writer.h" | 16 #include "base/json/json_writer.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
19 #include "base/memory/weak_ptr.h" | 19 #include "base/memory/weak_ptr.h" |
20 #include "base/run_loop.h" | 20 #include "base/run_loop.h" |
| 21 #include "base/stl_util.h" |
21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
22 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
23 #include "base/test/test_file_util.h" | 24 #include "base/test/test_file_util.h" |
24 #include "net/base/auth.h" | 25 #include "net/base/auth.h" |
25 #include "net/base/chunked_upload_data_stream.h" | 26 #include "net/base/chunked_upload_data_stream.h" |
26 #include "net/base/completion_callback.h" | 27 #include "net/base/completion_callback.h" |
27 #include "net/base/elements_upload_data_stream.h" | 28 #include "net/base/elements_upload_data_stream.h" |
28 #include "net/base/load_timing_info.h" | 29 #include "net/base/load_timing_info.h" |
29 #include "net/base/load_timing_info_test_util.h" | 30 #include "net/base/load_timing_info_test_util.h" |
30 #include "net/base/net_errors.h" | 31 #include "net/base/net_errors.h" |
(...skipping 11726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11757 HttpNetworkTransaction trans2(MEDIUM, session.get()); | 11758 HttpNetworkTransaction trans2(MEDIUM, session.get()); |
11758 TestCompletionCallback callback2; | 11759 TestCompletionCallback callback2; |
11759 EXPECT_EQ(ERR_IO_PENDING, | 11760 EXPECT_EQ(ERR_IO_PENDING, |
11760 trans2.Start(&request2, callback2.callback(), BoundNetLog())); | 11761 trans2.Start(&request2, callback2.callback(), BoundNetLog())); |
11761 base::MessageLoop::current()->RunUntilIdle(); | 11762 base::MessageLoop::current()->RunUntilIdle(); |
11762 | 11763 |
11763 EXPECT_EQ(OK, callback2.WaitForResult()); | 11764 EXPECT_EQ(OK, callback2.WaitForResult()); |
11764 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); | 11765 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); |
11765 } | 11766 } |
11766 | 11767 |
| 11768 class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest { |
| 11769 public: |
| 11770 void Run(bool pooling, bool valid) { |
| 11771 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org", |
| 11772 443); |
| 11773 HostPortPair alternative("www.example.org", 443); |
| 11774 |
| 11775 base::FilePath certs_dir = GetTestCertsDirectory(); |
| 11776 scoped_refptr<X509Certificate> cert( |
| 11777 ImportCertFromFile(certs_dir, "spdy_pooling.pem")); |
| 11778 ASSERT_TRUE(cert.get() != nullptr); |
| 11779 bool common_name_fallback_used; |
| 11780 EXPECT_EQ(valid, |
| 11781 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used)); |
| 11782 EXPECT_TRUE( |
| 11783 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used)); |
| 11784 SSLSocketDataProvider ssl(ASYNC, OK); |
| 11785 ssl.SetNextProto(GetParam()); |
| 11786 ssl.cert = cert; |
| 11787 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); |
| 11788 |
| 11789 // If pooling, then start a request to alternative first to create a |
| 11790 // SpdySession. |
| 11791 std::string url0 = "https://www.example.org:443"; |
| 11792 // Second request to origin, which has an alternative service, and could |
| 11793 // open a connection to the alternative host or pool to the existing one. |
| 11794 std::string url1("https://"); |
| 11795 url1.append(origin.host()); |
| 11796 url1.append(":443"); |
| 11797 |
| 11798 scoped_ptr<SpdyFrame> req0; |
| 11799 scoped_ptr<SpdyFrame> req1; |
| 11800 scoped_ptr<SpdyFrame> resp0; |
| 11801 scoped_ptr<SpdyFrame> body0; |
| 11802 scoped_ptr<SpdyFrame> resp1; |
| 11803 scoped_ptr<SpdyFrame> body1; |
| 11804 std::vector<MockWrite> writes; |
| 11805 std::vector<MockRead> reads; |
| 11806 |
| 11807 if (pooling) { |
| 11808 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST)); |
| 11809 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST)); |
| 11810 |
| 11811 writes.push_back(CreateMockWrite(*req0, 0)); |
| 11812 writes.push_back(CreateMockWrite(*req1, 3)); |
| 11813 |
| 11814 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 11815 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 11816 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); |
| 11817 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true)); |
| 11818 |
| 11819 reads.push_back(CreateMockRead(*resp0, 1)); |
| 11820 reads.push_back(CreateMockRead(*body0, 2)); |
| 11821 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4)); |
| 11822 reads.push_back(CreateMockRead(*resp1, 5)); |
| 11823 reads.push_back(CreateMockRead(*body1, 6)); |
| 11824 reads.push_back(MockRead(ASYNC, OK, 7)); |
| 11825 } else { |
| 11826 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST)); |
| 11827 |
| 11828 writes.push_back(CreateMockWrite(*req1, 0)); |
| 11829 |
| 11830 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 11831 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 11832 |
| 11833 reads.push_back(CreateMockRead(*resp1, 1)); |
| 11834 reads.push_back(CreateMockRead(*body1, 2)); |
| 11835 reads.push_back(MockRead(ASYNC, OK, 3)); |
| 11836 } |
| 11837 |
| 11838 OrderedSocketData data(vector_as_array(&reads), reads.size(), |
| 11839 vector_as_array(&writes), writes.size()); |
| 11840 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 11841 |
| 11842 // Connection to the origin fails. |
| 11843 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); |
| 11844 StaticSocketDataProvider data_refused; |
| 11845 data_refused.set_connect_data(mock_connect); |
| 11846 session_deps_.socket_factory->AddSocketDataProvider(&data_refused); |
| 11847 |
| 11848 session_deps_.use_alternate_protocols = true; |
| 11849 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| 11850 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 11851 session->http_server_properties(); |
| 11852 AlternativeService alternative_service( |
| 11853 AlternateProtocolFromNextProto(GetParam()), alternative); |
| 11854 http_server_properties->SetAlternativeService(origin, alternative_service, |
| 11855 1.0); |
| 11856 |
| 11857 // First request to alternative. |
| 11858 if (pooling) { |
| 11859 scoped_ptr<HttpTransaction> trans0( |
| 11860 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 11861 HttpRequestInfo request0; |
| 11862 request0.method = "GET"; |
| 11863 request0.url = GURL(url0); |
| 11864 request0.load_flags = 0; |
| 11865 TestCompletionCallback callback0; |
| 11866 |
| 11867 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog()); |
| 11868 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 11869 rv = callback0.WaitForResult(); |
| 11870 EXPECT_EQ(OK, rv); |
| 11871 } |
| 11872 |
| 11873 // Second request to origin. |
| 11874 scoped_ptr<HttpTransaction> trans1( |
| 11875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 11876 HttpRequestInfo request1; |
| 11877 request1.method = "GET"; |
| 11878 request1.url = GURL(url1); |
| 11879 request1.load_flags = 0; |
| 11880 TestCompletionCallback callback1; |
| 11881 |
| 11882 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog()); |
| 11883 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 11884 rv = callback1.WaitForResult(); |
| 11885 if (valid) { |
| 11886 EXPECT_EQ(OK, rv); |
| 11887 } else { |
| 11888 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); |
| 11889 } |
| 11890 } |
| 11891 }; |
| 11892 |
| 11893 INSTANTIATE_TEST_CASE_P(NextProto, |
| 11894 AltSvcCertificateVerificationTest, |
| 11895 testing::Values(kProtoSPDY31, |
| 11896 kProtoSPDY4_14, |
| 11897 kProtoSPDY4)); |
| 11898 |
| 11899 // The alternative service host must exhibit a certificate that is valid for the |
| 11900 // origin host. Test that this is enforced when pooling to an existing |
| 11901 // connection. |
| 11902 TEST_P(AltSvcCertificateVerificationTest, PoolingValid) { |
| 11903 Run(true, true); |
| 11904 } |
| 11905 |
| 11906 TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) { |
| 11907 Run(true, false); |
| 11908 } |
| 11909 |
| 11910 // The alternative service host must exhibit a certificate that is valid for the |
| 11911 // origin host. Test that this is enforced when opening a new connection. |
| 11912 TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) { |
| 11913 Run(false, true); |
| 11914 } |
| 11915 |
| 11916 TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) { |
| 11917 Run(false, false); |
| 11918 } |
| 11919 |
11767 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { | 11920 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { |
11768 const std::string https_url = "https://www.google.com:8080/"; | 11921 const std::string https_url = "https://www.google.com:8080/"; |
11769 const std::string http_url = "http://www.google.com:8080/"; | 11922 const std::string http_url = "http://www.google.com:8080/"; |
11770 | 11923 |
11771 // SPDY GET for HTTPS URL (through CONNECT tunnel) | 11924 // SPDY GET for HTTPS URL (through CONNECT tunnel) |
11772 const HostPortPair host_port_pair("www.google.com", 8080); | 11925 const HostPortPair host_port_pair("www.google.com", 8080); |
11773 scoped_ptr<SpdyFrame> connect( | 11926 scoped_ptr<SpdyFrame> connect( |
11774 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair)); | 11927 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair)); |
11775 scoped_ptr<SpdyFrame> req1( | 11928 scoped_ptr<SpdyFrame> req1( |
11776 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); | 11929 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); |
(...skipping 2006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13783 ASSERT_TRUE(response); | 13936 ASSERT_TRUE(response); |
13784 ASSERT_TRUE(response->headers.get()); | 13937 ASSERT_TRUE(response->headers.get()); |
13785 | 13938 |
13786 EXPECT_EQ(101, response->headers->response_code()); | 13939 EXPECT_EQ(101, response->headers->response_code()); |
13787 | 13940 |
13788 trans.reset(); | 13941 trans.reset(); |
13789 session->CloseAllConnections(); | 13942 session->CloseAllConnections(); |
13790 } | 13943 } |
13791 | 13944 |
13792 } // namespace net | 13945 } // namespace net |
OLD | NEW |