Home | History | Annotate | Download | only in service_worker
      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:
     31   ServiceWorkerRequestInterceptor() {}
     32   virtual ~ServiceWorkerRequestInterceptor() {}
     33   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
     50 bool IsMethodSupportedForServiceWroker(const std::string& method) {
     51   return method != "OPTIONS";
     52 }
     53 
     54 }  // namespace
     55 
     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 
     95 ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler(
     96     net::URLRequest* request) {
     97   return reinterpret_cast<ServiceWorkerRequestHandler*>(
     98       request->GetUserData(&kUserDataKey));
     99 }
    100 
    101 scoped_ptr<net::URLRequestInterceptor>
    102 ServiceWorkerRequestHandler::CreateInterceptor() {
    103   return scoped_ptr<net::URLRequestInterceptor>(
    104       new ServiceWorkerRequestInterceptor);
    105 }
    106 
    107 ServiceWorkerRequestHandler::~ServiceWorkerRequestHandler() {
    108 }
    109 
    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