blob: 8936647b1c847449837bb8d61879e0eab2b25559 [file] [log] [blame]
/*
* Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
* Copyright (C) 2009, 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ResourceRequest_h
#define ResourceRequest_h
#include <memory>
#include "platform/loader/fetch/ResourceLoadPriority.h"
#include "platform/network/EncodedFormData.h"
#include "platform/network/HTTPHeaderMap.h"
#include "platform/network/HTTPParsers.h"
#include "platform/network/http_names.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/Referrer.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "platform/wtf/Optional.h"
#include "platform/wtf/RefCounted.h"
#include "public/platform/WebURLRequest.h"
#include "public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "services/network/public/mojom/cors.mojom-blink.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "services/network/public/mojom/request_context_frame_type.mojom-shared.h"
#include "third_party/WebKit/common/net/ip_address_space.mojom-blink.h"
namespace blink {
enum class ResourceRequestBlockedReason {
kCSP,
kMixedContent,
kOrigin,
kInspector,
kSubresourceFilter,
kOther,
kContentType,
kNone
};
enum InputToLoadPerfMetricReportPolicy : uint8_t {
kNoReport, // Don't report metrics for this ResourceRequest.
kReportLink, // Report metrics for this request as initiated by a link click.
kReportIntent, // Report metrics for this request as initiated by an intent.
};
struct CrossThreadResourceRequestData;
// A ResourceRequest is a "request" object for ResourceLoader. Conceptually
// it is https://fetch.spec.whatwg.org/#concept-request, but it contains
// a lot of blink specific fields. WebURLRequest is the "public version"
// of this class and WebURLLoader needs it. See WebURLRequest and
// WrappedResourceRequest.
//
// There are cases where we need to copy a request across threads, and
// CrossThreadResourceRequestData is a struct for the purpose. When you add a
// member variable to this class, do not forget to add the corresponding
// one in CrossThreadResourceRequestData and write copying logic.
class PLATFORM_EXPORT ResourceRequest final {
USING_FAST_MALLOC(ResourceRequest);
public:
enum class RedirectStatus : uint8_t { kFollowedRedirect, kNoRedirect };
class ExtraData : public RefCounted<ExtraData> {
public:
virtual ~ExtraData() = default;
};
ResourceRequest();
explicit ResourceRequest(const String& url_string);
explicit ResourceRequest(const KURL&);
explicit ResourceRequest(CrossThreadResourceRequestData*);
// TODO(toyoshim): Use std::unique_ptr as much as possible, and hopefully
// make ResourceRequest WTF_MAKE_NONCOPYABLE. See crbug.com/787704.
ResourceRequest(const ResourceRequest&);
ResourceRequest& operator=(const ResourceRequest&);
// Constructs a new ResourceRequest for a redirect from this instance.
std::unique_ptr<ResourceRequest> CreateRedirectRequest(
const KURL& new_url,
const AtomicString& new_method,
const KURL& new_site_for_cookies,
const String& new_referrer,
ReferrerPolicy new_referrer_policy,
WebURLRequest::ServiceWorkerMode new_sw_mode) const;
// Gets a copy of the data suitable for passing to another thread.
std::unique_ptr<CrossThreadResourceRequestData> CopyData() const;
bool IsNull() const;
const KURL& Url() const;
void SetURL(const KURL&);
void RemoveUserAndPassFromURL();
mojom::FetchCacheMode GetCacheMode() const;
void SetCacheMode(mojom::FetchCacheMode);
double TimeoutInterval() const; // May return 0 when using platform default.
void SetTimeoutInterval(double);
const KURL& SiteForCookies() const;
void SetSiteForCookies(const KURL&);
scoped_refptr<const SecurityOrigin> RequestorOrigin() const;
void SetRequestorOrigin(scoped_refptr<const SecurityOrigin>);
const AtomicString& HttpMethod() const;
void SetHTTPMethod(const AtomicString&);
const HTTPHeaderMap& HttpHeaderFields() const;
const AtomicString& HttpHeaderField(const AtomicString& name) const;
void SetHTTPHeaderField(const AtomicString& name, const AtomicString& value);
void AddHTTPHeaderField(const AtomicString& name, const AtomicString& value);
void AddHTTPHeaderFields(const HTTPHeaderMap& header_fields);
void ClearHTTPHeaderField(const AtomicString& name);
const AtomicString& HttpContentType() const {
return HttpHeaderField(HTTPNames::Content_Type);
}
void SetHTTPContentType(const AtomicString& http_content_type) {
SetHTTPHeaderField(HTTPNames::Content_Type, http_content_type);
}
bool DidSetHTTPReferrer() const { return did_set_http_referrer_; }
const AtomicString& HttpReferrer() const {
return HttpHeaderField(HTTPNames::Referer);
}
ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
void SetHTTPReferrer(const Referrer&);
void ClearHTTPReferrer();
const AtomicString& HttpOrigin() const {
return HttpHeaderField(HTTPNames::Origin);
}
void SetHTTPOrigin(const SecurityOrigin*);
void ClearHTTPOrigin();
void AddHTTPOriginIfNeeded(const SecurityOrigin*);
void AddHTTPOriginIfNeeded(const String&);
void SetHTTPUserAgent(const AtomicString& http_user_agent) {
SetHTTPHeaderField(HTTPNames::User_Agent, http_user_agent);
}
void ClearHTTPUserAgent();
void SetHTTPAccept(const AtomicString& http_accept) {
SetHTTPHeaderField(HTTPNames::Accept, http_accept);
}
EncodedFormData* HttpBody() const;
void SetHTTPBody(scoped_refptr<EncodedFormData>);
bool AllowStoredCredentials() const;
void SetAllowStoredCredentials(bool allow_credentials);
// TODO(yhirano): Describe what Priority and IntraPriorityValue are.
ResourceLoadPriority Priority() const;
int IntraPriorityValue() const;
void SetPriority(ResourceLoadPriority, int intra_priority_value = 0);
bool IsConditional() const;
// Whether the associated ResourceHandleClient needs to be notified of
// upload progress made for that resource.
bool ReportUploadProgress() const { return report_upload_progress_; }
void SetReportUploadProgress(bool report_upload_progress) {
report_upload_progress_ = report_upload_progress;
}
// Whether actual headers being sent/received should be collected and reported
// for the request.
bool ReportRawHeaders() const { return report_raw_headers_; }
void SetReportRawHeaders(bool report_raw_headers) {
report_raw_headers_ = report_raw_headers;
}
// Allows the request to be matched up with its requestor.
int RequestorID() const { return requestor_id_; }
void SetRequestorID(int requestor_id) { requestor_id_ = requestor_id; }
// The unique child id (not PID) of the process from which this request
// originated. In the case of out-of-process plugins, this allows to link back
// the request to the plugin process (as it is processed through a render view
// process).
int GetPluginChildID() const { return plugin_child_id_; }
void SetPluginChildID(int plugin_child_id) {
plugin_child_id_ = plugin_child_id;
}
// Allows the request to be matched up with its app cache host.
int AppCacheHostID() const { return app_cache_host_id_; }
void SetAppCacheHostID(int id) { app_cache_host_id_ = id; }
// True if request was user initiated.
bool HasUserGesture() const { return has_user_gesture_; }
void SetHasUserGesture(bool);
// True if request should be downloaded to file.
bool DownloadToFile() const { return download_to_file_; }
void SetDownloadToFile(bool download_to_file) {
download_to_file_ = download_to_file;
}
// True if the requestor wants to receive a response body as
// WebDataConsumerHandle.
bool UseStreamOnResponse() const { return use_stream_on_response_; }
void SetUseStreamOnResponse(bool use_stream_on_response) {
use_stream_on_response_ = use_stream_on_response;
}
// True if the request can work after the fetch group is terminated.
bool GetKeepalive() const { return keepalive_; }
void SetKeepalive(bool keepalive) { keepalive_ = keepalive; }
// The service worker mode indicating which service workers should get events
// for this request.
WebURLRequest::ServiceWorkerMode GetServiceWorkerMode() const {
return service_worker_mode_;
}
void SetServiceWorkerMode(
WebURLRequest::ServiceWorkerMode service_worker_mode) {
service_worker_mode_ = service_worker_mode;
}
// True if corresponding AppCache group should be resetted.
bool ShouldResetAppCache() const { return should_reset_app_cache_; }
void SetShouldResetAppCache(bool should_reset_app_cache) {
should_reset_app_cache_ = should_reset_app_cache;
}
// Extra data associated with this request.
ExtraData* GetExtraData() const { return extra_data_.get(); }
void SetExtraData(scoped_refptr<ExtraData> extra_data) {
extra_data_ = std::move(extra_data);
}
WebURLRequest::RequestContext GetRequestContext() const {
return request_context_;
}
void SetRequestContext(WebURLRequest::RequestContext context) {
request_context_ = context;
}
network::mojom::RequestContextFrameType GetFrameType() const {
return frame_type_;
}
void SetFrameType(network::mojom::RequestContextFrameType frame_type) {
frame_type_ = frame_type;
}
network::mojom::FetchRequestMode GetFetchRequestMode() const {
return fetch_request_mode_;
}
void SetFetchRequestMode(network::mojom::FetchRequestMode mode) {
fetch_request_mode_ = mode;
}
network::mojom::FetchCredentialsMode GetFetchCredentialsMode() const {
return fetch_credentials_mode_;
}
void SetFetchCredentialsMode(network::mojom::FetchCredentialsMode mode) {
fetch_credentials_mode_ = mode;
}
network::mojom::FetchRedirectMode GetFetchRedirectMode() const {
return fetch_redirect_mode_;
}
void SetFetchRedirectMode(network::mojom::FetchRedirectMode redirect) {
fetch_redirect_mode_ = redirect;
}
const String& GetFetchIntegrity() const { return fetch_integrity_; }
void SetFetchIntegrity(const String& integrity) {
fetch_integrity_ = integrity;
}
WebURLRequest::PreviewsState GetPreviewsState() const {
return previews_state_;
}
void SetPreviewsState(WebURLRequest::PreviewsState previews_state) {
previews_state_ = previews_state;
}
bool CacheControlContainsNoCache() const;
bool CacheControlContainsNoStore() const;
bool HasCacheValidatorFields() const;
bool CheckForBrowserSideNavigation() const {
return check_for_browser_side_navigation_;
}
void SetCheckForBrowserSideNavigation(bool check) {
check_for_browser_side_navigation_ = check;
}
double UiStartTime() const { return ui_start_time_; }
void SetUIStartTime(double ui_start_time_seconds) {
ui_start_time_ = ui_start_time_seconds;
}
// https://wicg.github.io/cors-rfc1918/#external-request
bool IsExternalRequest() const { return is_external_request_; }
void SetExternalRequestStateFromRequestorAddressSpace(mojom::IPAddressSpace);
network::mojom::CORSPreflightPolicy CORSPreflightPolicy() const {
return cors_preflight_policy_;
}
void SetCORSPreflightPolicy(network::mojom::CORSPreflightPolicy policy) {
cors_preflight_policy_ = policy;
}
InputToLoadPerfMetricReportPolicy InputPerfMetricReportPolicy() const {
return input_perf_metric_report_policy_;
}
void SetInputPerfMetricReportPolicy(
InputToLoadPerfMetricReportPolicy input_perf_metric_report_policy) {
input_perf_metric_report_policy_ = input_perf_metric_report_policy;
}
void SetRedirectStatus(RedirectStatus status) { redirect_status_ = status; }
RedirectStatus GetRedirectStatus() const { return redirect_status_; }
void SetSuggestedFilename(const WTF::Optional<String>& suggested_filename) {
suggested_filename_ = suggested_filename;
}
const WTF::Optional<String>& GetSuggestedFilename() const {
return suggested_filename_;
}
void SetNavigationStartTime(double);
double NavigationStartTime() const { return navigation_start_; }
void SetIsSameDocumentNavigation(bool is_same_document) {
is_same_document_navigation_ = is_same_document;
}
bool IsSameDocumentNavigation() const { return is_same_document_navigation_; }
void SetIsAdResource() { is_ad_resource_ = true; };
bool IsAdResource() const { return is_ad_resource_; }
private:
const CacheControlHeader& GetCacheControlHeader() const;
bool NeedsHTTPOrigin() const;
KURL url_;
double timeout_interval_; // 0 is a magic value for platform default on
// platforms that have one.
KURL site_for_cookies_;
// The SecurityOrigin specified by the ResourceLoaderOptions in case e.g.
// when the fetching was initiated in an isolated world. Set by
// ResourceFetcher but only when needed.
//
// TODO(crbug.com/811669): Merge with some of the other origin variables.
scoped_refptr<const SecurityOrigin> requestor_origin_;
AtomicString http_method_;
HTTPHeaderMap http_header_fields_;
scoped_refptr<EncodedFormData> http_body_;
bool allow_stored_credentials_ : 1;
bool report_upload_progress_ : 1;
bool report_raw_headers_ : 1;
bool has_user_gesture_ : 1;
bool download_to_file_ : 1;
bool use_stream_on_response_ : 1;
bool keepalive_ : 1;
bool should_reset_app_cache_ : 1;
mojom::FetchCacheMode cache_mode_;
WebURLRequest::ServiceWorkerMode service_worker_mode_;
ResourceLoadPriority priority_;
int intra_priority_value_;
int requestor_id_;
int plugin_child_id_;
int app_cache_host_id_;
WebURLRequest::PreviewsState previews_state_;
scoped_refptr<ExtraData> extra_data_;
WebURLRequest::RequestContext request_context_;
network::mojom::RequestContextFrameType frame_type_;
network::mojom::FetchRequestMode fetch_request_mode_;
network::mojom::FetchCredentialsMode fetch_credentials_mode_;
network::mojom::FetchRedirectMode fetch_redirect_mode_;
String fetch_integrity_;
ReferrerPolicy referrer_policy_;
bool did_set_http_referrer_;
bool check_for_browser_side_navigation_;
double ui_start_time_;
bool is_external_request_;
network::mojom::CORSPreflightPolicy cors_preflight_policy_;
bool is_same_document_navigation_;
InputToLoadPerfMetricReportPolicy input_perf_metric_report_policy_;
RedirectStatus redirect_status_;
WTF::Optional<String> suggested_filename_;
mutable CacheControlHeader cache_control_header_cache_;
static double default_timeout_interval_;
double navigation_start_ = 0;
bool is_ad_resource_ = false;
};
// This class is needed to copy a ResourceRequest across threads, because it
// has some members which cannot be transferred across threads (AtomicString
// for example).
// There are some rules / restrictions:
// - This struct cannot contain an object that cannot be transferred across
// threads (e.g., AtomicString)
// - Non-simple members need explicit copying (e.g., String::IsolatedCopy,
// KURL::Copy) rather than the copy constructor or the assignment operator.
struct CrossThreadResourceRequestData {
WTF_MAKE_NONCOPYABLE(CrossThreadResourceRequestData);
USING_FAST_MALLOC(CrossThreadResourceRequestData);
public:
CrossThreadResourceRequestData() = default;
KURL url_;
mojom::FetchCacheMode cache_mode_;
double timeout_interval_;
KURL site_for_cookies_;
scoped_refptr<const SecurityOrigin> requestor_origin_;
String http_method_;
std::unique_ptr<CrossThreadHTTPHeaderMapData> http_headers_;
scoped_refptr<EncodedFormData> http_body_;
bool allow_stored_credentials_;
bool report_upload_progress_;
bool has_user_gesture_;
bool download_to_file_;
WebURLRequest::ServiceWorkerMode service_worker_mode_;
bool use_stream_on_response_;
bool keepalive_;
bool should_reset_app_cache_;
ResourceLoadPriority priority_;
int intra_priority_value_;
int requestor_id_;
int plugin_child_id_;
int app_cache_host_id_;
WebURLRequest::RequestContext request_context_;
network::mojom::RequestContextFrameType frame_type_;
network::mojom::FetchRequestMode fetch_request_mode_;
network::mojom::FetchCredentialsMode fetch_credentials_mode_;
network::mojom::FetchRedirectMode fetch_redirect_mode_;
String fetch_integrity_;
WebURLRequest::PreviewsState previews_state_;
ReferrerPolicy referrer_policy_;
bool did_set_http_referrer_;
bool check_for_browser_side_navigation_;
double ui_start_time_;
bool is_external_request_;
network::mojom::CORSPreflightPolicy cors_preflight_policy_;
InputToLoadPerfMetricReportPolicy input_perf_metric_report_policy_;
ResourceRequest::RedirectStatus redirect_status_;
base::Optional<String> suggested_filename_;
bool is_ad_resource_;
};
} // namespace blink
#endif // ResourceRequest_h