Commit b3559beb authored by Dominic Farolino's avatar Dominic Farolino Committed by Commit Bot

Remove RequestInit implementation in favor of IDL compiler's version

This CL removes our RequestInit implementation and replaces it with one
the IDL compiler generates.

R=kinuko@chromium.org, kouhei@chromium.org, yhirano@chromium.org, yoav@yoav.ws

Bug: 836873
Change-Id: I29c55be8756deb5053cec04a5f82677d48413533
Reviewed-on: https://chromium-review.googlesource.com/1116418Reviewed-by: default avatarYoav Weiss <yoav@yoav.ws>
Commit-Queue: Dominic Farolino <domfarolino@gmail.com>
Cr-Commit-Position: refs/heads/master@{#570997}
parent 2c474b75
......@@ -608,6 +608,7 @@ core_dictionary_idl_files =
"events/transition_event_init.idl",
"events/ui_event_init.idl",
"events/wheel_event_init.idl",
"fetch/request_init.idl",
"fetch/response_init.idl",
"fileapi/blob_property_bag.idl",
"fileapi/file_property_bag.idl",
......
......@@ -38,8 +38,6 @@ blink_core_sources("fetch") {
"readable_stream_bytes_consumer.h",
"request.cc",
"request.h",
"request_init.cc",
"request_init.h",
"response.cc",
"response.h",
]
......
......@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/core/fetch/fetch_manager.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
......@@ -41,7 +42,7 @@ class GlobalFetchImpl final
ScriptPromise Fetch(ScriptState* script_state,
const RequestInfo& input,
const Dictionary& init,
const RequestInit& init,
ExceptionState& exception_state) override {
ExecutionContext* execution_context = fetch_manager_->GetExecutionContext();
if (!script_state->ContextIsValid() || !execution_context) {
......@@ -105,7 +106,7 @@ void GlobalFetch::ScopedFetcher::Trace(blink::Visitor* visitor) {}
ScriptPromise GlobalFetch::fetch(ScriptState* script_state,
LocalDOMWindow& window,
const RequestInfo& input,
const Dictionary& init,
const RequestInit& init,
ExceptionState& exception_state) {
UseCounter::Count(window.GetExecutionContext(), WebFeature::kFetch);
if (!window.GetFrame()) {
......@@ -119,7 +120,7 @@ ScriptPromise GlobalFetch::fetch(ScriptState* script_state,
ScriptPromise GlobalFetch::fetch(ScriptState* script_state,
WorkerGlobalScope& worker,
const RequestInfo& input,
const Dictionary& init,
const RequestInit& init,
ExceptionState& exception_state) {
UseCounter::Count(worker.GetExecutionContext(), WebFeature::kFetch);
return ScopedFetcher::From(worker)->Fetch(script_state, input, init,
......
......@@ -11,9 +11,9 @@
namespace blink {
class Dictionary;
class LocalDOMWindow;
class ExceptionState;
class RequestInit;
class ScriptState;
class WorkerGlobalScope;
......@@ -27,7 +27,7 @@ class CORE_EXPORT GlobalFetch {
virtual ScriptPromise Fetch(ScriptState*,
const RequestInfo&,
const Dictionary&,
const RequestInit&,
ExceptionState&) = 0;
static ScopedFetcher* From(LocalDOMWindow&);
......@@ -39,12 +39,12 @@ class CORE_EXPORT GlobalFetch {
static ScriptPromise fetch(ScriptState*,
LocalDOMWindow&,
const RequestInfo&,
const Dictionary&,
const RequestInit&,
ExceptionState&);
static ScriptPromise fetch(ScriptState*,
WorkerGlobalScope&,
const RequestInfo&,
const Dictionary&,
const RequestInit&,
ExceptionState&);
};
......
......@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_abort_signal.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
......@@ -40,6 +41,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
#include "third_party/blink/renderer/platform/weborigin/referrer.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
namespace blink {
......@@ -77,6 +79,14 @@ FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
return request;
}
static bool AreAnyMembersPresent(const RequestInit& init) {
return init.hasMethod() || init.hasHeaders() || init.hasBody() ||
init.hasReferrer() || init.hasReferrerPolicy() || init.hasMode() ||
init.hasCredentials() || init.hasCache() || init.hasRedirect() ||
init.hasIntegrity() || init.hasKeepalive() || init.hasImportance() ||
init.hasSignal();
}
static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
ExceptionState& exception_state,
v8::Local<v8::Value> body,
......@@ -147,10 +157,8 @@ Request* Request::CreateRequestWithRequestOrString(
ScriptState* script_state,
Request* input_request,
const String& input_string,
RequestInit& init,
const RequestInit& init,
ExceptionState& exception_state) {
v8::Local<v8::Value> init_body = init.GetBody().V8Value();
// Setup RequestInit's body first
// - "If |input| is a Request object and it is disturbed, throw a
// TypeError."
......@@ -253,7 +261,7 @@ Request* Request::CreateRequestWithRequestOrString(
}
// "If any of |init|'s members are present, then:"
if (init.AreAnyMembersSet()) {
if (AreAnyMembersPresent(init)) {
// "If |request|'s |mode| is "navigate", then set it to "same-origin".
if (request->Mode() == network::mojom::FetchRequestMode::kNavigate)
request->SetMode(network::mojom::FetchRequestMode::kSameOrigin);
......@@ -272,21 +280,21 @@ Request* Request::CreateRequestWithRequestOrString(
}
// "If init’s referrer member is present, then:"
if (!init.Referrer().IsNull()) {
if (init.hasReferrer()) {
// Nothing to do for the step "Let |referrer| be |init|'s referrer
// member."
if (init.Referrer().IsEmpty()) {
if (init.referrer().IsEmpty()) {
// "If |referrer| is the empty string, set |request|'s referrer to
// "no-referrer" and terminate these substeps."
request->SetReferrerString(AtomicString(Referrer::NoReferrer()));
} else {
// "Let |parsedReferrer| be the result of parsing |referrer| with
// |baseURL|."
KURL parsed_referrer(base_url, init.Referrer());
KURL parsed_referrer(base_url, init.referrer());
if (!parsed_referrer.IsValid()) {
// "If |parsedReferrer| is failure, throw a TypeError."
exception_state.ThrowTypeError("Referrer '" + init.Referrer() +
exception_state.ThrowTypeError("Referrer '" + init.referrer() +
"' is not a valid URL.");
return nullptr;
}
......@@ -316,25 +324,37 @@ Request* Request::CreateRequestWithRequestOrString(
// "If init's referrerPolicy member is present, set request's referrer
// policy to it."
if (init.GetReferrerPolicy().has_value())
request->SetReferrerPolicy(init.GetReferrerPolicy().value());
if (init.hasReferrerPolicy()) {
// In case referrerPolicy = "", the SecurityPolicy method below will not
// actually set referrer_policy, so we'll default to
// kReferrerPolicyDefault.
ReferrerPolicy referrer_policy;
if (!SecurityPolicy::ReferrerPolicyFromString(
init.referrerPolicy(), kDoNotSupportReferrerPolicyLegacyKeywords,
&referrer_policy)) {
DCHECK(init.referrerPolicy().IsEmpty());
referrer_policy = kReferrerPolicyDefault;
}
request->SetReferrerPolicy(referrer_policy);
}
// The following code performs the following steps:
// - "Let |mode| be |init|'s mode member if it is present, and
// |fallbackMode| otherwise."
// - "If |mode| is "navigate", throw a TypeError."
// - "If |mode| is non-null, set |request|'s mode to |mode|."
if (init.Mode() == "navigate") {
if (init.mode() == "navigate") {
exception_state.ThrowTypeError(
"Cannot construct a Request with a RequestInit whose mode member is "
"set as 'navigate'.");
return nullptr;
}
if (init.Mode() == "same-origin") {
if (init.mode() == "same-origin") {
request->SetMode(network::mojom::FetchRequestMode::kSameOrigin);
} else if (init.Mode() == "no-cors") {
} else if (init.mode() == "no-cors") {
request->SetMode(network::mojom::FetchRequestMode::kNoCORS);
} else if (init.Mode() == "cors") {
} else if (init.mode() == "cors") {
request->SetMode(network::mojom::FetchRequestMode::kCORS);
} else {
// |inputRequest| is directly checked here instead of setting and
......@@ -347,11 +367,11 @@ Request* Request::CreateRequestWithRequestOrString(
// "If |init|'s importance member is present, set |request|'s importance
// mode to it." For more information see Priority Hints at
// https://crbug.com/821464
DCHECK(init.Importance().IsNull() ||
DCHECK(init.importance().IsNull() ||
RuntimeEnabledFeatures::PriorityHintsEnabled());
if (init.Importance() == "low") {
if (init.importance() == "low") {
request->SetImportance(mojom::FetchImportanceMode::kImportanceLow);
} else if (init.Importance() == "high") {
} else if (init.importance() == "high") {
request->SetImportance(mojom::FetchImportanceMode::kImportanceHigh);
}
......@@ -361,24 +381,24 @@ Request* Request::CreateRequestWithRequestOrString(
// |credentials|."
network::mojom::FetchCredentialsMode credentials_mode;
if (ParseCredentialsMode(init.Credentials(), &credentials_mode)) {
if (ParseCredentialsMode(init.credentials(), &credentials_mode)) {
request->SetCredentials(credentials_mode);
} else if (!input_request) {
request->SetCredentials(network::mojom::FetchCredentialsMode::kSameOrigin);
}
// "If |init|'s cache member is present, set |request|'s cache mode to it."
if (init.CacheMode() == "default") {
if (init.cache() == "default") {
request->SetCacheMode(mojom::FetchCacheMode::kDefault);
} else if (init.CacheMode() == "no-store") {
} else if (init.cache() == "no-store") {
request->SetCacheMode(mojom::FetchCacheMode::kNoStore);
} else if (init.CacheMode() == "reload") {
} else if (init.cache() == "reload") {
request->SetCacheMode(mojom::FetchCacheMode::kBypassCache);
} else if (init.CacheMode() == "no-cache") {
} else if (init.cache() == "no-cache") {
request->SetCacheMode(mojom::FetchCacheMode::kValidateCache);
} else if (init.CacheMode() == "force-cache") {
} else if (init.cache() == "force-cache") {
request->SetCacheMode(mojom::FetchCacheMode::kForceCache);
} else if (init.CacheMode() == "only-if-cached") {
} else if (init.cache() == "only-if-cached") {
request->SetCacheMode(mojom::FetchCacheMode::kOnlyIfCached);
}
......@@ -393,47 +413,49 @@ Request* Request::CreateRequestWithRequestOrString(
// "If |init|'s redirect member is present, set |request|'s redirect mode
// to it."
if (init.Redirect() == "follow") {
if (init.redirect() == "follow") {
request->SetRedirect(network::mojom::FetchRedirectMode::kFollow);
} else if (init.Redirect() == "error") {
} else if (init.redirect() == "error") {
request->SetRedirect(network::mojom::FetchRedirectMode::kError);
} else if (init.Redirect() == "manual") {
} else if (init.redirect() == "manual") {
request->SetRedirect(network::mojom::FetchRedirectMode::kManual);
}
// "If |init|'s integrity member is present, set |request|'s
// integrity metadata to it."
if (!init.Integrity().IsNull())
request->SetIntegrity(init.Integrity());
if (init.hasIntegrity())
request->SetIntegrity(init.integrity());
if (init.Keepalive().has_value())
request->SetKeepalive(*init.Keepalive());
if (init.hasKeepalive())
request->SetKeepalive(init.keepalive());
// "If |init|'s method member is present, let |method| be it and run these
// substeps:"
if (!init.Method().IsNull()) {
if (init.hasMethod()) {
// "If |method| is not a method or method is a forbidden method, throw
// a TypeError."
if (!IsValidHTTPToken(init.Method())) {
exception_state.ThrowTypeError("'" + init.Method() +
if (!IsValidHTTPToken(init.method())) {
exception_state.ThrowTypeError("'" + init.method() +
"' is not a valid HTTP method.");
return nullptr;
}
if (FetchUtils::IsForbiddenMethod(init.Method())) {
exception_state.ThrowTypeError("'" + init.Method() +
if (FetchUtils::IsForbiddenMethod(init.method())) {
exception_state.ThrowTypeError("'" + init.method() +
"' HTTP method is unsupported.");
return nullptr;
}
// "Normalize |method|."
// "Set |request|'s method to |method|."
request->SetMethod(
FetchUtils::NormalizeMethod(AtomicString(init.Method())));
FetchUtils::NormalizeMethod(AtomicString(init.method())));
}
// "If |init|'s signal member is present, then set |signal| to it."
auto init_signal = init.Signal();
if (init_signal.has_value()) {
signal = init_signal.value();
v8::Local<v8::Value> init_signal =
init.hasSignal() ? init.signal().V8Value() : v8::Local<v8::Value>();
if (!init_signal.IsEmpty()) {
signal = V8AbortSignal::ToImplWithTypeCheck(script_state->GetIsolate(),
init_signal);
}
// "Let |r| be a new Request object associated with |request| and a new
......@@ -447,7 +469,7 @@ Request* Request::CreateRequestWithRequestOrString(
// We don't create a copy of r's Headers object when init's headers member
// is present.
Headers* headers = nullptr;
if (init.GetHeaders().IsNull()) {
if (!init.hasHeaders()) {
headers = r->getHeaders()->Clone();
}
// "Empty |r|'s request's header list."
......@@ -465,12 +487,12 @@ Request* Request::CreateRequestWithRequestOrString(
r->getHeaders()->SetGuard(Headers::kRequestNoCORSGuard);
}
// "If |signal| is not null, then make |r|’s signal follow |signal|."
if (signal) {
if (signal)
r->signal_->Follow(signal);
}
// "Fill |r|'s Headers object with |headers|. Rethrow any exceptions."
if (!init.GetHeaders().IsNull()) {
r->getHeaders()->FillWith(init.GetHeaders(), exception_state);
if (init.hasHeaders()) {
r->getHeaders()->FillWith(init.headers(), exception_state);
} else {
DCHECK(headers);
r->getHeaders()->FillWith(headers, exception_state);
......@@ -480,6 +502,8 @@ Request* Request::CreateRequestWithRequestOrString(
// "If either |init|'s body member is present or |temporaryBody| is
// non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError.
v8::Local<v8::Value> init_body =
init.hasBody() ? init.body().V8Value() : v8::Local<v8::Value>();
if ((!init_body.IsEmpty() && !init_body->IsNull()) || temporary_body) {
if (request->Method() == HTTPNames::GET ||
request->Method() == HTTPNames::HEAD) {
......@@ -547,7 +571,7 @@ Request* Request::CreateRequestWithRequestOrString(
Request* Request::Create(ScriptState* script_state,
const RequestInfo& input,
const Dictionary& init,
const RequestInit& init,
ExceptionState& exception_state) {
DCHECK(!input.IsNull());
if (input.IsUSVString())
......@@ -558,31 +582,29 @@ Request* Request::Create(ScriptState* script_state,
Request* Request::Create(ScriptState* script_state,
const String& input,
ExceptionState& exception_state) {
return Create(script_state, input, Dictionary(), exception_state);
return Create(script_state, input, RequestInit(), exception_state);
}
Request* Request::Create(ScriptState* script_state,
const String& input,
const Dictionary& init,
const RequestInit& init,
ExceptionState& exception_state) {
RequestInit request_init(script_state, init, exception_state);
return CreateRequestWithRequestOrString(script_state, nullptr, input,
request_init, exception_state);
return CreateRequestWithRequestOrString(script_state, nullptr, input, init,
exception_state);
}
Request* Request::Create(ScriptState* script_state,
Request* input,
ExceptionState& exception_state) {
return Create(script_state, input, Dictionary(), exception_state);
return Create(script_state, input, RequestInit(), exception_state);
}
Request* Request::Create(ScriptState* script_state,
Request* input,
const Dictionary& init,
const RequestInit& init,
ExceptionState& exception_state) {
RequestInit request_init(script_state, init, exception_state);
return CreateRequestWithRequestOrString(script_state, input, String(),
request_init, exception_state);
return CreateRequestWithRequestOrString(script_state, input, String(), init,
exception_state);
}
Request* Request::Create(ScriptState* script_state, FetchRequestData* request) {
......
......@@ -37,18 +37,18 @@ class CORE_EXPORT Request final : public Body {
// From Request.idl:
static Request* Create(ScriptState*,
const RequestInfo&,
const Dictionary&,
const RequestInit&,
ExceptionState&);
static Request* Create(ScriptState*, const String&, ExceptionState&);
static Request* Create(ScriptState*,
const String&,
const Dictionary&,
const RequestInit&,
ExceptionState&);
static Request* Create(ScriptState*, Request*, ExceptionState&);
static Request* Create(ScriptState*,
Request*,
const Dictionary&,
const RequestInit&,
ExceptionState&);
static Request* Create(ScriptState*, FetchRequestData*);
static Request* Create(ScriptState*, const WebServiceWorkerRequest&);
......@@ -96,7 +96,7 @@ class CORE_EXPORT Request final : public Body {
static Request* CreateRequestWithRequestOrString(ScriptState*,
Request*,
const String&,
RequestInit&,
const RequestInit&,
ExceptionState&);
String ContentType() const override;
......
......@@ -13,6 +13,7 @@ enum RequestCredentials { "omit", "same-origin", "include" };
enum RequestRedirect { "follow", "error", "manual" };
enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache",
"only-if-cached" };
enum RequestImportance {"low", "auto", "high"};
// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
......@@ -20,14 +21,17 @@ enum ReferrerPolicy {
"",
"no-referrer",
"no-referrer-when-downgrade",
"same-origin",
"origin",
"strict-origin",
"origin-when-cross-origin",
"strict-origin-when-cross-origin",
"unsafe-url"
};
[
ActiveScriptWrappable,
Constructor(RequestInfo input, optional Dictionary requestInitDict),
Constructor(RequestInfo input, optional RequestInit requestInitDict),
ConstructorCallWith=ScriptState,
Exposed=(Window,Worker),
RaisesException=Constructor
......
// Copyright 2014 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.
#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_abort_signal.h"
#include "third_party/blink/renderer/core/fetch/headers.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
namespace blink {
struct RequestInit::IDLPassThrough
: public IDLBaseHelper<v8::Local<v8::Value>> {};
template <>
struct NativeValueTraits<RequestInit::IDLPassThrough>
: public NativeValueTraitsBase<RequestInit::IDLPassThrough> {
static v8::Local<v8::Value> NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state) {
DCHECK(!value.IsEmpty());
return value;
}
};
class RequestInit::GetterHelper {
STACK_ALLOCATED();
public:
// |this| object must not outlive |src| and |exception_state|.
GetterHelper(const Dictionary& src, ExceptionState& exception_state)
: src_(src), exception_state_(exception_state) {}
template <typename IDLType>
base::Optional<typename IDLType::ImplType> Get(const StringView& key) {
auto r = src_.Get<IDLType>(key, exception_state_);
are_any_members_set_ = are_any_members_set_ || r.has_value();
return r;
}
bool AreAnyMembersSet() const { return are_any_members_set_; }
private:
const Dictionary& src_;
ExceptionState& exception_state_;
bool are_any_members_set_ = false;
DISALLOW_COPY_AND_ASSIGN(GetterHelper);
};
RequestInit::RequestInit(ScriptState* script_state,
const Dictionary& options,
ExceptionState& exception_state) {
GetterHelper h(options, exception_state);
ExecutionContext* context = ExecutionContext::From(script_state);
method_ = h.Get<IDLByteString>("method").value_or(String());
if (exception_state.HadException())
return;
auto v8_headers = h.Get<IDLPassThrough>("headers");
if (exception_state.HadException())
return;
mode_ = h.Get<IDLUSVString>("mode").value_or(String());
if (exception_state.HadException())
return;
cache_ = h.Get<IDLUSVString>("cache").value_or(String());
if (exception_state.HadException())
return;
redirect_ = h.Get<IDLUSVString>("redirect").value_or(String());
if (exception_state.HadException())
return;
referrer_ = h.Get<IDLUSVString>("referrer").value_or(String());
if (exception_state.HadException())
return;
auto referrer_policy_string = h.Get<IDLUSVString>("referrerPolicy");
if (exception_state.HadException())
return;
integrity_ = h.Get<IDLString>("integrity").value_or(String());
if (exception_state.HadException())
return;
if (RuntimeEnabledFeatures::PriorityHintsEnabled()) {
importance_ = h.Get<IDLString>("importance").value_or(String());
if (exception_state.HadException())
return;
}
keepalive_ = h.Get<IDLBoolean>("keepalive");
if (exception_state.HadException())
return;
base::Optional<v8::Local<v8::Value>> v8_signal;
// In order to distinguish between undefined and null, split the steps of
// looking it up in the dictionary and converting to the native type.
v8_signal = h.Get<IDLPassThrough>("signal");
if (exception_state.HadException())
return;
auto v8_body = h.Get<IDLPassThrough>("body");
if (exception_state.HadException())
return;
credentials_ = h.Get<IDLUSVString>("credentials").value_or(String());
if (exception_state.HadException())
return;
are_any_members_set_ = h.AreAnyMembersSet();
CheckEnumValues(referrer_policy_string, exception_state);
if (exception_state.HadException())
return;
v8::Isolate* isolate = ToIsolate(context);
if (v8_headers.has_value()) {
V8ByteStringSequenceSequenceOrByteStringByteStringRecord::ToImpl(
isolate, *v8_headers, headers_, UnionTypeConversionMode::kNotNullable,
exception_state);
if (exception_state.HadException())
return;
}
if (v8_signal.has_value()) {
if ((*v8_signal)->IsNull()) {
// Override any existing value.
signal_.emplace(nullptr);
} else {
signal_.emplace(NativeValueTraits<AbortSignal>::NativeValue(
isolate, *v8_signal, exception_state));
}
if (exception_state.HadException())
return;
}
if (v8_body.has_value())
body_ = ScriptValue(script_state, *v8_body);
}
base::Optional<AbortSignal*> RequestInit::Signal() const {
return signal_.has_value() ? base::make_optional(signal_.value().Get())
: base::nullopt;
}
void RequestInit::CheckEnumValues(
const base::Optional<String>& referrer_policy_string,
ExceptionState& exception_state) {
TRACE_EVENT0("blink", "RequestInit::CheckEnumValues");
// Validate cache_
if (!cache_.IsNull() && cache_ != "default" && cache_ != "no-store" &&
cache_ != "reload" && cache_ != "no-cache" && cache_ != "force-cache" &&
cache_ != "only-if-cached") {
exception_state.ThrowTypeError("Invalid cache mode");
return;
}
// Validate credentials_
if (!credentials_.IsNull() && credentials_ != "omit" &&
credentials_ != "same-origin" && credentials_ != "include") {
exception_state.ThrowTypeError("Invalid credentials mode");
return;
}
// Validate mode_
if (!mode_.IsNull() && mode_ != "navigate" && mode_ != "same-origin" &&
mode_ != "no-cors" && mode_ != "cors") {
exception_state.ThrowTypeError("Invalid mode");
return;
}
// Validate redirect_
if (!redirect_.IsNull() && redirect_ != "follow" && redirect_ != "error" &&
redirect_ != "manual") {
exception_state.ThrowTypeError("Invalid redirect mode");
return;
}
// Validate importance_
if (!importance_.IsNull() && importance_ != "low" && importance_ != "auto" &&
importance_ != "high") {
exception_state.ThrowTypeError("Invalid importance mode");
return;
}
// Validate referrer policy
if (referrer_policy_string.has_value()) {
if (*referrer_policy_string == "") {
referrer_policy_ = kReferrerPolicyDefault;
} else if (*referrer_policy_string == "no-referrer") {
referrer_policy_ = kReferrerPolicyNever;
} else if (*referrer_policy_string == "no-referrer-when-downgrade") {
referrer_policy_ = kReferrerPolicyNoReferrerWhenDowngrade;
} else if (*referrer_policy_string == "origin") {
referrer_policy_ = kReferrerPolicyOrigin;
} else if (*referrer_policy_string == "origin-when-cross-origin") {
referrer_policy_ = kReferrerPolicyOriginWhenCrossOrigin;
} else if (*referrer_policy_string == "same-origin") {
referrer_policy_ = kReferrerPolicySameOrigin;
} else if (*referrer_policy_string == "strict-origin") {
referrer_policy_ = kReferrerPolicyStrictOrigin;
} else if (*referrer_policy_string == "unsafe-url") {
referrer_policy_ = kReferrerPolicyAlways;
} else if (*referrer_policy_string == "strict-origin-when-cross-origin") {
referrer_policy_ = kReferrerPolicyStrictOriginWhenCrossOrigin;
} else {
exception_state.ThrowTypeError("Invalid referrer policy");
return;
}
}
}
} // namespace blink
// Copyright 2014 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_REQUEST_INIT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_REQUEST_INIT_H_
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "third_party/blink/renderer/bindings/core/v8/byte_string_sequence_sequence_or_byte_string_byte_string_record.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h"
#include "third_party/blink/renderer/core/fetch/headers.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/weborigin/referrer.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class AbortSignal;
class Dictionary;
class ExceptionState;
class ScriptState;
// FIXME: Use IDL dictionary instead of this class.
class RequestInit {
STACK_ALLOCATED();
public:
RequestInit(ScriptState*, const Dictionary&, ExceptionState&);
const String& Method() const { return method_; }
const HeadersInit& GetHeaders() const { return headers_; }
ScriptValue GetBody() const { return body_; }
const String& Referrer() const { return referrer_; }
base::Optional<ReferrerPolicy> GetReferrerPolicy() const {
return referrer_policy_;
}
const String& Mode() const { return mode_; }
const String& Credentials() const { return credentials_; }
const String& CacheMode() const { return cache_; }
const String& Redirect() const { return redirect_; }
const String& Integrity() const { return integrity_; }
const String& Importance() const { return importance_; }
const base::Optional<bool>& Keepalive() const { return keepalive_; }
base::Optional<AbortSignal*> Signal() const;
bool AreAnyMembersSet() const { return are_any_members_set_; }
private:
// These are defined here to avoid JUMBO ambiguity.
class GetterHelper;
struct IDLPassThrough;
friend struct NativeValueTraits<IDLPassThrough>;
friend struct NativeValueTraitsBase<IDLPassThrough>;
void CheckEnumValues(const base::Optional<String>& referrer_policy_string,
ExceptionState&);
void SetUpBody(ExecutionContext*,
v8::Isolate*,
v8::Local<v8::Value> v8_body,
ExceptionState&);
String method_;
HeadersInit headers_;
// Having a ScriptValue is safe here because this struct is STACK_ALLOCATED
// and not intended to live long.
ScriptValue body_;
String referrer_;
base::Optional<ReferrerPolicy> referrer_policy_;
String mode_;
String credentials_;
String cache_;
String redirect_;
String integrity_;
String importance_;
base::Optional<bool> keepalive_;
base::Optional<Member<AbortSignal>> signal_;
// True if any members in RequestInit are set and hence the referrer member
// should be used in the Request constructor.
bool are_any_members_set_ = false;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_REQUEST_INIT_H_
// Copyright 2018 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.
// https://fetch.spec.whatwg.org/#requestinit
// NOTE: Upon adding or removing any dictionary members here you must update
// the AreAnyMembersPresent function in request.cc.
dictionary RequestInit {
ByteString method;
HeadersInit headers;
// TODO(domfarolino): this should be of type BodyInit? when the IDL
// compiler can handle it.
any body;
USVString referrer;
ReferrerPolicy referrerPolicy;
RequestMode mode;
RequestCredentials credentials;
RequestCache cache;
RequestRedirect redirect;
DOMString integrity;
boolean keepalive;
[RuntimeEnabled=PriorityHints] RequestImportance importance;
// TODO(domfarolino): use AbortSignal? type for signal member once
// http://crrev.com/c/1113176 is merged.
any signal;
// TODO(domfarolino): add support for RequestInit window member.
//any window; // can only be set to null
};
......@@ -5,5 +5,5 @@
[
ImplementedAs=GlobalFetch
] partial interface Window {
[CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional Dictionary init);
[CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional RequestInit init);
};
......@@ -5,5 +5,5 @@
[
ImplementedAs=GlobalFetch
] partial interface WorkerGlobalScope {
[CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional Dictionary init);
[CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional RequestInit init);
};
......@@ -6,12 +6,12 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_request.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
......@@ -28,20 +28,6 @@ class BackgroundFetchManagerTest : public testing::Test {
return BackgroundFetchManager::CreateWebRequestVector(
scope.GetScriptState(), requests, scope.GetExceptionState());
}
// Returns a Dictionary object that represents a JavaScript dictionary with
// a single key-value pair, where the key always is "method" with the value
// set to |method|.
Dictionary GetDictionaryForMethod(V8TestingScope& scope, const char* method) {
v8::Isolate* isolate = scope.GetIsolate();
v8::Local<v8::Object> data = v8::Object::New(isolate);
data->Set(isolate->GetCurrentContext(), V8String(isolate, "method"),
V8String(isolate, method))
.ToChecked();
return Dictionary(scope.GetIsolate(), data, scope.GetExceptionState());
}
};
TEST_F(BackgroundFetchManagerTest, NullValue) {
......@@ -80,9 +66,11 @@ TEST_F(BackgroundFetchManagerTest, SingleRequest) {
KURL image_url("https://www.example.com/my_image.png");
Request* request = Request::Create(
scope.GetScriptState(), image_url.GetString(),
GetDictionaryForMethod(scope, "POST"), scope.GetExceptionState());
RequestInit request_init;
request_init.setMethod("POST");
Request* request =
Request::Create(scope.GetScriptState(), image_url.GetString(),
request_init, scope.GetExceptionState());
ASSERT_FALSE(scope.GetExceptionState().HadException());
ASSERT_TRUE(request);
......@@ -112,9 +100,11 @@ TEST_F(BackgroundFetchManagerTest, Sequence) {
RequestOrUSVString icon_request =
RequestOrUSVString::FromUSVString(icon_url.GetString());
Request* request = Request::Create(
scope.GetScriptState(), cat_video_url.GetString(),
GetDictionaryForMethod(scope, "DELETE"), scope.GetExceptionState());
RequestInit request_init;
request_init.setMethod("DELETE");
Request* request =
Request::Create(scope.GetScriptState(), cat_video_url.GetString(),
request_init, scope.GetExceptionState());
ASSERT_FALSE(scope.GetExceptionState().HadException());
ASSERT_TRUE(request);
......
......@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/fetch_data_loader.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
......@@ -662,7 +663,7 @@ ScriptPromise Cache::AddAllImpl(ScriptState* script_state,
request_infos[i].SetRequest(requests[i]);
promises[i] = scoped_fetcher_->Fetch(script_state, request_infos[i],
Dictionary(), exception_state);
RequestInit(), exception_state);
}
return ScriptPromise::All(script_state, promises)
......
......@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/global_fetch.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/core/fetch/response_init.h"
#include "third_party/blink/renderer/core/frame/frame.h"
......@@ -57,7 +58,7 @@ class ScopedFetcherForTests final
ScriptPromise Fetch(ScriptState* script_state,
const RequestInfo& request_info,
const Dictionary&,
const RequestInit&,
ExceptionState&) override {
++fetch_count_;
if (expected_url_) {
......
......@@ -222,7 +222,7 @@ void ServiceWorkerGlobalScope::DidEvaluateClassicScript() {
ScriptPromise ServiceWorkerGlobalScope::fetch(ScriptState* script_state,
const RequestInfo& input,
const Dictionary& init,
const RequestInit& init,
ExceptionState& exception_state) {
return GlobalFetch::fetch(script_state, *this, input, init, exception_state);
}
......
......@@ -41,8 +41,8 @@
namespace blink {
class Dictionary;
class RespondWithObserver;
class RequestInit;
class ScriptPromise;
class ScriptState;
class ServiceWorkerClients;
......@@ -91,7 +91,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
ScriptPromise fetch(ScriptState*,
const RequestInfo&,
const Dictionary&,
const RequestInit&,
ExceptionState&);
ScriptPromise skipWaiting(ScriptState*);
......
......@@ -38,7 +38,7 @@
readonly attribute Clients clients;
readonly attribute ServiceWorkerRegistration registration;
[CallWith=ScriptState, RaisesException] Promise<Response> fetch(RequestInfo input, optional Dictionary init);
[CallWith=ScriptState, RaisesException] Promise<Response> fetch(RequestInfo input, optional RequestInit init);
[CallWith=ScriptState] Promise<void> skipWaiting();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment