| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "content/browser/loader/resource_loader.h" | 5 #include "content/browser/loader/resource_loader.h" |
| 6 | 6 |
| 7 #include "base/files/file.h" | 7 #include "base/files/file.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 13 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
| 14 #include "content/browser/browser_thread_impl.h" | 14 #include "content/browser/browser_thread_impl.h" |
| 15 #include "content/browser/loader/redirect_to_file_resource_handler.h" | 15 #include "content/browser/loader/redirect_to_file_resource_handler.h" |
| 16 #include "content/browser/loader/resource_loader_delegate.h" | 16 #include "content/browser/loader/resource_loader_delegate.h" |
| 17 #include "content/common/ssl_status_serialization.h" | |
| 18 #include "content/public/browser/cert_store.h" | |
| 19 #include "content/public/browser/client_certificate_delegate.h" | 17 #include "content/public/browser/client_certificate_delegate.h" |
| 20 #include "content/public/browser/resource_request_info.h" | 18 #include "content/public/browser/resource_request_info.h" |
| 21 #include "content/public/common/content_paths.h" | 19 #include "content/public/common/content_paths.h" |
| 22 #include "content/public/common/resource_response.h" | 20 #include "content/public/common/resource_response.h" |
| 23 #include "content/public/test/mock_resource_context.h" | 21 #include "content/public/test/mock_resource_context.h" |
| 24 #include "content/public/test/test_browser_context.h" | 22 #include "content/public/test/test_browser_context.h" |
| 25 #include "content/public/test/test_browser_thread_bundle.h" | 23 #include "content/public/test/test_browser_thread_bundle.h" |
| 26 #include "content/public/test/test_renderer_host.h" | 24 #include "content/public/test/test_renderer_host.h" |
| 27 #include "content/test/test_content_browser_client.h" | 25 #include "content/test/test_content_browser_client.h" |
| 28 #include "content/test/test_web_contents.h" | 26 #include "content/test/test_web_contents.h" |
| 29 #include "ipc/ipc_message.h" | 27 #include "ipc/ipc_message.h" |
| 30 #include "net/base/chunked_upload_data_stream.h" | 28 #include "net/base/chunked_upload_data_stream.h" |
| 31 #include "net/base/io_buffer.h" | 29 #include "net/base/io_buffer.h" |
| 32 #include "net/base/mock_file_stream.h" | 30 #include "net/base/mock_file_stream.h" |
| 33 #include "net/base/net_errors.h" | 31 #include "net/base/net_errors.h" |
| 34 #include "net/base/request_priority.h" | 32 #include "net/base/request_priority.h" |
| 35 #include "net/base/test_data_directory.h" | |
| 36 #include "net/base/upload_bytes_element_reader.h" | 33 #include "net/base/upload_bytes_element_reader.h" |
| 37 #include "net/cert/x509_certificate.h" | 34 #include "net/cert/x509_certificate.h" |
| 38 #include "net/ssl/client_cert_store.h" | 35 #include "net/ssl/client_cert_store.h" |
| 39 #include "net/ssl/ssl_cert_request_info.h" | 36 #include "net/ssl/ssl_cert_request_info.h" |
| 40 #include "net/test/cert_test_util.h" | |
| 41 #include "net/test/embedded_test_server/embedded_test_server.h" | 37 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 42 #include "net/url_request/url_request.h" | 38 #include "net/url_request/url_request.h" |
| 43 #include "net/url_request/url_request_filter.h" | |
| 44 #include "net/url_request/url_request_interceptor.h" | |
| 45 #include "net/url_request/url_request_job_factory.h" | 39 #include "net/url_request/url_request_job_factory.h" |
| 46 #include "net/url_request/url_request_job_factory_impl.h" | 40 #include "net/url_request/url_request_job_factory_impl.h" |
| 47 #include "net/url_request/url_request_test_job.h" | 41 #include "net/url_request/url_request_test_job.h" |
| 48 #include "net/url_request/url_request_test_util.h" | 42 #include "net/url_request/url_request_test_util.h" |
| 49 #include "storage/browser/blob/shareable_file_reference.h" | 43 #include "storage/browser/blob/shareable_file_reference.h" |
| 50 #include "testing/gtest/include/gtest/gtest.h" | 44 #include "testing/gtest/include/gtest/gtest.h" |
| 51 | 45 |
| 52 using storage::ShareableFileReference; | 46 using storage::ShareableFileReference; |
| 53 | 47 |
| 54 namespace content { | 48 namespace content { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 : public net::URLRequestJobFactory::ProtocolHandler { | 157 : public net::URLRequestJobFactory::ProtocolHandler { |
| 164 public: | 158 public: |
| 165 // URLRequestJobFactory::ProtocolHandler implementation: | 159 // URLRequestJobFactory::ProtocolHandler implementation: |
| 166 net::URLRequestJob* MaybeCreateJob( | 160 net::URLRequestJob* MaybeCreateJob( |
| 167 net::URLRequest* request, | 161 net::URLRequest* request, |
| 168 net::NetworkDelegate* network_delegate) const override { | 162 net::NetworkDelegate* network_delegate) const override { |
| 169 return new MockClientCertURLRequestJob(request, network_delegate); | 163 return new MockClientCertURLRequestJob(request, network_delegate); |
| 170 } | 164 } |
| 171 }; | 165 }; |
| 172 | 166 |
| 173 // Set up dummy values to use in test HTTPS requests. | |
| 174 | |
| 175 scoped_refptr<net::X509Certificate> GetTestCert() { | |
| 176 return net::ImportCertFromFile(net::GetTestCertsDirectory(), | |
| 177 "test_mail_google_com.pem"); | |
| 178 } | |
| 179 | |
| 180 const net::CertStatus kTestCertError = net::CERT_STATUS_DATE_INVALID; | |
| 181 const int kTestSecurityBits = 256; | |
| 182 // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA | |
| 183 const int kTestConnectionStatus = 0x300039; | |
| 184 | |
| 185 // A mock URLRequestJob which simulates an HTTPS request. | |
| 186 class MockHTTPSURLRequestJob : public net::URLRequestTestJob { | |
| 187 public: | |
| 188 MockHTTPSURLRequestJob(net::URLRequest* request, | |
| 189 net::NetworkDelegate* network_delegate, | |
| 190 const std::string& response_headers, | |
| 191 const std::string& response_data, | |
| 192 bool auto_advance) | |
| 193 : net::URLRequestTestJob(request, | |
| 194 network_delegate, | |
| 195 response_headers, | |
| 196 response_data, | |
| 197 auto_advance) {} | |
| 198 | |
| 199 // net::URLRequestTestJob: | |
| 200 void GetResponseInfo(net::HttpResponseInfo* info) override { | |
| 201 // Get the original response info, but override the SSL info. | |
| 202 net::URLRequestJob::GetResponseInfo(info); | |
| 203 info->ssl_info.cert = GetTestCert(); | |
| 204 info->ssl_info.cert_status = kTestCertError; | |
| 205 info->ssl_info.security_bits = kTestSecurityBits; | |
| 206 info->ssl_info.connection_status = kTestConnectionStatus; | |
| 207 } | |
| 208 | |
| 209 private: | |
| 210 ~MockHTTPSURLRequestJob() override {} | |
| 211 | |
| 212 DISALLOW_COPY_AND_ASSIGN(MockHTTPSURLRequestJob); | |
| 213 }; | |
| 214 | |
| 215 class MockHTTPSJobURLRequestInterceptor : public net::URLRequestInterceptor { | |
| 216 public: | |
| 217 MockHTTPSJobURLRequestInterceptor() {} | |
| 218 ~MockHTTPSJobURLRequestInterceptor() override {} | |
| 219 | |
| 220 // net::URLRequestInterceptor: | |
| 221 net::URLRequestJob* MaybeInterceptRequest( | |
| 222 net::URLRequest* request, | |
| 223 net::NetworkDelegate* network_delegate) const override { | |
| 224 return new MockHTTPSURLRequestJob(request, network_delegate, | |
| 225 net::URLRequestTestJob::test_headers(), | |
| 226 "dummy response", true); | |
| 227 } | |
| 228 }; | |
| 229 | |
| 230 // Arbitrary read buffer size. | 167 // Arbitrary read buffer size. |
| 231 const int kReadBufSize = 1024; | 168 const int kReadBufSize = 1024; |
| 232 | 169 |
| 233 // Dummy implementation of ResourceHandler, instance of which is needed to | 170 // Dummy implementation of ResourceHandler, instance of which is needed to |
| 234 // initialize ResourceLoader. | 171 // initialize ResourceLoader. |
| 235 class ResourceHandlerStub : public ResourceHandler { | 172 class ResourceHandlerStub : public ResourceHandler { |
| 236 public: | 173 public: |
| 237 explicit ResourceHandlerStub(net::URLRequest* request) | 174 explicit ResourceHandlerStub(net::URLRequest* request) |
| 238 : ResourceHandler(request), | 175 : ResourceHandler(request), |
| 239 read_buffer_(new net::IOBuffer(kReadBufSize)), | 176 read_buffer_(new net::IOBuffer(kReadBufSize)), |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 scoped_ptr<ResourceLoader> loader_; | 531 scoped_ptr<ResourceLoader> loader_; |
| 595 }; | 532 }; |
| 596 | 533 |
| 597 class ClientCertResourceLoaderTest : public ResourceLoaderTest { | 534 class ClientCertResourceLoaderTest : public ResourceLoaderTest { |
| 598 protected: | 535 protected: |
| 599 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override { | 536 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override { |
| 600 return new MockClientCertJobProtocolHandler; | 537 return new MockClientCertJobProtocolHandler; |
| 601 } | 538 } |
| 602 }; | 539 }; |
| 603 | 540 |
| 604 // A ResourceLoaderTest that intercepts https://example.test URLs and | |
| 605 // sets SSL info on the responses. | |
| 606 class HTTPSSecurityInfoResourceLoaderTest : public ResourceLoaderTest { | |
| 607 public: | |
| 608 HTTPSSecurityInfoResourceLoaderTest() | |
| 609 : ResourceLoaderTest(), test_https_url_("https://example.test") {} | |
| 610 | |
| 611 ~HTTPSSecurityInfoResourceLoaderTest() override {} | |
| 612 | |
| 613 const GURL& test_https_url() { return test_https_url_; } | |
| 614 | |
| 615 protected: | |
| 616 void SetUp() override { | |
| 617 ResourceLoaderTest::SetUp(); | |
| 618 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( | |
| 619 "https", "example.test", scoped_ptr<net::URLRequestInterceptor>( | |
| 620 new MockHTTPSJobURLRequestInterceptor)); | |
| 621 } | |
| 622 | |
| 623 private: | |
| 624 const GURL test_https_url_; | |
| 625 }; | |
| 626 | |
| 627 // Tests that client certificates are requested with ClientCertStore lookup. | 541 // Tests that client certificates are requested with ClientCertStore lookup. |
| 628 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { | 542 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { |
| 629 // Set up the test client cert store. | 543 // Set up the test client cert store. |
| 630 int store_request_count; | 544 int store_request_count; |
| 631 std::vector<std::string> store_requested_authorities; | 545 std::vector<std::string> store_requested_authorities; |
| 632 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( | 546 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( |
| 633 new net::X509Certificate("test", "test", base::Time(), base::Time()))); | 547 new net::X509Certificate("test", "test", base::Time(), base::Time()))); |
| 634 scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( | 548 scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( |
| 635 dummy_certs, &store_request_count, &store_requested_authorities)); | 549 dummy_certs, &store_request_count, &store_requested_authorities)); |
| 636 resource_context_.SetClientCertStore(test_store.Pass()); | 550 resource_context_.SetClientCertStore(test_store.Pass()); |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1072 std::string contents; | 986 std::string contents; |
| 1073 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); | 987 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); |
| 1074 EXPECT_EQ(test_data(), contents); | 988 EXPECT_EQ(test_data(), contents); |
| 1075 | 989 |
| 1076 // Release the loader. The file should be gone now. | 990 // Release the loader. The file should be gone now. |
| 1077 ReleaseLoader(); | 991 ReleaseLoader(); |
| 1078 base::RunLoop().RunUntilIdle(); | 992 base::RunLoop().RunUntilIdle(); |
| 1079 EXPECT_FALSE(base::PathExists(temp_path())); | 993 EXPECT_FALSE(base::PathExists(temp_path())); |
| 1080 } | 994 } |
| 1081 | 995 |
| 1082 // Test that an HTTPS resource has the expected security info attached | |
| 1083 // to it. | |
| 1084 TEST_F(HTTPSSecurityInfoResourceLoaderTest, SecurityInfoOnHTTPSResource) { | |
| 1085 // Start the request and wait for it to finish. | |
| 1086 scoped_ptr<net::URLRequest> request( | |
| 1087 resource_context_.GetRequestContext()->CreateRequest( | |
| 1088 test_https_url(), net::DEFAULT_PRIORITY, nullptr /* delegate */)); | |
| 1089 SetUpResourceLoader(request.Pass()); | |
| 1090 | |
| 1091 // Send the request and wait until it completes. | |
| 1092 loader_->StartRequest(); | |
| 1093 base::RunLoop().RunUntilIdle(); | |
| 1094 ASSERT_EQ(net::URLRequestStatus::SUCCESS, | |
| 1095 raw_ptr_to_request_->status().status()); | |
| 1096 ASSERT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | |
| 1097 | |
| 1098 ResourceResponse* response = raw_ptr_resource_handler_->response(); | |
| 1099 ASSERT_TRUE(response); | |
| 1100 | |
| 1101 // Deserialize the security info from the response and check that it | |
| 1102 // is as expected. | |
| 1103 SSLStatus deserialized; | |
| 1104 ASSERT_TRUE( | |
| 1105 DeserializeSecurityInfo(response->head.security_info, &deserialized)); | |
| 1106 | |
| 1107 // Expect a BROKEN security style because the cert status has errors. | |
| 1108 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN, | |
| 1109 deserialized.security_style); | |
| 1110 scoped_refptr<net::X509Certificate> cert; | |
| 1111 ASSERT_TRUE( | |
| 1112 CertStore::GetInstance()->RetrieveCert(deserialized.cert_id, &cert)); | |
| 1113 EXPECT_TRUE(cert->Equals(GetTestCert().get())); | |
| 1114 | |
| 1115 EXPECT_EQ(kTestCertError, deserialized.cert_status); | |
| 1116 EXPECT_EQ(kTestConnectionStatus, deserialized.connection_status); | |
| 1117 EXPECT_EQ(kTestSecurityBits, deserialized.security_bits); | |
| 1118 } | |
| 1119 | |
| 1120 } // namespace content | 996 } // namespace content |
| OLD | NEW |