1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_request_handler.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_wrapper.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_provider_host.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_url_request_job.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_utils.h" 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/common/resource_request_body.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/service_worker/service_worker_types.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_util.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/url_request/url_request.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request_interceptor.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_storage_context.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int kUserDataKey; // Key value is not important. 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ServiceWorkerRequestInterceptor 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : public net::URLRequestInterceptor { 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerRequestInterceptor() {} 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~ServiceWorkerRequestInterceptor() {} 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual net::URLRequestJob* MaybeInterceptRequest( 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request, 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::NetworkDelegate* network_delegate) const OVERRIDE { 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerRequestHandler* handler = 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerRequestHandler::GetHandler(request); 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!handler) 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return handler->MaybeCreateJob(request, network_delegate); 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestInterceptor); 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This is work around to avoid hijacking CORS preflight. 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(horo): Remove this check when we implement "HTTP fetch" correctly. 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// http://fetch.spec.whatwg.org/#concept-http-fetch 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool IsMethodSupportedForServiceWroker(const std::string& method) { 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return method != "OPTIONS"; 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerRequestHandler::InitializeHandler( 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request, 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerContextWrapper* context_wrapper, 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::BlobStorageContext* blob_storage_context, 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int process_id, 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int provider_id, 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool skip_service_worker, 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ResourceType resource_type, 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<ResourceRequestBody> body) { 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!request->url().SchemeIsHTTPOrHTTPS() || 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !IsMethodSupportedForServiceWroker(request->method())) { 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!context_wrapper || !context_wrapper->context() || 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) provider_id == kInvalidServiceWorkerProviderId) { 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerProviderHost* provider_host = 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context_wrapper->context()->GetProviderHost(process_id, provider_id); 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!provider_host || !provider_host->IsContextAlive()) 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (skip_service_worker) { 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ServiceWorkerUtils::IsMainResourceType(resource_type)) 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url())); 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<ServiceWorkerRequestHandler> handler( 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) provider_host->CreateRequestHandler( 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) resource_type, blob_storage_context->AsWeakPtr(), body)); 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!handler) 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->SetUserData(&kUserDataKey, handler.release()); 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler( 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request) { 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return reinterpret_cast<ServiceWorkerRequestHandler*>( 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->GetUserData(&kUserDataKey)); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<net::URLRequestInterceptor> 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerRequestHandler::CreateInterceptor() { 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<net::URLRequestInterceptor>( 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new ServiceWorkerRequestInterceptor); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerRequestHandler::~ServiceWorkerRequestHandler() { 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerRequestHandler::ServiceWorkerRequestHandler( 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtr<ServiceWorkerContextCore> context, 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtr<ServiceWorkerProviderHost> provider_host, 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<storage::BlobStorageContext> blob_storage_context, 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType resource_type) 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : context_(context), 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) provider_host_(provider_host), 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_storage_context_(blob_storage_context), 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu resource_type_(resource_type) { 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace content 122