1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_request_handler.h"
7 #include "base/run_loop.h"
8 #include "content/browser/fileapi/mock_url_request_delegate.h"
9 #include "content/browser/service_worker/embedded_worker_test_helper.h"
10 #include "content/browser/service_worker/service_worker_context_core.h"
11 #include "content/browser/service_worker/service_worker_provider_host.h"
12 #include "content/browser/service_worker/service_worker_registration.h"
13 #include "content/common/resource_request_body.h"
14 #include "content/common/service_worker/service_worker_utils.h"
15 #include "content/public/common/request_context_frame_type.h"
16 #include "content/public/common/request_context_type.h"
17 #include "content/public/common/resource_type.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "net/url_request/url_request_context.h"
20 #include "storage/browser/blob/blob_storage_context.h"
21 #include "testing/gtest/include/gtest/gtest.h"
27 int kMockRenderProcessId
= 1224;
28 int kMockProviderId
= 1;
30 void EmptyCallback() {
35 class ServiceWorkerRequestHandlerTest
: public testing::Test
{
37 ServiceWorkerRequestHandlerTest()
38 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {}
40 void SetUp() override
{
42 new EmbeddedWorkerTestHelper(base::FilePath(), kMockRenderProcessId
));
44 // A new unstored registration/version.
45 registration_
= new ServiceWorkerRegistration(
46 GURL("http://host/scope/"), 1L, context()->AsWeakPtr());
47 version_
= new ServiceWorkerVersion(registration_
.get(),
48 GURL("http://host/script.js"),
50 context()->AsWeakPtr());
53 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
54 kMockRenderProcessId
, MSG_ROUTING_NONE
, kMockProviderId
,
55 SERVICE_WORKER_PROVIDER_FOR_WINDOW
, context()->AsWeakPtr(), nullptr));
56 host
->SetDocumentUrl(GURL("http://host/scope/"));
57 provider_host_
= host
->AsWeakPtr();
58 context()->AddProviderHost(host
.Pass());
60 context()->storage()->LazyInitialize(base::Bind(&EmptyCallback
));
61 base::RunLoop().RunUntilIdle();
63 version_
->SetStatus(ServiceWorkerVersion::ACTIVATED
);
64 registration_
->SetActiveVersion(version_
);
65 context()->storage()->StoreRegistration(
68 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
69 provider_host_
->AssociateRegistration(registration_
.get(),
70 false /* notify_controllerchange */);
71 base::RunLoop().RunUntilIdle();
74 void TearDown() override
{
76 registration_
= nullptr;
80 ServiceWorkerContextCore
* context() const { return helper_
->context(); }
81 ServiceWorkerContextWrapper
* context_wrapper() const {
82 return helper_
->context_wrapper();
85 bool InitializeHandlerCheck(const std::string
& url
,
86 const std::string
& method
,
87 bool skip_service_worker
,
88 ResourceType resource_type
) {
89 const GURL
kDocUrl(url
);
90 scoped_ptr
<net::URLRequest
> request
= url_request_context_
.CreateRequest(
91 kDocUrl
, net::DEFAULT_PRIORITY
, &url_request_delegate_
);
92 request
->set_method(method
);
93 ServiceWorkerRequestHandler::InitializeHandler(
94 request
.get(), context_wrapper(), &blob_storage_context_
,
95 kMockRenderProcessId
, kMockProviderId
, skip_service_worker
,
96 FETCH_REQUEST_MODE_NO_CORS
, FETCH_CREDENTIALS_MODE_OMIT
,
97 FetchRedirectMode::FOLLOW_MODE
, resource_type
,
98 REQUEST_CONTEXT_TYPE_HYPERLINK
, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
,
100 return ServiceWorkerRequestHandler::GetHandler(request
.get()) != nullptr;
104 TestBrowserThreadBundle browser_thread_bundle_
;
105 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
106 scoped_refptr
<ServiceWorkerRegistration
> registration_
;
107 scoped_refptr
<ServiceWorkerVersion
> version_
;
108 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host_
;
109 net::URLRequestContext url_request_context_
;
110 MockURLRequestDelegate url_request_delegate_
;
111 storage::BlobStorageContext blob_storage_context_
;
114 TEST_F(ServiceWorkerRequestHandlerTest
, InitializeHandler
) {
115 // Cannot initialize a handler for non-secure origins.
116 EXPECT_FALSE(InitializeHandlerCheck(
117 "ftp://host/scope/doc", "GET", false, RESOURCE_TYPE_MAIN_FRAME
));
118 // HTTP is ok because it might redirect to HTTPS.
119 EXPECT_TRUE(InitializeHandlerCheck("http://host/scope/doc", "GET", false,
120 RESOURCE_TYPE_MAIN_FRAME
));
121 EXPECT_TRUE(InitializeHandlerCheck("https://host/scope/doc", "GET", false,
122 RESOURCE_TYPE_MAIN_FRAME
));
124 // OPTIONS is also supported. See crbug.com/434660.
125 EXPECT_TRUE(InitializeHandlerCheck(
126 "https://host/scope/doc", "OPTIONS", false, RESOURCE_TYPE_MAIN_FRAME
));
128 // Check provider host's URL after initializing a handler for main
130 provider_host_
->SetDocumentUrl(GURL(""));
131 EXPECT_FALSE(InitializeHandlerCheck(
132 "http://host/scope/doc", "GET", true, RESOURCE_TYPE_MAIN_FRAME
));
133 EXPECT_STREQ("http://host/scope/doc",
134 provider_host_
->document_url().spec().c_str());
135 EXPECT_FALSE(InitializeHandlerCheck(
136 "https://host/scope/doc", "GET", true, RESOURCE_TYPE_MAIN_FRAME
));
137 EXPECT_STREQ("https://host/scope/doc",
138 provider_host_
->document_url().spec().c_str());
140 // Check provider host's URL after initializing a handler for a subframe.
141 provider_host_
->SetDocumentUrl(GURL(""));
142 EXPECT_FALSE(InitializeHandlerCheck(
143 "http://host/scope/doc", "GET", true, RESOURCE_TYPE_SUB_FRAME
));
144 EXPECT_STREQ("http://host/scope/doc",
145 provider_host_
->document_url().spec().c_str());
146 EXPECT_FALSE(InitializeHandlerCheck(
147 "https://host/scope/doc", "GET", true, RESOURCE_TYPE_SUB_FRAME
));
148 EXPECT_STREQ("https://host/scope/doc",
149 provider_host_
->document_url().spec().c_str());
151 // Check provider host's URL after initializing a handler for an image.
152 provider_host_
->SetDocumentUrl(GURL(""));
153 EXPECT_FALSE(InitializeHandlerCheck(
154 "http://host/scope/doc", "GET", true, RESOURCE_TYPE_IMAGE
));
155 EXPECT_STREQ("", provider_host_
->document_url().spec().c_str());
156 EXPECT_FALSE(InitializeHandlerCheck(
157 "https://host/scope/doc", "GET", true, RESOURCE_TYPE_IMAGE
));
158 EXPECT_STREQ("", provider_host_
->document_url().spec().c_str());
161 } // namespace content