// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// The intent of this file is to provide a type-neutral abstraction between
// Chrome and WebKit for resource loading. This pure-virtual interface is
// implemented by the embedder.
//
// One of these objects will be created by WebKit for each request. WebKit
// will own the pointer to the bridge, and will delete it when the request is
// no longer needed.
//
// In turn, the bridge's owner on the WebKit end will implement the Peer
// interface, which we will use to communicate notifications back.
#ifndef WEBKIT_CHILD_RESOURCE_LOADER_BRIDGE_H_
#define WEBKIT_CHILD_RESOURCE_LOADER_BRIDGE_H_
#include <utility>
#include "build/build_config.h"
#if defined(OS_POSIX)
#include "base/file_descriptor_posix.h"
#endif
#include "base/memory/ref_counted.h"
#include "base/platform_file.h"
#include "base/values.h"
#include "net/base/request_priority.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "url/gurl.h"
#include "webkit/child/webkit_child_export.h"
#include "webkit/common/resource_response_info.h"
#include "webkit/common/resource_type.h"
namespace webkit_glue {
class ResourceRequestBody;
class ResourceLoaderBridge {
public:
// Structure used when calling
// WebKitPlatformSupportImpl::CreateResourceLoader().
struct WEBKIT_CHILD_EXPORT RequestInfo {
RequestInfo();
~RequestInfo();
// HTTP-style method name (e.g., "GET" or "POST").
std::string method;
// Absolute URL encoded in ASCII per the rules of RFC-2396.
GURL url;
// URL of the document in the top-level window, which may be checked by the
// third-party cookie blocking policy.
GURL first_party_for_cookies;
// Optional parameter, a URL with similar constraints in how it must be
// encoded as the url member.
GURL referrer;
// The referrer policy that applies to the referrer.
blink::WebReferrerPolicy referrer_policy;
// For HTTP(S) requests, the headers parameter can be a \r\n-delimited and
// \r\n-terminated list of MIME headers. They should be ASCII-encoded using
// the standard MIME header encoding rules. The headers parameter can also
// be null if no extra request headers need to be set.
std::string headers;
// Composed of the values defined in url_request_load_flags.h.
int load_flags;
// Process id of the process making the request.
int requestor_pid;
// Indicates if the current request is the main frame load, a sub-frame
// load, or a sub objects load.
ResourceType::Type request_type;
// Indicates the priority of this request, as determined by WebKit.
net::RequestPriority priority;
// Used for plugin to browser requests.
uint32 request_context;
// Identifies what appcache host this request is associated with.
int appcache_host_id;
// Used to associated the bridge with a frame's network context.
int routing_id;
// If true, then the response body will be downloaded to a file and the
// path to that file will be provided in ResponseInfo::download_file_path.
bool download_to_file;
// True if the request was user initiated.
bool has_user_gesture;
// Extra data associated with this request. We do not own this pointer.
blink::WebURLRequest::ExtraData* extra_data;
private:
DISALLOW_COPY_AND_ASSIGN(RequestInfo);
};
// See the SyncLoad method declared below. (The name of this struct is not
// suffixed with "Info" because it also contains the response data.)
struct SyncLoadResponse : ResourceResponseInfo {
WEBKIT_CHILD_EXPORT SyncLoadResponse();
WEBKIT_CHILD_EXPORT ~SyncLoadResponse();
// The response error code.
int error_code;
// The final URL of the response. This may differ from the request URL in
// the case of a server redirect.
GURL url;
// The response data.
std::string data;
};
// Generated by the bridge. This is implemented by our custom resource loader
// within webkit. The Peer and it's bridge should have identical lifetimes
// as they represent each end of a communication channel.
//
// These callbacks mirror net::URLRequest::Delegate and the order and
// conditions in which they will be called are identical. See url_request.h
// for more information.
class WEBKIT_CHILD_EXPORT Peer {
public:
// Called as upload progress is made.
// note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set
virtual void OnUploadProgress(uint64 position, uint64 size) = 0;
// Called when a redirect occurs. The implementation may return false to
// suppress the redirect. The given ResponseInfo provides complete
// information about the redirect, and new_url is the URL that will be
// loaded if this method returns true. If this method returns true, the
// output parameter *has_new_first_party_for_cookies indicates whether the
// output parameter *new_first_party_for_cookies contains the new URL that
// should be consulted for the third-party cookie blocking policy.
virtual bool OnReceivedRedirect(const GURL& new_url,
const ResourceResponseInfo& info,
bool* has_new_first_party_for_cookies,
GURL* new_first_party_for_cookies) = 0;
// Called when response headers are available (after all redirects have
// been followed).
virtual void OnReceivedResponse(const ResourceResponseInfo& info) = 0;
// Called when a chunk of response data is downloaded. This method may be
// called multiple times or not at all if an error occurs. This method is
// only called if RequestInfo::download_to_file was set to true, and in
// that case, OnReceivedData will not be called.
// The encoded_data_length is the length of the encoded data transferred
// over the network, which could be different from data length (e.g. for
// gzipped content), or -1 if unknown. It is only valid while devtools are
// attached. Otherwise it becomes -1.
virtual void OnDownloadedData(int len, int encoded_data_length) = 0;
// Called when a chunk of response data is available. This method may
// be called multiple times or not at all if an error occurs.
// The encoded_data_length is the length of the encoded data transferred
// over the network, which could be different from data length (e.g. for
// gzipped content), or -1 if unknown. It is only valid while devtools are
// attached. Otherwise it becomes -1.
virtual void OnReceivedData(const char* data,
int data_length,
int encoded_data_length) = 0;
// Called when metadata generated by the renderer is retrieved from the
// cache. This method may be called zero or one times.
virtual void OnReceivedCachedMetadata(const char* data, int len) { }
// Called when the response is complete. This method signals completion of
// the resource load.
virtual void OnCompletedRequest(
int error_code,
bool was_ignored_by_handler,
const std::string& security_info,
const base::TimeTicks& completion_time) = 0;
protected:
virtual ~Peer() {}
};
// use WebKitPlatformSupportImpl::CreateResourceLoader() for construction, but
// anybody can delete at any time, INCLUDING during processing of callbacks.
WEBKIT_CHILD_EXPORT virtual ~ResourceLoaderBridge();
// Call this method before calling Start() to set the request body.
// May only be used with HTTP(S) POST requests.
virtual void SetRequestBody(ResourceRequestBody* request_body) = 0;
// Call this method to initiate the request. If this method succeeds, then
// the peer's methods will be called asynchronously to report various events.
virtual bool Start(Peer* peer) = 0;
// Call this method to cancel a request that is in progress. This method
// causes the request to immediately transition into the 'done' state. The
// OnCompletedRequest method will be called asynchronously; this assumes
// the peer is still valid.
virtual void Cancel() = 0;
// Call this method to suspend or resume a load that is in progress. This
// method may only be called after a successful call to the Start method.
virtual void SetDefersLoading(bool value) = 0;
// Call this method when the priority of the requested resource changes after
// Start() has been called. This method may only be called after a successful
// call to the Start method.
virtual void DidChangePriority(net::RequestPriority new_priority) = 0;
// Call this method to load the resource synchronously (i.e., in one shot).
// This is an alternative to the Start method. Be warned that this method
// will block the calling thread until the resource is fully downloaded or an
// error occurs. It could block the calling thread for a long time, so only
// use this if you really need it! There is also no way for the caller to
// interrupt this method. Errors are reported via the status field of the
// response parameter.
virtual void SyncLoad(SyncLoadResponse* response) = 0;
protected:
// Construction must go through
// WebKitPlatformSupportImpl::CreateResourceLoader()
// For HTTP(S) POST requests, the AppendDataToUpload and AppendFileToUpload
// methods may be called to construct the body of the request.
WEBKIT_CHILD_EXPORT ResourceLoaderBridge();
private:
DISALLOW_COPY_AND_ASSIGN(ResourceLoaderBridge);
};
} // namespace webkit_glue
#endif // WEBKIT_CHILD_RESOURCE_LOADER_BRIDGE_H_