• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/browser/service_worker/service_worker_request_handler.h"
6 
7 #include <string>
8 
9 #include "content/browser/service_worker/service_worker_context_core.h"
10 #include "content/browser/service_worker/service_worker_context_wrapper.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/browser/service_worker/service_worker_url_request_job.h"
14 #include "content/browser/service_worker/service_worker_utils.h"
15 #include "content/common/resource_request_body.h"
16 #include "content/common/service_worker/service_worker_types.h"
17 #include "net/base/net_util.h"
18 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_interceptor.h"
20 #include "storage/browser/blob/blob_storage_context.h"
21 
22 namespace content {
23 
24 namespace {
25 
26 int kUserDataKey;  // Key value is not important.
27 
28 class ServiceWorkerRequestInterceptor
29     : public net::URLRequestInterceptor {
30  public:
ServiceWorkerRequestInterceptor()31   ServiceWorkerRequestInterceptor() {}
~ServiceWorkerRequestInterceptor()32   virtual ~ServiceWorkerRequestInterceptor() {}
MaybeInterceptRequest(net::URLRequest * request,net::NetworkDelegate * network_delegate) const33   virtual net::URLRequestJob* MaybeInterceptRequest(
34       net::URLRequest* request,
35       net::NetworkDelegate* network_delegate) const OVERRIDE {
36     ServiceWorkerRequestHandler* handler =
37         ServiceWorkerRequestHandler::GetHandler(request);
38     if (!handler)
39       return NULL;
40     return handler->MaybeCreateJob(request, network_delegate);
41   }
42 
43  private:
44   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestInterceptor);
45 };
46 
47 // This is work around to avoid hijacking CORS preflight.
48 // TODO(horo): Remove this check when we implement "HTTP fetch" correctly.
49 // http://fetch.spec.whatwg.org/#concept-http-fetch
IsMethodSupportedForServiceWroker(const std::string & method)50 bool IsMethodSupportedForServiceWroker(const std::string& method) {
51   return method != "OPTIONS";
52 }
53 
54 }  // namespace
55 
InitializeHandler(net::URLRequest * request,ServiceWorkerContextWrapper * context_wrapper,storage::BlobStorageContext * blob_storage_context,int process_id,int provider_id,bool skip_service_worker,ResourceType resource_type,scoped_refptr<ResourceRequestBody> body)56 void ServiceWorkerRequestHandler::InitializeHandler(
57     net::URLRequest* request,
58     ServiceWorkerContextWrapper* context_wrapper,
59     storage::BlobStorageContext* blob_storage_context,
60     int process_id,
61     int provider_id,
62     bool skip_service_worker,
63     ResourceType resource_type,
64     scoped_refptr<ResourceRequestBody> body) {
65   if (!request->url().SchemeIsHTTPOrHTTPS() ||
66       !IsMethodSupportedForServiceWroker(request->method())) {
67     return;
68   }
69 
70   if (!context_wrapper || !context_wrapper->context() ||
71       provider_id == kInvalidServiceWorkerProviderId) {
72     return;
73   }
74 
75   ServiceWorkerProviderHost* provider_host =
76       context_wrapper->context()->GetProviderHost(process_id, provider_id);
77   if (!provider_host || !provider_host->IsContextAlive())
78     return;
79 
80   if (skip_service_worker) {
81     if (ServiceWorkerUtils::IsMainResourceType(resource_type))
82       provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url()));
83     return;
84   }
85 
86   scoped_ptr<ServiceWorkerRequestHandler> handler(
87       provider_host->CreateRequestHandler(
88           resource_type, blob_storage_context->AsWeakPtr(), body));
89   if (!handler)
90     return;
91 
92   request->SetUserData(&kUserDataKey, handler.release());
93 }
94 
GetHandler(net::URLRequest * request)95 ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler(
96     net::URLRequest* request) {
97   return reinterpret_cast<ServiceWorkerRequestHandler*>(
98       request->GetUserData(&kUserDataKey));
99 }
100 
101 scoped_ptr<net::URLRequestInterceptor>
CreateInterceptor()102 ServiceWorkerRequestHandler::CreateInterceptor() {
103   return scoped_ptr<net::URLRequestInterceptor>(
104       new ServiceWorkerRequestInterceptor);
105 }
106 
~ServiceWorkerRequestHandler()107 ServiceWorkerRequestHandler::~ServiceWorkerRequestHandler() {
108 }
109 
ServiceWorkerRequestHandler(base::WeakPtr<ServiceWorkerContextCore> context,base::WeakPtr<ServiceWorkerProviderHost> provider_host,base::WeakPtr<storage::BlobStorageContext> blob_storage_context,ResourceType resource_type)110 ServiceWorkerRequestHandler::ServiceWorkerRequestHandler(
111     base::WeakPtr<ServiceWorkerContextCore> context,
112     base::WeakPtr<ServiceWorkerProviderHost> provider_host,
113     base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
114     ResourceType resource_type)
115     : context_(context),
116       provider_host_(provider_host),
117       blob_storage_context_(blob_storage_context),
118       resource_type_(resource_type) {
119 }
120 
121 }  // namespace content
122