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)#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <map>
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string>
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/weak_ptr.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/time/time.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/content_export.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/service_worker/service_worker_status_code.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/service_worker/service_worker_types.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_byte_range.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/url_request/url_request_job.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class BlobDataHandle;
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class BlobStorageContext;
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content {
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class ResourceRequestBody;
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ServiceWorkerContextCore;
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ServiceWorkerFetchDispatcher;
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ServiceWorkerProviderHost;
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CONTENT_EXPORT ServiceWorkerURLRequestJob
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : public net::URLRequestJob,
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      public net::URLRequest::Delegate {
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ServiceWorkerURLRequestJob(
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::URLRequest* request,
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::NetworkDelegate* network_delegate,
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::WeakPtr<ServiceWorkerProviderHost> provider_host,
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      scoped_refptr<ResourceRequestBody> body);
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Sets the response type.
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void FallbackToNetwork();
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void ForwardToServiceWorker();
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool ShouldFallbackToNetwork() const {
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return response_type_ == FALLBACK_TO_NETWORK;
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool ShouldForwardToServiceWorker() const {
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return response_type_ == FORWARD_TO_SERVICE_WORKER;
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // net::URLRequestJob overrides:
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void Start() OVERRIDE;
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void Kill() OVERRIDE;
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual net::LoadState GetLoadState() const OVERRIDE;
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual bool GetCharset(std::string* charset) OVERRIDE;
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE;
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void GetLoadTimingInfo(
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::LoadTimingInfo* load_timing_info) const OVERRIDE;
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual int GetResponseCode() const OVERRIDE;
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetExtraRequestHeaders(
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const net::HttpRequestHeaders& headers) OVERRIDE;
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual bool ReadRawData(net::IOBuffer* buf,
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           int buf_size,
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           int *bytes_read) OVERRIDE;
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // net::URLRequest::Delegate overrides that read the blob from the
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ServiceWorkerFetchResponse.
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnReceivedRedirect(net::URLRequest* request,
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                  const net::RedirectInfo& redirect_info,
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  bool* defer_redirect) OVERRIDE;
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnAuthRequired(net::URLRequest* request,
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              net::AuthChallengeInfo* auth_info) OVERRIDE;
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnCertificateRequested(
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequest* request,
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::SSLCertRequestInfo* cert_request_info) OVERRIDE;
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnSSLCertificateError(net::URLRequest* request,
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     const net::SSLInfo& ssl_info,
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     bool fatal) OVERRIDE;
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnBeforeNetworkStart(net::URLRequest* request,
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    bool* defer) OVERRIDE;
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnReadCompleted(net::URLRequest* request,
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               int bytes_read) OVERRIDE;
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const net::HttpResponseInfo* http_info() const;
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void GetExtraResponseInfo(bool* was_fetched_via_service_worker,
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            GURL* original_url_via_service_worker,
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            base::TimeTicks* fetch_start_time,
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            base::TimeTicks* fetch_ready_time,
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            base::TimeTicks* fetch_end_time) const;
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected:
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~ServiceWorkerURLRequestJob();
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  enum ResponseType {
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOT_DETERMINED,
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FALLBACK_TO_NETWORK,
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FORWARD_TO_SERVICE_WORKER,
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We start processing the request if Start() is called AND response_type_
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // is determined.
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void MaybeStartRequest();
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void StartRequest();
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Creates ServiceWorkerFetchRequest from |request_| and |body_|.
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<ServiceWorkerFetchRequest> CreateFetchRequest();
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Creates BlobDataHandle of the request body from |body_|. This handle
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |request_body_blob_data_handle_| will be deleted when
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // ServiceWorkerURLRequestJob is deleted.
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool CreateRequestBodyBlob(std::string* blob_uuid, uint64* blob_size);
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // For FORWARD_TO_SERVICE_WORKER case.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void DidPrepareFetchEvent();
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DidDispatchFetchEvent(ServiceWorkerStatusCode status,
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             ServiceWorkerFetchEventResult fetch_result,
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             const ServiceWorkerResponse& response);
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Populates |http_response_headers_|.
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void CreateResponseHeader(int status_code,
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            const std::string& status_text,
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            const ServiceWorkerHeaderMap& headers);
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Creates |http_response_info_| using |http_response_headers_| and calls
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // NotifyHeadersComplete.
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void CommitResponseHeader();
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Creates and commits a response header indicating error.
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void DeliverErrorResponse();
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Timing info to show on the popup in Devtools' Network tab.
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  net::LoadTimingInfo load_timing_info_;
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks fetch_start_time_;
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks fetch_ready_time_;
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks fetch_end_time_;
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Time response_time_;
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ResponseType response_type_;
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool is_started_;
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  net::HttpByteRange byte_range_;
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<net::HttpResponseInfo> range_response_info_;
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<net::HttpResponseInfo> http_response_info_;
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Headers that have not yet been committed to |http_response_info_|.
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> http_response_headers_;
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GURL response_url_;
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Used when response type is FORWARD_TO_SERVICE_WORKER.
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<net::URLRequest> blob_request_;
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // ResourceRequestBody has a collection of BlobDataHandles attached to it
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // using the userdata mechanism. So we have to keep it not to free the blobs.
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<ResourceRequestBody> body_;
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<storage::BlobDataHandle> request_body_blob_data_handle_;
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WeakPtrFactory<ServiceWorkerURLRequestJob> weak_factory_;
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLRequestJob);
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace content
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
174