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 11829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11860 HttpNetworkTransaction trans2(MEDIUM, session.get()); | 11861 HttpNetworkTransaction trans2(MEDIUM, session.get()); |
11861 TestCompletionCallback callback2; | 11862 TestCompletionCallback callback2; |
11862 EXPECT_EQ(ERR_IO_PENDING, | 11863 EXPECT_EQ(ERR_IO_PENDING, |
11863 trans2.Start(&request2, callback2.callback(), BoundNetLog())); | 11864 trans2.Start(&request2, callback2.callback(), BoundNetLog())); |
11864 base::MessageLoop::current()->RunUntilIdle(); | 11865 base::MessageLoop::current()->RunUntilIdle(); |
11865 | 11866 |
11866 EXPECT_EQ(OK, callback2.WaitForResult()); | 11867 EXPECT_EQ(OK, callback2.WaitForResult()); |
11867 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); | 11868 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); |
11868 } | 11869 } |
11869 | 11870 |
| 11871 class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest { |
| 11872 public: |
| 11873 void Run(bool pooling, bool valid) { |
| 11874 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org", |
| 11875 443); |
| 11876 HostPortPair alternative("www.example.org", 443); |
| 11877 |
| 11878 base::FilePath certs_dir = GetTestCertsDirectory(); |
| 11879 scoped_refptr<X509Certificate> cert( |
| 11880 ImportCertFromFile(certs_dir, "spdy_pooling.pem")); |
| 11881 ASSERT_TRUE(cert.get()); |
| 11882 bool common_name_fallback_used; |
| 11883 EXPECT_EQ(valid, |
| 11884 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used)); |
| 11885 EXPECT_TRUE( |
| 11886 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used)); |
| 11887 SSLSocketDataProvider ssl(ASYNC, OK); |
| 11888 ssl.SetNextProto(GetParam()); |
| 11889 ssl.cert = cert; |
| 11890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); |
| 11891 |
| 11892 // If pooling, then start a request to alternative first to create a |
| 11893 // SpdySession. |
| 11894 std::string url0 = "https://www.example.org:443"; |
| 11895 // Second request to origin, which has an alternative service, and could |
| 11896 // open a connection to the alternative host or pool to the existing one. |
| 11897 std::string url1("https://"); |
| 11898 url1.append(origin.host()); |
| 11899 url1.append(":443"); |
| 11900 |
| 11901 scoped_ptr<SpdyFrame> req0; |
| 11902 scoped_ptr<SpdyFrame> req1; |
| 11903 scoped_ptr<SpdyFrame> resp0; |
| 11904 scoped_ptr<SpdyFrame> body0; |
| 11905 scoped_ptr<SpdyFrame> resp1; |
| 11906 scoped_ptr<SpdyFrame> body1; |
| 11907 std::vector<MockWrite> writes; |
| 11908 std::vector<MockRead> reads; |
| 11909 |
| 11910 if (pooling) { |
| 11911 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST)); |
| 11912 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST)); |
| 11913 |
| 11914 writes.push_back(CreateMockWrite(*req0, 0)); |
| 11915 writes.push_back(CreateMockWrite(*req1, 3)); |
| 11916 |
| 11917 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 11918 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 11919 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); |
| 11920 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true)); |
| 11921 |
| 11922 reads.push_back(CreateMockRead(*resp0, 1)); |
| 11923 reads.push_back(CreateMockRead(*body0, 2)); |
| 11924 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4)); |
| 11925 reads.push_back(CreateMockRead(*resp1, 5)); |
| 11926 reads.push_back(CreateMockRead(*body1, 6)); |
| 11927 reads.push_back(MockRead(ASYNC, OK, 7)); |
| 11928 } else { |
| 11929 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST)); |
| 11930 |
| 11931 writes.push_back(CreateMockWrite(*req1, 0)); |
| 11932 |
| 11933 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 11934 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 11935 |
| 11936 reads.push_back(CreateMockRead(*resp1, 1)); |
| 11937 reads.push_back(CreateMockRead(*body1, 2)); |
| 11938 reads.push_back(MockRead(ASYNC, OK, 3)); |
| 11939 } |
| 11940 |
| 11941 OrderedSocketData data(vector_as_array(&reads), reads.size(), |
| 11942 vector_as_array(&writes), writes.size()); |
| 11943 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 11944 |
| 11945 // Connection to the origin fails. |
| 11946 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); |
| 11947 StaticSocketDataProvider data_refused; |
| 11948 data_refused.set_connect_data(mock_connect); |
| 11949 session_deps_.socket_factory->AddSocketDataProvider(&data_refused); |
| 11950 |
| 11951 session_deps_.use_alternate_protocols = true; |
| 11952 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| 11953 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 11954 session->http_server_properties(); |
| 11955 AlternativeService alternative_service( |
| 11956 AlternateProtocolFromNextProto(GetParam()), alternative); |
| 11957 http_server_properties->SetAlternativeService(origin, alternative_service, |
| 11958 1.0); |
| 11959 |
| 11960 // First request to alternative. |
| 11961 if (pooling) { |
| 11962 scoped_ptr<HttpTransaction> trans0( |
| 11963 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 11964 HttpRequestInfo request0; |
| 11965 request0.method = "GET"; |
| 11966 request0.url = GURL(url0); |
| 11967 request0.load_flags = 0; |
| 11968 TestCompletionCallback callback0; |
| 11969 |
| 11970 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog()); |
| 11971 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 11972 rv = callback0.WaitForResult(); |
| 11973 EXPECT_EQ(OK, rv); |
| 11974 } |
| 11975 |
| 11976 // Second request to origin. |
| 11977 scoped_ptr<HttpTransaction> trans1( |
| 11978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| 11979 HttpRequestInfo request1; |
| 11980 request1.method = "GET"; |
| 11981 request1.url = GURL(url1); |
| 11982 request1.load_flags = 0; |
| 11983 TestCompletionCallback callback1; |
| 11984 |
| 11985 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog()); |
| 11986 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 11987 rv = callback1.WaitForResult(); |
| 11988 if (valid) { |
| 11989 EXPECT_EQ(OK, rv); |
| 11990 } else { |
| 11991 if (pooling) { |
| 11992 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv); |
| 11993 } else { |
| 11994 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv); |
| 11995 } |
| 11996 } |
| 11997 } |
| 11998 }; |
| 11999 |
| 12000 INSTANTIATE_TEST_CASE_P(NextProto, |
| 12001 AltSvcCertificateVerificationTest, |
| 12002 testing::Values(kProtoSPDY31, |
| 12003 kProtoSPDY4_14, |
| 12004 kProtoSPDY4)); |
| 12005 |
| 12006 // The alternative service host must exhibit a certificate that is valid for the |
| 12007 // origin host. Test that this is enforced when pooling to an existing |
| 12008 // connection. |
| 12009 TEST_P(AltSvcCertificateVerificationTest, PoolingValid) { |
| 12010 Run(true, true); |
| 12011 } |
| 12012 |
| 12013 TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) { |
| 12014 Run(true, false); |
| 12015 } |
| 12016 |
| 12017 // The alternative service host must exhibit a certificate that is valid for the |
| 12018 // origin host. Test that this is enforced when opening a new connection. |
| 12019 TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) { |
| 12020 Run(false, true); |
| 12021 } |
| 12022 |
| 12023 TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) { |
| 12024 Run(false, false); |
| 12025 } |
| 12026 |
11870 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { | 12027 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { |
11871 const std::string https_url = "https://www.example.org:8080/"; | 12028 const std::string https_url = "https://www.example.org:8080/"; |
11872 const std::string http_url = "http://www.example.org:8080/"; | 12029 const std::string http_url = "http://www.example.org:8080/"; |
11873 | 12030 |
11874 // SPDY GET for HTTPS URL (through CONNECT tunnel) | 12031 // SPDY GET for HTTPS URL (through CONNECT tunnel) |
11875 const HostPortPair host_port_pair("www.example.org", 8080); | 12032 const HostPortPair host_port_pair("www.example.org", 8080); |
11876 scoped_ptr<SpdyFrame> connect( | 12033 scoped_ptr<SpdyFrame> connect( |
11877 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair)); | 12034 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair)); |
11878 scoped_ptr<SpdyFrame> req1( | 12035 scoped_ptr<SpdyFrame> req1( |
11879 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); | 12036 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); |
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13889 ASSERT_TRUE(response); | 14046 ASSERT_TRUE(response); |
13890 ASSERT_TRUE(response->headers.get()); | 14047 ASSERT_TRUE(response->headers.get()); |
13891 | 14048 |
13892 EXPECT_EQ(101, response->headers->response_code()); | 14049 EXPECT_EQ(101, response->headers->response_code()); |
13893 | 14050 |
13894 trans.reset(); | 14051 trans.reset(); |
13895 session->CloseAllConnections(); | 14052 session->CloseAllConnections(); |
13896 } | 14053 } |
13897 | 14054 |
13898 } // namespace net | 14055 } // namespace net |
OLD | NEW |