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