blob: 56cb9eb4448103ffefd7e43a254d4fe7f23d94cb [file]
/*
* Copyright (C) 2009 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:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 THE COPYRIGHT
* OWNER 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.
*/
#include "third_party/blink/public/platform/web_url_request.h"
#include <memory>
#include "base/time/time.h"
#include "net/base/load_flags.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/optional_trust_token_params.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_http_header_visitor.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_request_extra_data.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.h"
#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
#include "third_party/blink/renderer/platform/weborigin/referrer.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
using blink::mojom::FetchCacheMode;
namespace blink {
// This is complementary to ConvertRequestPriorityToResourceLoadPriority,
// defined in third_party/blink/renderer/core/fetch/fetch_request_data.cc.
net::RequestPriority WebURLRequest::ConvertToNetPriority(
WebURLRequest::Priority priority) {
switch (priority) {
case WebURLRequest::Priority::kVeryHigh:
return net::HIGHEST;
case WebURLRequest::Priority::kHigh:
return net::MEDIUM;
case WebURLRequest::Priority::kMedium:
return net::LOW;
case WebURLRequest::Priority::kLow:
return net::LOWEST;
case WebURLRequest::Priority::kVeryLow:
return net::IDLE;
case WebURLRequest::Priority::kUnresolved:
default:
NOTREACHED();
}
}
WebURLRequest::~WebURLRequest() = default;
WebURLRequest::WebURLRequest()
: owned_resource_request_(std::make_unique<ResourceRequest>()),
resource_request_(owned_resource_request_.get()) {}
WebURLRequest::WebURLRequest(WebURLRequest&& src) {
*this = std::move(src);
}
WebURLRequest& WebURLRequest::operator=(WebURLRequest&& src) {
if (this == &src) {
return *this;
}
if (src.owned_resource_request_) {
owned_resource_request_ = std::move(src.owned_resource_request_);
resource_request_ = owned_resource_request_.get();
} else {
owned_resource_request_ = std::make_unique<ResourceRequest>();
resource_request_ = owned_resource_request_.get();
CopyFrom(src);
}
src.resource_request_ = nullptr;
return *this;
}
WebURLRequest::WebURLRequest(const WebURL& url) : WebURLRequest() {
SetUrl(url);
}
void WebURLRequest::CopyFrom(const WebURLRequest& r) {
// Copying subclasses that have different m_resourceRequest ownership
// semantics via this operator is just not supported.
DCHECK(owned_resource_request_);
DCHECK_EQ(owned_resource_request_.get(), resource_request_);
DCHECK(owned_resource_request_->IsNull());
DCHECK(this != &r);
resource_request_->CopyHeadFrom(*r.resource_request_);
resource_request_->SetHttpBody(r.resource_request_->HttpBody());
}
bool WebURLRequest::IsNull() const {
return resource_request_->IsNull();
}
WebURL WebURLRequest::Url() const {
return resource_request_->Url();
}
void WebURLRequest::SetUrl(const WebURL& url) {
resource_request_->SetUrl(url);
}
const net::SiteForCookies& WebURLRequest::SiteForCookies() const {
return resource_request_->SiteForCookies();
}
void WebURLRequest::SetSiteForCookies(
const net::SiteForCookies& site_for_cookies) {
resource_request_->SetSiteForCookies(site_for_cookies);
}
std::optional<WebSecurityOrigin> WebURLRequest::TopFrameOrigin() const {
const SecurityOrigin* origin = resource_request_->TopFrameOrigin();
return origin ? std::optional<WebSecurityOrigin>(origin)
: std::optional<WebSecurityOrigin>();
}
void WebURLRequest::SetTopFrameOrigin(const WebSecurityOrigin& origin) {
resource_request_->SetTopFrameOrigin(origin);
}
WebSecurityOrigin WebURLRequest::RequestorOrigin() const {
return resource_request_->RequestorOrigin();
}
WebSecurityOrigin WebURLRequest::IsolatedWorldOrigin() const {
return resource_request_->IsolatedWorldOrigin();
}
void WebURLRequest::SetRequestorOrigin(
const WebSecurityOrigin& requestor_origin) {
resource_request_->SetRequestorOrigin(requestor_origin);
}
mojom::FetchCacheMode WebURLRequest::GetCacheMode() const {
return resource_request_->GetCacheMode();
}
void WebURLRequest::SetCacheMode(mojom::FetchCacheMode cache_mode) {
resource_request_->SetCacheMode(cache_mode);
}
base::TimeDelta WebURLRequest::TimeoutInterval() const {
return resource_request_->TimeoutInterval();
}
WebString WebURLRequest::HttpMethod() const {
return resource_request_->HttpMethod();
}
void WebURLRequest::SetHttpMethod(const WebString& http_method) {
resource_request_->SetHttpMethod(http_method);
}
WebString WebURLRequest::HttpContentType() const {
return resource_request_->HttpContentType();
}
bool WebURLRequest::IsFormSubmission() const {
return resource_request_->IsFormSubmission();
}
WebString WebURLRequest::HttpHeaderField(const WebString& name) const {
return resource_request_->HttpHeaderField(name);
}
void WebURLRequest::SetHttpHeaderField(const WebString& name,
const WebString& value) {
CHECK(!EqualIgnoringAsciiCase(name, "referer"));
resource_request_->SetHttpHeaderField(name, value);
}
void WebURLRequest::AddHttpHeaderField(const WebString& name,
const WebString& value) {
resource_request_->AddHttpHeaderField(name, value);
}
void WebURLRequest::ClearHttpHeaderField(const WebString& name) {
resource_request_->ClearHttpHeaderField(name);
}
void WebURLRequest::VisitHttpHeaderFields(WebHTTPHeaderVisitor* visitor) const {
const HTTPHeaderMap& map = resource_request_->HttpHeaderFields();
for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it)
visitor->VisitHeader(it->key, it->value);
}
WebHTTPBody WebURLRequest::HttpBody() const {
return WebHTTPBody(resource_request_->HttpBody());
}
void WebURLRequest::SetHttpBody(const WebHTTPBody& http_body) {
resource_request_->SetHttpBody(http_body);
}
bool WebURLRequest::ReportUploadProgress() const {
return resource_request_->ReportUploadProgress();
}
void WebURLRequest::SetReportUploadProgress(bool report_upload_progress) {
resource_request_->SetReportUploadProgress(report_upload_progress);
}
mojom::blink::RequestContextType WebURLRequest::GetRequestContext() const {
return resource_request_->GetRequestContext();
}
network::mojom::RequestDestination WebURLRequest::GetRequestDestination()
const {
return resource_request_->GetRequestDestination();
}
void WebURLRequest::SetReferrerString(const WebString& referrer) {
resource_request_->SetReferrerString(referrer);
}
void WebURLRequest::SetReferrerPolicy(
network::mojom::ReferrerPolicy referrer_policy) {
resource_request_->SetReferrerPolicy(referrer_policy);
}
WebString WebURLRequest::ReferrerString() const {
return resource_request_->ReferrerString();
}
network::mojom::ReferrerPolicy WebURLRequest::GetReferrerPolicy() const {
return resource_request_->GetReferrerPolicy();
}
bool WebURLRequest::HasUserGesture() const {
return resource_request_->HasUserGesture();
}
bool WebURLRequest::HasTextFragmentToken() const {
return resource_request_->HasTextFragmentToken();
}
void WebURLRequest::SetHasUserGesture(bool has_user_gesture) {
resource_request_->SetHasUserGesture(has_user_gesture);
}
void WebURLRequest::SetRequestContext(
mojom::blink::RequestContextType request_context) {
resource_request_->SetRequestContext(request_context);
}
void WebURLRequest::SetRequestDestination(
network::mojom::RequestDestination destination) {
resource_request_->SetRequestDestination(destination);
}
bool WebURLRequest::UseStreamOnResponse() const {
return resource_request_->UseStreamOnResponse();
}
void WebURLRequest::SetUseStreamOnResponse(bool use_stream_on_response) {
resource_request_->SetUseStreamOnResponse(use_stream_on_response);
}
bool WebURLRequest::GetKeepalive() const {
return resource_request_->GetKeepalive();
}
void WebURLRequest::SetKeepalive(bool keepalive) {
resource_request_->SetKeepalive(keepalive);
}
bool WebURLRequest::GetSkipServiceWorker() const {
return resource_request_->GetSkipServiceWorker();
}
void WebURLRequest::SetSkipServiceWorker(bool skip_service_worker) {
resource_request_->SetSkipServiceWorker(skip_service_worker);
}
network::mojom::RequestMode WebURLRequest::GetMode() const {
return resource_request_->GetMode();
}
void WebURLRequest::SetMode(network::mojom::RequestMode mode) {
return resource_request_->SetMode(mode);
}
bool WebURLRequest::GetFavicon() const {
return resource_request_->IsFavicon();
}
void WebURLRequest::SetFavicon(bool) {
resource_request_->SetFavicon(true);
}
network::mojom::CredentialsMode WebURLRequest::GetCredentialsMode() const {
return resource_request_->GetCredentialsMode();
}
void WebURLRequest::SetCredentialsMode(network::mojom::CredentialsMode mode) {
return resource_request_->SetCredentialsMode(mode);
}
network::mojom::RedirectMode WebURLRequest::GetRedirectMode() const {
return resource_request_->GetRedirectMode();
}
void WebURLRequest::SetRedirectMode(network::mojom::RedirectMode redirect) {
return resource_request_->SetRedirectMode(redirect);
}
const scoped_refptr<WebURLRequestExtraData>&
WebURLRequest::GetURLRequestExtraData() const {
return resource_request_->GetURLRequestExtraData();
}
void WebURLRequest::SetURLRequestExtraData(
scoped_refptr<WebURLRequestExtraData> extra_data) {
resource_request_->SetURLRequestExtraData(std::move(extra_data));
}
bool WebURLRequest::IsDownloadToNetworkCacheOnly() const {
return resource_request_->IsDownloadToNetworkCacheOnly();
}
void WebURLRequest::SetDownloadToNetworkCacheOnly(bool download_to_cache_only) {
resource_request_->SetDownloadToNetworkCacheOnly(download_to_cache_only);
}
ResourceRequest& WebURLRequest::ToMutableResourceRequest() {
DCHECK(resource_request_);
return *resource_request_;
}
WebURLRequest::Priority WebURLRequest::GetPriority() const {
return static_cast<WebURLRequest::Priority>(resource_request_->Priority());
}
void WebURLRequest::SetPriority(WebURLRequest::Priority priority) {
resource_request_->SetPriority(static_cast<ResourceLoadPriority>(priority));
}
network::mojom::CorsPreflightPolicy WebURLRequest::GetCorsPreflightPolicy()
const {
return resource_request_->CorsPreflightPolicy();
}
std::optional<WebString> WebURLRequest::GetSuggestedFilename() const {
if (!resource_request_->GetSuggestedFilename().has_value())
return std::optional<WebString>();
return static_cast<WebString>(
resource_request_->GetSuggestedFilename().value());
}
bool WebURLRequest::IsAdResource() const {
return resource_request_->IsAdResource();
}
void WebURLRequest::SetUpgradeIfInsecure(bool upgrade_if_insecure) {
resource_request_->SetUpgradeIfInsecure(upgrade_if_insecure);
}
bool WebURLRequest::UpgradeIfInsecure() const {
return resource_request_->UpgradeIfInsecure();
}
bool WebURLRequest::SupportsAsyncRevalidation() const {
return resource_request_->AllowsStaleResponse();
}
bool WebURLRequest::IsRevalidating() const {
return resource_request_->IsRevalidating();
}
const std::optional<base::UnguessableToken>&
WebURLRequest::GetDevToolsThrottlingToken() const {
return resource_request_->GetDevToolsThrottlingToken();
}
const WebString WebURLRequest::GetRequestedWithHeader() const {
return resource_request_->GetRequestedWithHeader();
}
void WebURLRequest::SetRequestedWithHeader(const WebString& value) {
resource_request_->SetRequestedWithHeader(value);
}
const base::UnguessableToken& WebURLRequest::GetFetchWindowId() const {
return resource_request_->GetFetchWindowId();
}
void WebURLRequest::SetFetchWindowId(const base::UnguessableToken& id) {
resource_request_->SetFetchWindowId(id);
}
int WebURLRequest::GetLoadFlagsForWebUrlRequest() const {
int load_flags = net::LOAD_NORMAL;
switch (resource_request_->GetCacheMode()) {
case FetchCacheMode::kNoStore:
load_flags |= net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_CACHE;
break;
case FetchCacheMode::kValidateCache:
load_flags |= net::LOAD_VALIDATE_CACHE;
break;
case FetchCacheMode::kBypassCache:
load_flags |= net::LOAD_BYPASS_CACHE;
break;
case FetchCacheMode::kForceCache:
load_flags |= net::LOAD_SKIP_CACHE_VALIDATION;
break;
case FetchCacheMode::kOnlyIfCached:
load_flags |= net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION;
break;
case FetchCacheMode::kUnspecifiedOnlyIfCachedStrict:
load_flags |= net::LOAD_ONLY_FROM_CACHE;
break;
case FetchCacheMode::kDefault:
break;
case FetchCacheMode::kUnspecifiedForceCacheMiss:
load_flags |= net::LOAD_ONLY_FROM_CACHE | net::LOAD_BYPASS_CACHE;
break;
}
if (resource_request_->GetRequestContext() ==
blink::mojom::blink::RequestContextType::PREFETCH)
load_flags |= net::LOAD_PREFETCH;
if (resource_request_->GetURLRequestExtraData()) {
if (resource_request_->GetURLRequestExtraData()->is_for_no_state_prefetch())
load_flags |= net::LOAD_PREFETCH;
}
if (resource_request_->AllowsStaleResponse()) {
load_flags |= net::LOAD_SUPPORT_ASYNC_REVALIDATION;
}
if (resource_request_->PrefetchMaybeForTopLevelNavigation()) {
CHECK_EQ(resource_request_->GetRequestContext(),
blink::mojom::blink::RequestContextType::PREFETCH);
if (!resource_request_->RequestorOrigin()->IsSameOriginWith(
SecurityOrigin::Create(resource_request_->Url()).get())) {
load_flags |= net::LOAD_RESTRICTED_PREFETCH_FOR_MAIN_FRAME;
}
}
return load_flags;
}
const ResourceRequest& WebURLRequest::ToResourceRequest() const {
DCHECK(resource_request_);
return *resource_request_;
}
std::optional<WebString> WebURLRequest::GetDevToolsId() const {
return resource_request_->GetDevToolsId();
}
bool WebURLRequest::IsFromOriginDirtyStyleSheet() const {
return resource_request_->IsFromOriginDirtyStyleSheet();
}
std::optional<base::UnguessableToken> WebURLRequest::RecursivePrefetchToken()
const {
return resource_request_->RecursivePrefetchToken();
}
network::OptionalTrustTokenParams WebURLRequest::TrustTokenParams() const {
return ConvertTrustTokenParams(resource_request_->TrustTokenParams());
}
std::optional<WebURL> WebURLRequest::WebBundleUrl() const {
if (resource_request_->GetWebBundleTokenParams()) {
return resource_request_->GetWebBundleTokenParams()->bundle_url;
}
return std::nullopt;
}
std::optional<base::UnguessableToken> WebURLRequest::WebBundleToken() const {
if (resource_request_->GetWebBundleTokenParams()) {
return resource_request_->GetWebBundleTokenParams()->token;
}
return std::nullopt;
}
WebURLRequest::WebURLRequest(ResourceRequest& r) : resource_request_(&r) {}
} // namespace blink