| 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" |
| 17 #include "content/public/browser/client_certificate_delegate.h" | 19 #include "content/public/browser/client_certificate_delegate.h" |
| 18 #include "content/public/browser/resource_request_info.h" | 20 #include "content/public/browser/resource_request_info.h" |
| 19 #include "content/public/common/content_paths.h" | 21 #include "content/public/common/content_paths.h" |
| 20 #include "content/public/common/resource_response.h" | 22 #include "content/public/common/resource_response.h" |
| 21 #include "content/public/test/mock_resource_context.h" | 23 #include "content/public/test/mock_resource_context.h" |
| 22 #include "content/public/test/test_browser_context.h" | 24 #include "content/public/test/test_browser_context.h" |
| 23 #include "content/public/test/test_browser_thread_bundle.h" | 25 #include "content/public/test/test_browser_thread_bundle.h" |
| 24 #include "content/public/test/test_renderer_host.h" | 26 #include "content/public/test/test_renderer_host.h" |
| 25 #include "content/test/test_content_browser_client.h" | 27 #include "content/test/test_content_browser_client.h" |
| 26 #include "content/test/test_web_contents.h" | 28 #include "content/test/test_web_contents.h" |
| 27 #include "ipc/ipc_message.h" | 29 #include "ipc/ipc_message.h" |
| 28 #include "net/base/chunked_upload_data_stream.h" | 30 #include "net/base/chunked_upload_data_stream.h" |
| 29 #include "net/base/io_buffer.h" | 31 #include "net/base/io_buffer.h" |
| 30 #include "net/base/mock_file_stream.h" | 32 #include "net/base/mock_file_stream.h" |
| 31 #include "net/base/net_errors.h" | 33 #include "net/base/net_errors.h" |
| 32 #include "net/base/request_priority.h" | 34 #include "net/base/request_priority.h" |
| 35 #include "net/base/test_data_directory.h" |
| 33 #include "net/base/upload_bytes_element_reader.h" | 36 #include "net/base/upload_bytes_element_reader.h" |
| 34 #include "net/cert/x509_certificate.h" | 37 #include "net/cert/x509_certificate.h" |
| 35 #include "net/ssl/client_cert_store.h" | 38 #include "net/ssl/client_cert_store.h" |
| 36 #include "net/ssl/ssl_cert_request_info.h" | 39 #include "net/ssl/ssl_cert_request_info.h" |
| 40 #include "net/test/cert_test_util.h" |
| 37 #include "net/test/embedded_test_server/embedded_test_server.h" | 41 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 38 #include "net/url_request/url_request.h" | 42 #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" |
| 39 #include "net/url_request/url_request_job_factory.h" | 45 #include "net/url_request/url_request_job_factory.h" |
| 40 #include "net/url_request/url_request_job_factory_impl.h" | 46 #include "net/url_request/url_request_job_factory_impl.h" |
| 41 #include "net/url_request/url_request_test_job.h" | 47 #include "net/url_request/url_request_test_job.h" |
| 42 #include "net/url_request/url_request_test_util.h" | 48 #include "net/url_request/url_request_test_util.h" |
| 43 #include "storage/browser/blob/shareable_file_reference.h" | 49 #include "storage/browser/blob/shareable_file_reference.h" |
| 44 #include "testing/gtest/include/gtest/gtest.h" | 50 #include "testing/gtest/include/gtest/gtest.h" |
| 45 | 51 |
| 46 using storage::ShareableFileReference; | 52 using storage::ShareableFileReference; |
| 47 | 53 |
| 48 namespace content { | 54 namespace content { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 : public net::URLRequestJobFactory::ProtocolHandler { | 163 : public net::URLRequestJobFactory::ProtocolHandler { |
| 158 public: | 164 public: |
| 159 // URLRequestJobFactory::ProtocolHandler implementation: | 165 // URLRequestJobFactory::ProtocolHandler implementation: |
| 160 net::URLRequestJob* MaybeCreateJob( | 166 net::URLRequestJob* MaybeCreateJob( |
| 161 net::URLRequest* request, | 167 net::URLRequest* request, |
| 162 net::NetworkDelegate* network_delegate) const override { | 168 net::NetworkDelegate* network_delegate) const override { |
| 163 return new MockClientCertURLRequestJob(request, network_delegate); | 169 return new MockClientCertURLRequestJob(request, network_delegate); |
| 164 } | 170 } |
| 165 }; | 171 }; |
| 166 | 172 |
| 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 |
| 167 // Arbitrary read buffer size. | 230 // Arbitrary read buffer size. |
| 168 const int kReadBufSize = 1024; | 231 const int kReadBufSize = 1024; |
| 169 | 232 |
| 170 // Dummy implementation of ResourceHandler, instance of which is needed to | 233 // Dummy implementation of ResourceHandler, instance of which is needed to |
| 171 // initialize ResourceLoader. | 234 // initialize ResourceLoader. |
| 172 class ResourceHandlerStub : public ResourceHandler { | 235 class ResourceHandlerStub : public ResourceHandler { |
| 173 public: | 236 public: |
| 174 explicit ResourceHandlerStub(net::URLRequest* request) | 237 explicit ResourceHandlerStub(net::URLRequest* request) |
| 175 : ResourceHandler(request), | 238 : ResourceHandler(request), |
| 176 read_buffer_(new net::IOBuffer(kReadBufSize)), | 239 read_buffer_(new net::IOBuffer(kReadBufSize)), |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 scoped_ptr<ResourceLoader> loader_; | 594 scoped_ptr<ResourceLoader> loader_; |
| 532 }; | 595 }; |
| 533 | 596 |
| 534 class ClientCertResourceLoaderTest : public ResourceLoaderTest { | 597 class ClientCertResourceLoaderTest : public ResourceLoaderTest { |
| 535 protected: | 598 protected: |
| 536 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override { | 599 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override { |
| 537 return new MockClientCertJobProtocolHandler; | 600 return new MockClientCertJobProtocolHandler; |
| 538 } | 601 } |
| 539 }; | 602 }; |
| 540 | 603 |
| 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 |
| 541 // Tests that client certificates are requested with ClientCertStore lookup. | 627 // Tests that client certificates are requested with ClientCertStore lookup. |
| 542 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { | 628 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { |
| 543 // Set up the test client cert store. | 629 // Set up the test client cert store. |
| 544 int store_request_count; | 630 int store_request_count; |
| 545 std::vector<std::string> store_requested_authorities; | 631 std::vector<std::string> store_requested_authorities; |
| 546 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( | 632 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( |
| 547 new net::X509Certificate("test", "test", base::Time(), base::Time()))); | 633 new net::X509Certificate("test", "test", base::Time(), base::Time()))); |
| 548 scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( | 634 scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( |
| 549 dummy_certs, &store_request_count, &store_requested_authorities)); | 635 dummy_certs, &store_request_count, &store_requested_authorities)); |
| 550 resource_context_.SetClientCertStore(test_store.Pass()); | 636 resource_context_.SetClientCertStore(test_store.Pass()); |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 std::string contents; | 1072 std::string contents; |
| 987 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); | 1073 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); |
| 988 EXPECT_EQ(test_data(), contents); | 1074 EXPECT_EQ(test_data(), contents); |
| 989 | 1075 |
| 990 // Release the loader. The file should be gone now. | 1076 // Release the loader. The file should be gone now. |
| 991 ReleaseLoader(); | 1077 ReleaseLoader(); |
| 992 base::RunLoop().RunUntilIdle(); | 1078 base::RunLoop().RunUntilIdle(); |
| 993 EXPECT_FALSE(base::PathExists(temp_path())); | 1079 EXPECT_FALSE(base::PathExists(temp_path())); |
| 994 } | 1080 } |
| 995 | 1081 |
| 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 |
| 996 } // namespace content | 1120 } // namespace content |
| OLD | NEW |