Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_request_handler.cc
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 "content/public/browser/resource_context.h"
18 #include "net/base/net_util.h"
19 #include "net/url_request/url_request.h"
20 #include "net/url_request/url_request_interceptor.h"
21 #include "storage/browser/blob/blob_storage_context.h"
22
23 namespace content {
24
25 namespace {
26
27 int kUserDataKey;  // Key value is not important.
28
29 class ServiceWorkerRequestInterceptor
30     : public net::URLRequestInterceptor {
31  public:
32   explicit ServiceWorkerRequestInterceptor(ResourceContext* resource_context)
33       : resource_context_(resource_context) {}
34   ~ServiceWorkerRequestInterceptor() override {}
35   net::URLRequestJob* MaybeInterceptRequest(
36       net::URLRequest* request,
37       net::NetworkDelegate* network_delegate) const override {
38     ServiceWorkerRequestHandler* handler =
39         ServiceWorkerRequestHandler::GetHandler(request);
40     if (!handler)
41       return NULL;
42     return handler->MaybeCreateJob(
43         request, network_delegate, resource_context_);
44   }
45
46  private:
47   ResourceContext* resource_context_;
48   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestInterceptor);
49 };
50
51 // This is work around to avoid hijacking CORS preflight.
52 // TODO(horo): Remove this check when we implement "HTTP fetch" correctly.
53 // http://fetch.spec.whatwg.org/#concept-http-fetch
54 bool IsMethodSupportedForServiceWorker(const std::string& method) {
55   return method != "OPTIONS";
56 }
57
58 }  // namespace
59
60 void ServiceWorkerRequestHandler::InitializeHandler(
61     net::URLRequest* request,
62     ServiceWorkerContextWrapper* context_wrapper,
63     storage::BlobStorageContext* blob_storage_context,
64     int process_id,
65     int provider_id,
66     bool skip_service_worker,
67     FetchRequestMode request_mode,
68     FetchCredentialsMode credentials_mode,
69     ResourceType resource_type,
70     RequestContextType request_context_type,
71     RequestContextFrameType frame_type,
72     scoped_refptr<ResourceRequestBody> body) {
73   if (!request->url().SchemeIsHTTPOrHTTPS() ||
74       !IsMethodSupportedForServiceWorker(request->method())) {
75     return;
76   }
77
78   if (!context_wrapper || !context_wrapper->context() ||
79       provider_id == kInvalidServiceWorkerProviderId) {
80     return;
81   }
82
83   ServiceWorkerProviderHost* provider_host =
84       context_wrapper->context()->GetProviderHost(process_id, provider_id);
85   if (!provider_host || !provider_host->IsContextAlive())
86     return;
87
88   if (skip_service_worker) {
89     if (ServiceWorkerUtils::IsMainResourceType(resource_type)) {
90       provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url()));
91       provider_host->SetTopmostFrameUrl(request->first_party_for_cookies());
92     }
93     return;
94   }
95
96   scoped_ptr<ServiceWorkerRequestHandler> handler(
97       provider_host->CreateRequestHandler(request_mode,
98                                           credentials_mode,
99                                           resource_type,
100                                           request_context_type,
101                                           frame_type,
102                                           blob_storage_context->AsWeakPtr(),
103                                           body));
104   if (!handler)
105     return;
106
107   request->SetUserData(&kUserDataKey, handler.release());
108 }
109
110 ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler(
111     net::URLRequest* request) {
112   return static_cast<ServiceWorkerRequestHandler*>(
113       request->GetUserData(&kUserDataKey));
114 }
115
116 scoped_ptr<net::URLRequestInterceptor>
117 ServiceWorkerRequestHandler::CreateInterceptor(
118     ResourceContext* resource_context) {
119   return scoped_ptr<net::URLRequestInterceptor>(
120       new ServiceWorkerRequestInterceptor(resource_context));
121 }
122
123 bool ServiceWorkerRequestHandler::IsControlledByServiceWorker(
124     net::URLRequest* request) {
125   ServiceWorkerRequestHandler* handler = GetHandler(request);
126   if (!handler || !handler->provider_host_)
127     return false;
128   return handler->provider_host_->associated_registration() ||
129          handler->provider_host_->running_hosted_version();
130 }
131
132 ServiceWorkerRequestHandler::~ServiceWorkerRequestHandler() {
133 }
134
135 ServiceWorkerRequestHandler::ServiceWorkerRequestHandler(
136     base::WeakPtr<ServiceWorkerContextCore> context,
137     base::WeakPtr<ServiceWorkerProviderHost> provider_host,
138     base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
139     ResourceType resource_type)
140     : context_(context),
141       provider_host_(provider_host),
142       blob_storage_context_(blob_storage_context),
143       resource_type_(resource_type) {
144 }
145
146 }  // namespace content