1// Copyright (c) 2011 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// The intent of this file is to provide a type-neutral abstraction between
6// Chrome and WebKit for resource loading. This pure-virtual interface is
7// implemented by the embedder, which also provides a factory method Create
8// to instantiate this object.
9//
10// One of these objects will be created by WebKit for each request. WebKit
11// will own the pointer to the bridge, and will delete it when the request is
12// no longer needed.
13//
14// In turn, the bridge's owner on the WebKit end will implement the Peer
15// interface, which we will use to communicate notifications back.
16
17#ifndef WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_
18#define WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_
19
20#include <utility>
21#include <vector>
22
23#include "build/build_config.h"
24#if defined(OS_POSIX)
25#include "base/file_descriptor_posix.h"
26#endif
27#include "base/file_path.h"
28#include "base/memory/ref_counted.h"
29#include "base/memory/scoped_ptr.h"
30#include "base/platform_file.h"
31#include "base/time.h"
32#include "base/values.h"
33#include "googleurl/src/gurl.h"
34#include "net/base/host_port_pair.h"
35#include "net/url_request/url_request_status.h"
36#include "webkit/glue/resource_type.h"
37
38namespace net {
39class HttpResponseHeaders;
40}
41
42namespace webkit_glue {
43
44// Structure containing timing information for the request. It addresses
45// http://groups.google.com/group/http-archive-specification/web/har-1-1-spec
46// and http://dev.w3.org/2006/webapi/WebTiming/ needs.
47//
48// All the values for starts and ends are given in milliseconds and are
49// offsets with respect to the given base time.
50struct ResourceLoadTimingInfo {
51  ResourceLoadTimingInfo();
52  ~ResourceLoadTimingInfo();
53
54  // All the values in this struct are given as offsets in milliseconds wrt
55  // this base time.
56  base::Time base_time;
57
58  // The time that proxy processing started. For requests with no proxy phase,
59  // this time is -1.
60  int32 proxy_start;
61
62  // The time that proxy processing ended. For reused sockets this time
63  // is -1.
64  int32 proxy_end;
65
66  // The time that DNS lookup started. For reused sockets this time is -1.
67  int32 dns_start;
68
69  // The time that DNS lookup ended. For reused sockets this time is -1.
70  int32 dns_end;
71
72  // The time that establishing connection started. Connect time includes
73  // DNS, blocking, TCP, TCP retries and SSL time.
74  int32 connect_start;
75
76  // The time that establishing connection ended. Connect time includes
77  // DNS, blocking, TCP, TCP retries and SSL time.
78  int32 connect_end;
79
80  // The time at which SSL handshake started. For non-HTTPS requests this
81  // is 0.
82  int32 ssl_start;
83
84  // The time at which SSL handshake ended. For non-HTTPS requests this is 0.
85  int32 ssl_end;
86
87  // The time that HTTP request started. For non-HTTP requests this is 0.
88  int32 send_start;
89
90  // The time that HTTP request ended. For non-HTTP requests this is 0.
91  int32 send_end;
92
93  // The time at which receiving HTTP headers started. For non-HTTP requests
94  // this is 0.
95  int32 receive_headers_start;
96
97  // The time at which receiving HTTP headers ended. For non-HTTP requests
98  // this is 0.
99  int32 receive_headers_end;
100};
101
102struct ResourceDevToolsInfo : base::RefCounted<ResourceDevToolsInfo> {
103  typedef std::vector<std::pair<std::string, std::string> >
104      HeadersVector;
105
106  ResourceDevToolsInfo();
107  ~ResourceDevToolsInfo();
108
109  int32 http_status_code;
110  std::string http_status_text;
111  HeadersVector request_headers;
112  HeadersVector response_headers;
113};
114
115struct ResourceResponseInfo {
116  ResourceResponseInfo();
117  ~ResourceResponseInfo();
118
119  // The time at which the request was made that resulted in this response.
120  // For cached responses, this time could be "far" in the past.
121  base::Time request_time;
122
123  // The time at which the response headers were received.  For cached
124  // responses, this time could be "far" in the past.
125  base::Time response_time;
126
127  // The response headers or NULL if the URL type does not support headers.
128  scoped_refptr<net::HttpResponseHeaders> headers;
129
130  // The mime type of the response.  This may be a derived value.
131  std::string mime_type;
132
133  // The character encoding of the response or none if not applicable to the
134  // response's mime type.  This may be a derived value.
135  std::string charset;
136
137  // An opaque string carrying security information pertaining to this
138  // response.  This may include information about the SSL connection used.
139  std::string security_info;
140
141  // Content length if available. -1 if not available
142  int64 content_length;
143
144  // Length of the encoded data transferred over the network. In case there is
145  // no data, contains -1.
146  int64 encoded_data_length;
147
148  // The appcache this response was loaded from, or kNoCacheId.
149  int64 appcache_id;
150
151  // The manifest url of the appcache this response was loaded from.
152  // Note: this value is only populated for main resource requests.
153  GURL appcache_manifest_url;
154
155  // Connection identifier from the underlying network stack. In case there
156  // is no associated connection, contains 0.
157  uint32 connection_id;
158
159  // Determines whether physical connection reused.
160  bool connection_reused;
161
162  // Detailed timing information used by the WebTiming, HAR and Developer
163  // Tools.
164  ResourceLoadTimingInfo load_timing;
165
166  // Actual request and response headers, as obtained from the network stack.
167  // Only present if request had LOAD_REPORT_RAW_HEADERS in load_flags, and
168  // requesting renderer had CanReadRowCookies permission.
169  scoped_refptr<ResourceDevToolsInfo> devtools_info;
170
171  // The path to a file that will contain the response body.  It may only
172  // contain a portion of the response body at the time that the ResponseInfo
173  // becomes available.
174  FilePath download_file_path;
175
176  // True if the response was delivered using SPDY.
177  bool was_fetched_via_spdy;
178
179  // True if the response was delivered after NPN is negotiated.
180  bool was_npn_negotiated;
181
182  // True if response could use alternate protocol. However, browser will
183  // ignore the alternate protocol when spdy is not enabled on browser side.
184  bool was_alternate_protocol_available;
185
186  // True if the response was fetched via an explicit proxy (as opposed to a
187  // transparent proxy). The proxy could be any type of proxy, HTTP or SOCKS.
188  // Note: we cannot tell if a transparent proxy may have been involved.
189  bool was_fetched_via_proxy;
190
191  // Remote address of the socket which fetched this resource.
192  net::HostPortPair socket_address;
193};
194
195class ResourceLoaderBridge {
196 public:
197  // Structure used when calling ResourceLoaderBridge::Create().
198  struct RequestInfo {
199    RequestInfo();
200    ~RequestInfo();
201
202    // HTTP-style method name (e.g., "GET" or "POST").
203    std::string method;
204
205    // Absolute URL encoded in ASCII per the rules of RFC-2396.
206    GURL url;
207
208    // URL of the document in the top-level window, which may be checked by the
209    // third-party cookie blocking policy.
210    GURL first_party_for_cookies;
211
212    // Optional parameter, a URL with similar constraints in how it must be
213    // encoded as the url member.
214    GURL referrer;
215
216    std::string frame_origin;
217    std::string main_frame_origin;
218
219    // For HTTP(S) requests, the headers parameter can be a \r\n-delimited and
220    // \r\n-terminated list of MIME headers.  They should be ASCII-encoded using
221    // the standard MIME header encoding rules.  The headers parameter can also
222    // be null if no extra request headers need to be set.
223    std::string headers;
224
225    // Composed of the values defined in url_request_load_flags.h.
226    int load_flags;
227
228    // Process id of the process making the request.
229    int requestor_pid;
230
231    // Indicates if the current request is the main frame load, a sub-frame
232    // load, or a sub objects load.
233    ResourceType::Type request_type;
234
235    // Used for plugin to browser requests.
236    uint32 request_context;
237
238    // Identifies what appcache host this request is associated with.
239    int appcache_host_id;
240
241    // Used to associated the bridge with a frame's network context.
242    int routing_id;
243
244    // If true, then the response body will be downloaded to a file and the
245    // path to that file will be provided in ResponseInfo::download_file_path.
246    bool download_to_file;
247
248    // True if the request was user initiated.
249    bool has_user_gesture;
250  };
251
252  // See the SyncLoad method declared below.  (The name of this struct is not
253  // suffixed with "Info" because it also contains the response data.)
254  struct SyncLoadResponse : ResourceResponseInfo {
255    SyncLoadResponse();
256    ~SyncLoadResponse();
257
258    // The response status.
259    net::URLRequestStatus status;
260
261    // The final URL of the response.  This may differ from the request URL in
262    // the case of a server redirect.
263    GURL url;
264
265    // The response data.
266    std::string data;
267  };
268
269  // Generated by the bridge. This is implemented by our custom resource loader
270  // within webkit. The Peer and it's bridge should have identical lifetimes
271  // as they represent each end of a communication channel.
272  //
273  // These callbacks mirror net::URLRequest::Delegate and the order and
274  // conditions in which they will be called are identical. See url_request.h
275  // for more information.
276  class Peer {
277   public:
278    virtual ~Peer() {}
279
280    // Called as upload progress is made.
281    // note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set
282    virtual void OnUploadProgress(uint64 position, uint64 size) = 0;
283
284    // Called when a redirect occurs.  The implementation may return false to
285    // suppress the redirect.  The given ResponseInfo provides complete
286    // information about the redirect, and new_url is the URL that will be
287    // loaded if this method returns true.  If this method returns true, the
288    // output parameter *has_new_first_party_for_cookies indicates whether the
289    // output parameter *new_first_party_for_cookies contains the new URL that
290    // should be consulted for the third-party cookie blocking policy.
291    virtual bool OnReceivedRedirect(const GURL& new_url,
292                                    const ResourceResponseInfo& info,
293                                    bool* has_new_first_party_for_cookies,
294                                    GURL* new_first_party_for_cookies) = 0;
295
296    // Called when response headers are available (after all redirects have
297    // been followed).
298    virtual void OnReceivedResponse(const ResourceResponseInfo& info) = 0;
299
300    // Called when a chunk of response data is downloaded.  This method may be
301    // called multiple times or not at all if an error occurs.  This method is
302    // only called if RequestInfo::download_to_file was set to true, and in
303    // that case, OnReceivedData will not be called.
304    virtual void OnDownloadedData(int len) = 0;
305
306    // Called when a chunk of response data is available. This method may
307    // be called multiple times or not at all if an error occurs.
308    // The encoded_data_length is the length of the encoded data transferred
309    // over the network, which could be different from data length (e.g. for
310    // gzipped content), or -1 if if unknown.
311    virtual void OnReceivedData(const char* data,
312                                int data_length,
313                                int encoded_data_length) = 0;
314
315    // Called when metadata generated by the renderer is retrieved from the
316    // cache. This method may be called zero or one times.
317    virtual void OnReceivedCachedMetadata(const char* data, int len) { }
318
319    // Called when the response is complete.  This method signals completion of
320    // the resource load.ff
321    virtual void OnCompletedRequest(const net::URLRequestStatus& status,
322                                    const std::string& security_info,
323                                    const base::Time& completion_time) = 0;
324  };
325
326  // use Create() for construction, but anybody can delete at any time,
327  // INCLUDING during processing of callbacks.
328  virtual ~ResourceLoaderBridge();
329
330  // Call this method to make a new instance.
331  //
332  // For HTTP(S) POST requests, the AppendDataToUpload and AppendFileToUpload
333  // methods may be called to construct the body of the request.
334  static ResourceLoaderBridge* Create(const RequestInfo& request_info);
335
336  // Call this method before calling Start() to append a chunk of binary data
337  // to the request body.  May only be used with HTTP(S) POST requests.
338  virtual void AppendDataToUpload(const char* data, int data_len) = 0;
339
340  // Call this method before calling Start() to append the contents of a file
341  // to the request body.  May only be used with HTTP(S) POST requests.
342  void AppendFileToUpload(const FilePath& file_path) {
343    AppendFileRangeToUpload(file_path, 0, kuint64max, base::Time());
344  }
345
346  // Call this method before calling Start() to append the contents of a file
347  // to the request body.  May only be used with HTTP(S) POST requests.
348  virtual void AppendFileRangeToUpload(
349      const FilePath& file_path,
350      uint64 offset,
351      uint64 length,
352      const base::Time& expected_modification_time) = 0;
353
354  // Call this method before calling Start() to append the contents of a blob
355  // to the request body.  May only be used with HTTP(S) POST requests.
356  virtual void AppendBlobToUpload(const GURL& blob_url) = 0;
357
358  // Call this method before calling Start() to assign an upload identifier to
359  // this request.  This is used to enable caching of POST responses.  A value
360  // of 0 implies the unspecified identifier.
361  virtual void SetUploadIdentifier(int64 identifier) = 0;
362
363  // Call this method to initiate the request.  If this method succeeds, then
364  // the peer's methods will be called asynchronously to report various events.
365  virtual bool Start(Peer* peer) = 0;
366
367  // Call this method to cancel a request that is in progress.  This method
368  // causes the request to immediately transition into the 'done' state. The
369  // OnCompletedRequest method will be called asynchronously; this assumes
370  // the peer is still valid.
371  virtual void Cancel() = 0;
372
373  // Call this method to suspend or resume a load that is in progress.  This
374  // method may only be called after a successful call to the Start method.
375  virtual void SetDefersLoading(bool value) = 0;
376
377  // Call this method to load the resource synchronously (i.e., in one shot).
378  // This is an alternative to the Start method.  Be warned that this method
379  // will block the calling thread until the resource is fully downloaded or an
380  // error occurs.  It could block the calling thread for a long time, so only
381  // use this if you really need it!  There is also no way for the caller to
382  // interrupt this method.  Errors are reported via the status field of the
383  // response parameter.
384  virtual void SyncLoad(SyncLoadResponse* response) = 0;
385
386 protected:
387  // construction must go through Create()
388  ResourceLoaderBridge();
389
390 private:
391  DISALLOW_COPY_AND_ASSIGN(ResourceLoaderBridge);
392};
393
394}  // namespace webkit_glue
395
396#endif  // WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_
397