Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Side by Side Diff: content/browser/service_worker/foreign_fetch_request_handler_unittest.cc

Issue 2518523003: Limit timeout for foreign fetch events when triggered by another service worker. (Closed)
Patch Set: don't intercept worker main resource fetches Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/service_worker/foreign_fetch_request_handler.h" 5 #include "content/browser/service_worker/foreign_fetch_request_handler.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/test/simple_test_tick_clock.h"
9 #include "content/browser/browser_thread_impl.h" 10 #include "content/browser/browser_thread_impl.h"
11 #include "content/browser/fileapi/mock_url_request_delegate.h"
10 #include "content/browser/service_worker/embedded_worker_test_helper.h" 12 #include "content/browser/service_worker/embedded_worker_test_helper.h"
11 #include "content/browser/service_worker/service_worker_context_core.h" 13 #include "content/browser/service_worker/service_worker_context_core.h"
12 #include "content/browser/service_worker/service_worker_registration.h" 14 #include "content/browser/service_worker/service_worker_registration.h"
13 #include "content/browser/service_worker/service_worker_test_utils.h" 15 #include "content/browser/service_worker/service_worker_test_utils.h"
14 #include "content/browser/service_worker/service_worker_version.h" 16 #include "content/browser/service_worker/service_worker_version.h"
17 #include "content/common/service_worker/service_worker_utils.h"
15 #include "content/public/common/content_client.h" 18 #include "content/public/common/content_client.h"
16 #include "content/public/common/origin_trial_policy.h" 19 #include "content/public/common/origin_trial_policy.h"
17 #include "content/public/test/test_browser_thread_bundle.h" 20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "content/test/test_content_browser_client.h"
18 #include "net/http/http_response_info.h" 22 #include "net/http/http_response_info.h"
19 #include "net/test/cert_test_util.h" 23 #include "net/test/cert_test_util.h"
20 #include "net/test/test_data_directory.h" 24 #include "net/test/test_data_directory.h"
25 #include "net/url_request/url_request_context.h"
26 #include "storage/browser/blob/blob_storage_context.h"
21 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
22 28
23 namespace content { 29 namespace content {
24 30
25 namespace { 31 namespace {
26 32
27 // This is a sample public key for testing the API. The corresponding private 33 // This is a sample public key for testing the API. The corresponding private
28 // key (use this to generate new samples for this test file) is: 34 // key (use this to generate new samples for this test file) is:
29 // 35 //
30 // 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13, 36 // 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13,
31 // 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba, 37 // 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba,
32 // 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75, 38 // 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75,
33 // 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a, 39 // 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a,
34 // 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64, 40 // 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64,
35 // 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0 41 // 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0
36 const uint8_t kTestPublicKey[] = { 42 const uint8_t kTestPublicKey[] = {
37 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 43 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
38 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 44 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
39 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0, 45 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
40 }; 46 };
41 47
48 int kMockProviderId = 1;
49
50 const char* kValidUrl = "https://valid.example.com/foo/bar";
51
52 void EmptyCallback() {}
53
42 } // namespace 54 } // namespace
43 55
44 class ForeignFetchRequestHandlerTest : public testing::Test { 56 class ForeignFetchRequestHandlerTest : public testing::Test {
45 public: 57 public:
46 ForeignFetchRequestHandlerTest() 58 ForeignFetchRequestHandlerTest()
47 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) { 59 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {
48 SetContentClient(&test_content_client_); 60 SetContentClient(&test_content_client_);
61 SetBrowserClientForTesting(&test_content_browser_client_);
49 } 62 }
50 ~ForeignFetchRequestHandlerTest() override {} 63 ~ForeignFetchRequestHandlerTest() override {}
51 64
52 void SetUp() override { 65 void SetUp() override {
53 const GURL kScope("https://valid.example.com/scope/"); 66 const GURL kScope("https://valid.example.com/scope/");
54 const GURL kResource1("https://valid.example.com/scope/sw.js"); 67 const GURL kResource1("https://valid.example.com/scope/sw.js");
55 const int64_t kRegistrationId = 0; 68 const int64_t kRegistrationId = 0;
56 const int64_t kVersionId = 0; 69 const int64_t kVersionId = 0;
57 helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); 70 helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
58 registration_ = new ServiceWorkerRegistration(kScope, kRegistrationId, 71 registration_ = new ServiceWorkerRegistration(kScope, kRegistrationId,
59 context()->AsWeakPtr()); 72 context()->AsWeakPtr());
60 version_ = new ServiceWorkerVersion(registration_.get(), kResource1, 73 version_ = new ServiceWorkerVersion(registration_.get(), kResource1,
61 kVersionId, context()->AsWeakPtr()); 74 kVersionId, context()->AsWeakPtr());
75
76 version_->set_foreign_fetch_scopes({kScope});
77
78 // An empty host.
79 std::unique_ptr<ServiceWorkerProviderHost> host(
80 new ServiceWorkerProviderHost(
81 helper_->mock_render_process_id(), MSG_ROUTING_NONE,
82 kMockProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
83 ServiceWorkerProviderHost::FrameSecurityLevel::SECURE,
84 context()->AsWeakPtr(), nullptr));
85 host->SetDocumentUrl(GURL("https://host/scope/"));
86 provider_host_ = host->AsWeakPtr();
87 context()->AddProviderHost(std::move(host));
88
89 context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
90 base::RunLoop().RunUntilIdle();
91
92 std::vector<ServiceWorkerDatabase::ResourceRecord> records;
93 records.push_back(
94 ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
95 version_->script_cache_map()->SetResources(records);
96 version_->set_fetch_handler_existence(
97 ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
98 version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
99 registration_->SetActiveVersion(version_);
100 context()->storage()->StoreRegistration(
101 registration_.get(), version_.get(),
102 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
103 base::RunLoop().RunUntilIdle();
62 } 104 }
63 105
64 void TearDown() override { 106 void TearDown() override {
65 version_ = nullptr; 107 version_ = nullptr;
66 registration_ = nullptr; 108 registration_ = nullptr;
67 helper_.reset(); 109 helper_.reset();
68 base::RunLoop().RunUntilIdle(); 110 base::RunLoop().RunUntilIdle();
69 } 111 }
70 112
71 protected: 113 protected:
72 ServiceWorkerContextCore* context() const { return helper_->context(); } 114 ServiceWorkerContextCore* context() const { return helper_->context(); }
115 ServiceWorkerContextWrapper* context_wrapper() const {
116 return helper_->context_wrapper();
117 }
118 ServiceWorkerProviderHost* provider_host() const {
119 return provider_host_.get();
120 }
73 121
74 bool CheckOriginTrialToken(const ServiceWorkerVersion* const version) const { 122 bool CheckOriginTrialToken(const ServiceWorkerVersion* const version) const {
75 return ForeignFetchRequestHandler::CheckOriginTrialToken(version); 123 return ForeignFetchRequestHandler::CheckOriginTrialToken(version);
76 } 124 }
77 125
126 base::Optional<base::TimeDelta> timeout_for_request(
127 ForeignFetchRequestHandler* handler) {
128 return handler->timeout_;
129 }
130
78 ServiceWorkerVersion* version() const { return version_.get(); } 131 ServiceWorkerVersion* version() const { return version_.get(); }
79 132
80 static std::unique_ptr<net::HttpResponseInfo> CreateTestHttpResponseInfo() { 133 static std::unique_ptr<net::HttpResponseInfo> CreateTestHttpResponseInfo() {
81 std::unique_ptr<net::HttpResponseInfo> http_info( 134 std::unique_ptr<net::HttpResponseInfo> http_info(
82 base::MakeUnique<net::HttpResponseInfo>()); 135 base::MakeUnique<net::HttpResponseInfo>());
83 http_info->ssl_info.cert = 136 http_info->ssl_info.cert =
84 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); 137 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
85 DCHECK(http_info->ssl_info.is_valid()); 138 DCHECK(http_info->ssl_info.is_valid());
86 http_info->ssl_info.security_bits = 0x100; 139 http_info->ssl_info.security_bits = 0x100;
87 // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA 140 // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
88 http_info->ssl_info.connection_status = 0x300039; 141 http_info->ssl_info.connection_status = 0x300039;
89 http_info->headers = make_scoped_refptr(new net::HttpResponseHeaders("")); 142 http_info->headers = make_scoped_refptr(new net::HttpResponseHeaders(""));
90 return http_info; 143 return http_info;
91 } 144 }
92 145
146 ForeignFetchRequestHandler* InitializeHandler(const std::string& url,
147 ResourceType resource_type,
148 const char* initiator) {
149 request_ = url_request_context_.CreateRequest(
150 GURL(url), net::DEFAULT_PRIORITY, &url_request_delegate_);
151 if (initiator)
152 request_->set_initiator(url::Origin(GURL(initiator)));
153 ForeignFetchRequestHandler::InitializeHandler(
154 request_.get(), context_wrapper(), &blob_storage_context_,
155 helper_->mock_render_process_id(), kMockProviderId,
156 SkipServiceWorker::NONE, FETCH_REQUEST_MODE_CORS,
157 FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
158 resource_type, REQUEST_CONTEXT_TYPE_FETCH,
159 REQUEST_CONTEXT_FRAME_TYPE_NONE, nullptr,
160 true /* initiated_in_secure_context */);
161
162 return ForeignFetchRequestHandler::GetHandler(request_.get());
163 }
164
165 void CreateServiceWorkerTypeProviderHost() {
166 std::unique_ptr<ServiceWorkerProviderHost> host(
167 new ServiceWorkerProviderHost(
168 helper_->mock_render_process_id(), MSG_ROUTING_NONE,
169 kMockProviderId, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
170 ServiceWorkerProviderHost::FrameSecurityLevel::UNINITIALIZED,
171 context()->AsWeakPtr(), nullptr));
172 provider_host_ = host->AsWeakPtr();
173 context()->RemoveProviderHost(host->process_id(), host->provider_id());
174 context()->AddProviderHost(std::move(host));
175
176 scoped_refptr<ServiceWorkerRegistration> registration =
177 new ServiceWorkerRegistration(GURL("https://host/scope"), 1L,
178 context()->AsWeakPtr());
179 scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
180 registration.get(), GURL("https://host/script.js"), 1L,
181 context()->AsWeakPtr());
182
183 std::vector<ServiceWorkerDatabase::ResourceRecord> records;
184 records.push_back(
185 ServiceWorkerDatabase::ResourceRecord(10, version->script_url(), 100));
186 version->script_cache_map()->SetResources(records);
187 version->set_fetch_handler_existence(
188 ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
189 version->SetStatus(ServiceWorkerVersion::ACTIVATED);
190 registration->SetActiveVersion(version);
191 context()->storage()->StoreRegistration(
192 registration.get(), version.get(),
193 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
194 base::RunLoop().RunUntilIdle();
195
196 provider_host_->running_hosted_version_ = version;
197 }
198
93 private: 199 private:
94 class TestContentClient : public ContentClient { 200 class TestContentClient : public ContentClient {
95 public: 201 public:
96 // ContentRendererClient methods 202 // ContentRendererClient methods
97 OriginTrialPolicy* GetOriginTrialPolicy() override { 203 OriginTrialPolicy* GetOriginTrialPolicy() override {
98 return &origin_trial_policy_; 204 return &origin_trial_policy_;
99 } 205 }
100 206
101 private: 207 private:
102 class TestOriginTrialPolicy : public OriginTrialPolicy { 208 class TestOriginTrialPolicy : public OriginTrialPolicy {
103 public: 209 public:
104 base::StringPiece GetPublicKey() const override { 210 base::StringPiece GetPublicKey() const override {
105 return base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey), 211 return base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey),
106 arraysize(kTestPublicKey)); 212 arraysize(kTestPublicKey));
107 } 213 }
108 bool IsFeatureDisabled(base::StringPiece feature) const override { 214 bool IsFeatureDisabled(base::StringPiece feature) const override {
109 return false; 215 return false;
110 } 216 }
111 }; 217 };
112 218
113 TestOriginTrialPolicy origin_trial_policy_; 219 TestOriginTrialPolicy origin_trial_policy_;
114 }; 220 };
115 221
116 scoped_refptr<ServiceWorkerRegistration> registration_; 222 scoped_refptr<ServiceWorkerRegistration> registration_;
117 scoped_refptr<ServiceWorkerVersion> version_; 223 scoped_refptr<ServiceWorkerVersion> version_;
118 TestContentClient test_content_client_; 224 TestContentClient test_content_client_;
225 TestContentBrowserClient test_content_browser_client_;
119 std::unique_ptr<EmbeddedWorkerTestHelper> helper_; 226 std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
120 TestBrowserThreadBundle browser_thread_bundle_; 227 TestBrowserThreadBundle browser_thread_bundle_;
121 228
229 net::URLRequestContext url_request_context_;
230 MockURLRequestDelegate url_request_delegate_;
231 base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
232 storage::BlobStorageContext blob_storage_context_;
233 std::unique_ptr<net::URLRequest> request_;
234
122 DISALLOW_COPY_AND_ASSIGN(ForeignFetchRequestHandlerTest); 235 DISALLOW_COPY_AND_ASSIGN(ForeignFetchRequestHandlerTest);
123 }; 236 };
124 237
125 TEST_F(ForeignFetchRequestHandlerTest, CheckOriginTrialToken_NoToken) { 238 TEST_F(ForeignFetchRequestHandlerTest, CheckOriginTrialToken_NoToken) {
126 EXPECT_TRUE(CheckOriginTrialToken(version())); 239 EXPECT_TRUE(CheckOriginTrialToken(version()));
127 std::unique_ptr<net::HttpResponseInfo> http_info( 240 std::unique_ptr<net::HttpResponseInfo> http_info(
128 CreateTestHttpResponseInfo()); 241 CreateTestHttpResponseInfo());
129 version()->SetMainScriptHttpResponseInfo(*http_info); 242 version()->SetMainScriptHttpResponseInfo(*http_info);
130 EXPECT_FALSE(CheckOriginTrialToken(version())); 243 EXPECT_FALSE(CheckOriginTrialToken(version()));
131 } 244 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 const std::string kFeatureToken( 291 const std::string kFeatureToken(
179 "AgBgj4Zhwzn85LJw7rzh4ZFRFqp49+9Es2SrCwZdDcoqtqQEjbvui4SKLn6GqMpr4DynGfJh" 292 "AgBgj4Zhwzn85LJw7rzh4ZFRFqp49+9Es2SrCwZdDcoqtqQEjbvui4SKLn6GqMpr4DynGfJh"
180 "tIy9dpOuK8PVTwkAAABceyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5leGFtcGxlLmNvbTo0" 293 "tIy9dpOuK8PVTwkAAABceyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5leGFtcGxlLmNvbTo0"
181 "NDMiLCAiZmVhdHVyZSI6ICJGb3JlaWduRmV0Y2giLCAiZXhwaXJ5IjogMTAwMDAwMDAwMH0" 294 "NDMiLCAiZmVhdHVyZSI6ICJGb3JlaWduRmV0Y2giLCAiZXhwaXJ5IjogMTAwMDAwMDAwMH0"
182 "="); 295 "=");
183 http_info->headers->AddHeader(kOriginTrial + kFeatureToken); 296 http_info->headers->AddHeader(kOriginTrial + kFeatureToken);
184 version()->SetMainScriptHttpResponseInfo(*http_info); 297 version()->SetMainScriptHttpResponseInfo(*http_info);
185 EXPECT_FALSE(CheckOriginTrialToken(version())); 298 EXPECT_FALSE(CheckOriginTrialToken(version()));
186 } 299 }
187 300
301 TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_Success) {
302 EXPECT_TRUE(InitializeHandler(kValidUrl, RESOURCE_TYPE_IMAGE,
303 nullptr /* initiator */));
304 }
305
306 TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_WrongResourceType) {
307 EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_MAIN_FRAME,
308 nullptr /* initiator */));
309 EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_SUB_FRAME,
310 nullptr /* initiator */));
311 EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_WORKER,
312 nullptr /* initiator */));
313 EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_SHARED_WORKER,
314 nullptr /* initiator */));
315 EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_SERVICE_WORKER,
316 nullptr /* initiator */));
317 }
318
319 TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_SameOriginRequest) {
320 EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_IMAGE,
321 kValidUrl /* initiator */));
322 }
323
324 TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_NoRegisteredHandlers) {
325 EXPECT_FALSE(InitializeHandler("https://invalid.example.com/foo",
326 RESOURCE_TYPE_IMAGE, nullptr /* initiator */));
327 }
328
329 TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_TimeoutBehavior) {
330 ForeignFetchRequestHandler* handler =
331 InitializeHandler("https://valid.example.com/foo", RESOURCE_TYPE_IMAGE,
332 nullptr /* initiator */);
333 ASSERT_TRUE(handler);
334
335 EXPECT_EQ(base::nullopt, timeout_for_request(handler));
336
337 CreateServiceWorkerTypeProviderHost();
338 ServiceWorkerVersion* version = provider_host()->running_hosted_version();
339
340 // Set mock clock on version to check timeout behavior.
341 base::SimpleTestTickClock* tick_clock = new base::SimpleTestTickClock();
342 tick_clock->SetNowTicks(base::TimeTicks::Now());
343 version->SetTickClockForTesting(base::WrapUnique(tick_clock));
344
345 // Make sure worker has a non-zero timeout.
346 version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
347 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
348 base::RunLoop().RunUntilIdle();
349 version->StartRequestWithCustomTimeout(
350 ServiceWorkerMetrics::EventType::ACTIVATE,
351 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback),
352 base::TimeDelta::FromSeconds(10), ServiceWorkerVersion::KILL_ON_TIMEOUT);
353
354 // Advance clock by a couple seconds.
355 tick_clock->Advance(base::TimeDelta::FromSeconds(4));
356 base::TimeDelta remaining_time = version->remaining_timeout();
357 EXPECT_EQ(base::TimeDelta::FromSeconds(6), remaining_time);
358
359 // Make sure new request only gets remaining timeout.
360 handler = InitializeHandler("https://valid.example.com/foo",
361 RESOURCE_TYPE_IMAGE, nullptr /* initiator */);
362 ASSERT_TRUE(handler);
363 EXPECT_EQ(remaining_time, timeout_for_request(handler));
364 }
365
188 } // namespace content 366 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698