| // 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 "modules/fetch/Request.h" |
| |
| #include "bindings/core/v8/Dictionary.h" |
| #include "core/dom/Document.h" |
| #include "core/dom/ExecutionContext.h" |
| #include "core/fetch/FetchUtils.h" |
| #include "core/fetch/ResourceLoaderOptions.h" |
| #include "core/loader/ThreadableLoader.h" |
| #include "modules/fetch/BodyStreamBuffer.h" |
| #include "modules/fetch/DataConsumerHandleUtil.h" |
| #include "modules/fetch/FetchBlobDataConsumerHandle.h" |
| #include "modules/fetch/FetchManager.h" |
| #include "modules/fetch/RequestInit.h" |
| #include "platform/HTTPNames.h" |
| #include "platform/network/HTTPParsers.h" |
| #include "platform/network/ResourceRequest.h" |
| #include "platform/weborigin/Referrer.h" |
| #include "public/platform/WebURLRequest.h" |
| #include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h" |
| |
| namespace blink { |
| |
| FetchRequestData* createCopyOfFetchRequestDataForFetch(ScriptState* scriptState, const FetchRequestData* original) |
| { |
| FetchRequestData* request = FetchRequestData::create(); |
| request->setURL(original->url()); |
| request->setMethod(original->method()); |
| request->setHeaderList(original->headerList()->clone()); |
| request->setUnsafeRequestFlag(true); |
| // FIXME: Set client. |
| DOMWrapperWorld& world = scriptState->world(); |
| if (world.isIsolatedWorld()) |
| request->setOrigin(world.isolatedWorldSecurityOrigin()); |
| else |
| request->setOrigin(scriptState->getExecutionContext()->getSecurityOrigin()); |
| // FIXME: Set ForceOriginHeaderFlag. |
| request->setSameOriginDataURLFlag(true); |
| request->setReferrer(original->referrer()); |
| request->setMode(original->mode()); |
| request->setCredentials(original->credentials()); |
| request->setAttachedCredential(original->attachedCredential()); |
| request->setRedirect(original->redirect()); |
| request->setIntegrity(original->integrity()); |
| // FIXME: Set cache mode. |
| // TODO(yhirano): Set redirect mode. |
| return request; |
| } |
| |
| Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Request* inputRequest, const String& inputString, RequestInit& init, ExceptionState& exceptionState) |
| { |
| // - "If |input| is a Request object and it is disturbed, throw a |
| // TypeError." |
| if (inputRequest && inputRequest->bodyUsed()) { |
| exceptionState.throwTypeError("Cannot construct a Request with a Request object that has already been used."); |
| return nullptr; |
| } |
| // - "Let |temporaryBody| be |input|'s request's body if |input| is a |
| // Request object, and null otherwise." |
| BodyStreamBuffer* temporaryBody = inputRequest ? inputRequest->bodyBuffer() : nullptr; |
| |
| // "Let |request| be |input|'s request, if |input| is a Request object, |
| // and a new request otherwise." |
| |
| RefPtr<SecurityOrigin> origin = scriptState->getExecutionContext()->getSecurityOrigin(); |
| |
| // TODO(yhirano): Implement the following steps: |
| // - "Let |window| be client." |
| // - "If |request|'s window is an environment settings object and its |
| // origin is same origin with entry settings object's origin, set |
| // |window| to |request|'s window." |
| // - "If |init|'s window member is present and it is not null, throw a |
| // TypeError." |
| // - "If |init|'s window member is present, set |window| to no-window." |
| // |
| // "Set |request| to a new request whose url is |request|'s current url, |
| // method is |request|'s method, header list is a copy of |request|'s |
| // header list, unsafe-request flag is set, client is entry settings object, |
| // window is |window|, origin is "client", omit-Origin-header flag is |
| // |request|'s omit-Origin-header flag, same-origin data-URL flag is set, |
| // referrer is |request|'s referrer, referrer policy is |request|'s |
| // referrer policy, destination is the empty string, mode is |request|'s |
| // mode, credentials mode is |request|'s credentials mode, cache mode is |
| // |request|'s cache mode, redirect mode is |request|'s redirect mode, and |
| // integrity metadata is |request|'s integrity metadata." |
| FetchRequestData* request = createCopyOfFetchRequestDataForFetch(scriptState, inputRequest ? inputRequest->request() : FetchRequestData::create()); |
| |
| // We don't use fallback values. We set these flags directly in below. |
| // - "Let |fallbackMode| be null." |
| // - "Let |fallbackCredentials| be null." |
| // - "Let |baseURL| be entry settings object's API base URL." |
| |
| // "If |input| is a string, run these substeps:" |
| if (!inputRequest) { |
| // "Let |parsedURL| be the result of parsing |input| with |baseURL|." |
| KURL parsedURL = scriptState->getExecutionContext()->completeURL(inputString); |
| // "If |parsedURL| is failure, throw a TypeError." |
| if (!parsedURL.isValid()) { |
| exceptionState.throwTypeError("Failed to parse URL from " + inputString); |
| return nullptr; |
| } |
| // "If |parsedURL| includes credentials, throw a TypeError." |
| if (!parsedURL.user().isEmpty() || !parsedURL.pass().isEmpty()) { |
| exceptionState.throwTypeError("Request cannot be constructed from a URL that includes credentials: " + inputString); |
| return nullptr; |
| } |
| // "Set |request|'s url to |parsedURL| and replace |request|'s url list |
| // single URL with a copy of |parsedURL|." |
| request->setURL(parsedURL); |
| |
| // We don't use fallback values. We set these flags directly in below. |
| // - "Set |fallbackMode| to "cors"." |
| // - "Set |fallbackCredentials| to "omit"." |
| } |
| |
| // "If any of |init|'s members are present, run these substeps:" |
| if (init.areAnyMembersSet) { |
| // "If |request|'s |mode| is "navigate", throw a TypeError." |
| if (request->mode() == WebURLRequest::FetchRequestModeNavigate) { |
| exceptionState.throwTypeError("Cannot construct a Request with a Request whose mode is 'navigate' and a non-empty RequestInit."); |
| return nullptr; |
| } |
| |
| // TODO(yhirano): Implement the following substep: |
| // "Unset |request|'s omit-Origin-header flag." |
| |
| // The substep "Set |request|'s referrer to "client"." is performed by |
| // the code below as follows: |
| // - |init.referrer.referrer| gets initialized by the RequestInit |
| // constructor to "about:client" when any of |options|'s members are |
| // present. |
| // - The code below does the equivalent as the step specified in the |
| // spec by processing the "about:client". |
| |
| // The substep "Set |request|'s referrer policy to the empty string." |
| // is also performed by the code below similarly. |
| } |
| |
| // The following if-clause performs the following two steps: |
| // - "If |init|'s referrer member is present, run these substeps:" |
| // - TODO(yhirano): Implement the following step: |
| // "If |init|'s referrerPolicy member is present, set |request|'s |
| // referrer policy to it." |
| // |
| // The condition "if any of |init|'s members are present" |
| // (areAnyMembersSet) is used for the if-clause instead of conditions |
| // indicating presence of each member as specified in the spec. This is to |
| // perform the substeps in the previous step together here. |
| if (init.areAnyMembersSet) { |
| // Nothing to do for the step "Let |referrer| be |init|'s referrer |
| // member." |
| |
| if (init.referrer.referrer.isEmpty()) { |
| // "If |referrer| is the empty string, set |request|'s referrer to |
| // "no-referrer" and terminate these substeps." |
| request->setReferrerString(FetchRequestData::noReferrerString()); |
| } else { |
| // "Let |parsedReferrer| be the result of parsing |referrer| with |
| // |baseURL|." |
| KURL parsedReferrer = scriptState->getExecutionContext()->completeURL(init.referrer.referrer); |
| if (!parsedReferrer.isValid()) { |
| // "If |parsedReferrer| is failure, throw a TypeError." |
| exceptionState.throwTypeError("Referrer '" + init.referrer.referrer + "' is not a valid URL."); |
| return nullptr; |
| } |
| if (parsedReferrer.protocolIsAbout() && parsedReferrer.host().isEmpty() && parsedReferrer.path() == "client") { |
| // "If |parsedReferrer|'s non-relative flag is set, scheme is |
| // "about", and path contains a single string "client", set |
| // request's referrer to "client" and terminate these |
| // substeps." |
| request->setReferrerString(FetchRequestData::clientReferrerString()); |
| } else if (!origin->isSameSchemeHostPortAndSuborigin(SecurityOrigin::create(parsedReferrer).get())) { |
| // "If |parsedReferrer|'s origin is not same origin with |
| // |origin|, throw a TypeError." |
| exceptionState.throwTypeError("The origin of '" + init.referrer.referrer + "' should be same as '" + origin->toString() + "'"); |
| return nullptr; |
| } else { |
| // "Set |request|'s referrer to |parsedReferrer|." |
| request->setReferrerString(AtomicString(parsedReferrer.getString())); |
| } |
| } |
| request->setReferrerPolicy(init.referrer.referrerPolicy); |
| } |
| |
| // 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") { |
| exceptionState.throwTypeError("Cannot construct a Request with a RequestInit whose mode member is set as 'navigate'."); |
| return nullptr; |
| } |
| if (init.mode == "same-origin") { |
| request->setMode(WebURLRequest::FetchRequestModeSameOrigin); |
| } else if (init.mode == "no-cors") { |
| request->setMode(WebURLRequest::FetchRequestModeNoCORS); |
| } else if (init.mode == "cors") { |
| request->setMode(WebURLRequest::FetchRequestModeCORS); |
| } else { |
| // |inputRequest| is directly checked here instead of setting and |
| // checking |fallbackMode| as specified in the spec. |
| if (!inputRequest) |
| request->setMode(WebURLRequest::FetchRequestModeCORS); |
| } |
| |
| // "Let |credentials| be |init|'s credentials member if it is present, and |
| // |fallbackCredentials| otherwise." |
| // "If |credentials| is non-null, set |request|'s credentials mode to |
| // |credentials|." |
| if (init.credentials == "omit") { |
| request->setCredentials(WebURLRequest::FetchCredentialsModeOmit); |
| } else if (init.credentials == "same-origin") { |
| request->setCredentials(WebURLRequest::FetchCredentialsModeSameOrigin); |
| } else if (init.credentials == "include") { |
| request->setCredentials(WebURLRequest::FetchCredentialsModeInclude); |
| } else if (init.credentials == "password") { |
| if (!init.attachedCredential.get()) { |
| exceptionState.throwTypeError("Cannot construct a Request with a credential mode of 'password' without a PasswordCredential."); |
| return nullptr; |
| } |
| request->setCredentials(WebURLRequest::FetchCredentialsModePassword); |
| request->setAttachedCredential(init.attachedCredential); |
| request->setRedirect(WebURLRequest::FetchRedirectModeManual); |
| } else { |
| if (!inputRequest) |
| request->setCredentials(WebURLRequest::FetchCredentialsModeOmit); |
| } |
| |
| // TODO(yhirano): Implement the following step: |
| // "If |init|'s cache member is present, set |request|'s cache mode to |
| // it." |
| |
| // "If |init|'s redirect member is present, set |request|'s redirect mode |
| // to it." |
| if (init.redirect == "follow") { |
| request->setRedirect(WebURLRequest::FetchRedirectModeFollow); |
| } else if (init.redirect == "error") { |
| request->setRedirect(WebURLRequest::FetchRedirectModeError); |
| } else if (init.redirect == "manual") { |
| request->setRedirect(WebURLRequest::FetchRedirectModeManual); |
| } |
| |
| // "If |init|'s integrity member is present, set |request|'s |
| // integrity metadata to it." |
| if (!init.integrity.isNull()) |
| request->setIntegrity(init.integrity); |
| |
| // "If |init|'s method member is present, let |method| be it and run these |
| // substeps:" |
| if (!init.method.isNull()) { |
| // "If |method| is not a method or method is a forbidden method, throw |
| // a TypeError." |
| if (!isValidHTTPToken(init.method)) { |
| exceptionState.throwTypeError("'" + init.method + "' is not a valid HTTP method."); |
| return nullptr; |
| } |
| if (FetchUtils::isForbiddenMethod(init.method)) { |
| exceptionState.throwTypeError("'" + init.method + "' HTTP method is unsupported."); |
| return nullptr; |
| } |
| // "Normalize |method|." |
| // "Set |request|'s method to |method|." |
| request->setMethod(FetchUtils::normalizeMethod(AtomicString(init.method))); |
| } |
| // "Let |r| be a new Request object associated with |request| and a new |
| // Headers object whose guard is "request"." |
| Request* r = Request::create(scriptState->getExecutionContext(), request); |
| // Perform the following steps: |
| // - "Let |headers| be a copy of |r|'s Headers object." |
| // - "If |init|'s headers member is present, set |headers| to |init|'s |
| // headers member." |
| // |
| // We don't create a copy of r's Headers object when init's headers member |
| // is present. |
| Headers* headers = nullptr; |
| if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { |
| headers = r->getHeaders()->clone(); |
| } |
| // "Empty |r|'s request's header list." |
| r->m_request->headerList()->clearList(); |
| // "If |r|'s request's mode is "no-cors", run these substeps: |
| if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { |
| // "If |r|'s request's method is not a simple method, throw a |
| // TypeError." |
| if (!FetchUtils::isSimpleMethod(r->request()->method())) { |
| exceptionState.throwTypeError("'" + r->request()->method() + "' is unsupported in no-cors mode."); |
| return nullptr; |
| } |
| // "If |request|'s integrity metadata is not the empty string, throw a |
| // TypeError." |
| if (!request->integrity().isEmpty()) { |
| exceptionState.throwTypeError("The integrity attribute is unsupported in no-cors mode."); |
| return nullptr; |
| } |
| // "Set |r|'s Headers object's guard to "request-no-cors"." |
| r->getHeaders()->setGuard(Headers::RequestNoCORSGuard); |
| } |
| // "Fill |r|'s Headers object with |headers|. Rethrow any exceptions." |
| if (init.headers) { |
| ASSERT(init.headersDictionary.isUndefinedOrNull()); |
| r->getHeaders()->fillWith(init.headers.get(), exceptionState); |
| } else if (!init.headersDictionary.isUndefinedOrNull()) { |
| r->getHeaders()->fillWith(init.headersDictionary, exceptionState); |
| } else { |
| ASSERT(headers); |
| r->getHeaders()->fillWith(headers, exceptionState); |
| } |
| if (exceptionState.hadException()) |
| return nullptr; |
| |
| // "If either |init|'s body member is present or |temporaryBody| is |
| // non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError. |
| if (init.body || temporaryBody || request->credentials() == WebURLRequest::FetchCredentialsModePassword) { |
| if (request->method() == HTTPNames::GET || request->method() == HTTPNames::HEAD) { |
| exceptionState.throwTypeError("Request with GET/HEAD method cannot have body."); |
| return nullptr; |
| } |
| } |
| |
| // TODO(mkwst): See the comment in RequestInit about serializing the attached credential |
| // prior to hitting the Service Worker machinery. |
| if (request->credentials() == WebURLRequest::FetchCredentialsModePassword) { |
| r->getHeaders()->append(HTTPNames::Content_Type, init.contentType, exceptionState); |
| |
| // TODO(mkwst): This should be a registrable-domain match. |
| if (!origin->canRequest(r->url())) { |
| exceptionState.throwTypeError("Credentials may only be submitted to same-origin endpoints."); |
| return nullptr; |
| } |
| } |
| |
| // "If |init|'s body member is present, run these substeps:" |
| if (init.body) { |
| // Perform the following steps: |
| // - "Let |stream| and |Content-Type| be the result of extracting |
| // |init|'s body member." |
| // - "Set |temporaryBody| to |stream|. |
| // - "If |Content-Type| is non-null and |r|'s request's header list |
| // contains no header named `Content-Type`, append |
| // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any |
| // exception." |
| temporaryBody = new BodyStreamBuffer(init.body.release()); |
| if (!init.contentType.isEmpty() && !r->getHeaders()->has(HTTPNames::Content_Type, exceptionState)) { |
| r->getHeaders()->append(HTTPNames::Content_Type, init.contentType, exceptionState); |
| } |
| if (exceptionState.hadException()) |
| return nullptr; |
| } |
| |
| // "Set |r|'s request's body to |temporaryBody|. |
| if (temporaryBody) |
| r->m_request->setBuffer(temporaryBody); |
| |
| // "Set |r|'s MIME type to the result of extracting a MIME type from |r|'s |
| // request's header list." |
| r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType()); |
| |
| // "If |input| is a Request object and |input|'s request's body is |
| // non-null, run these substeps:" |
| if (inputRequest && inputRequest->bodyBuffer()) { |
| // "Set |input|'s body to an empty byte stream." |
| inputRequest->m_request->setBuffer(new BodyStreamBuffer(createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle()))); |
| // "Set |input|'s disturbed flag." |
| inputRequest->bodyBuffer()->stream()->setIsDisturbed(); |
| } |
| |
| // "Return |r|." |
| return r; |
| } |
| |
| Request* Request::create(ScriptState* scriptState, const RequestInfo& input, const Dictionary& init, ExceptionState& exceptionState) |
| { |
| ASSERT(!input.isNull()); |
| if (input.isUSVString()) |
| return create(scriptState, input.getAsUSVString(), init, exceptionState); |
| return create(scriptState, input.getAsRequest(), init, exceptionState); |
| } |
| |
| Request* Request::create(ScriptState* scriptState, const String& input, ExceptionState& exceptionState) |
| { |
| return create(scriptState, input, Dictionary(), exceptionState); |
| } |
| |
| Request* Request::create(ScriptState* scriptState, const String& input, const Dictionary& init, ExceptionState& exceptionState) |
| { |
| RequestInit requestInit(scriptState->getExecutionContext(), init, exceptionState); |
| return createRequestWithRequestOrString(scriptState, nullptr, input, requestInit, exceptionState); |
| } |
| |
| Request* Request::create(ScriptState* scriptState, Request* input, ExceptionState& exceptionState) |
| { |
| return create(scriptState, input, Dictionary(), exceptionState); |
| } |
| |
| Request* Request::create(ScriptState* scriptState, Request* input, const Dictionary& init, ExceptionState& exceptionState) |
| { |
| RequestInit requestInit(scriptState->getExecutionContext(), init, exceptionState); |
| return createRequestWithRequestOrString(scriptState, input, String(), requestInit, exceptionState); |
| } |
| |
| Request* Request::create(ExecutionContext* context, FetchRequestData* request) |
| { |
| return new Request(context, request); |
| } |
| |
| Request::Request(ExecutionContext* context, FetchRequestData* request) |
| : Body(context) |
| , m_request(request) |
| , m_headers(Headers::create(m_request->headerList())) |
| { |
| m_headers->setGuard(Headers::RequestGuard); |
| } |
| |
| Request::Request(ExecutionContext* context, FetchRequestData* request, Headers* headers) |
| : Body(context) , m_request(request) , m_headers(headers) {} |
| |
| Request* Request::create(ExecutionContext* context, const WebServiceWorkerRequest& webRequest) |
| { |
| return new Request(context, webRequest); |
| } |
| |
| Request::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRequest) |
| : Body(context) |
| , m_request(FetchRequestData::create(context, webRequest)) |
| , m_headers(Headers::create(m_request->headerList())) |
| { |
| m_headers->setGuard(Headers::RequestGuard); |
| } |
| |
| String Request::method() const |
| { |
| // "The method attribute's getter must return request's method." |
| return m_request->method(); |
| } |
| |
| KURL Request::url() const |
| { |
| // The url attribute's getter must return request's url, serialized with the exclude fragment flag set. |
| if (!m_request->url().hasFragmentIdentifier()) |
| return m_request->url(); |
| KURL url(m_request->url()); |
| url.removeFragmentIdentifier(); |
| return url; |
| } |
| |
| String Request::context() const |
| { |
| // "The context attribute's getter must return request's context" |
| switch (m_request->context()) { |
| case WebURLRequest::RequestContextUnspecified: |
| return ""; |
| case WebURLRequest::RequestContextAudio: |
| return "audio"; |
| case WebURLRequest::RequestContextBeacon: |
| return "beacon"; |
| case WebURLRequest::RequestContextCSPReport: |
| return "cspreport"; |
| case WebURLRequest::RequestContextDownload: |
| return "download"; |
| case WebURLRequest::RequestContextEmbed: |
| return "embed"; |
| case WebURLRequest::RequestContextEventSource: |
| return "eventsource"; |
| case WebURLRequest::RequestContextFavicon: |
| return "favicon"; |
| case WebURLRequest::RequestContextFetch: |
| return "fetch"; |
| case WebURLRequest::RequestContextFont: |
| return "font"; |
| case WebURLRequest::RequestContextForm: |
| return "form"; |
| case WebURLRequest::RequestContextFrame: |
| return "frame"; |
| case WebURLRequest::RequestContextHyperlink: |
| return "hyperlink"; |
| case WebURLRequest::RequestContextIframe: |
| return "iframe"; |
| case WebURLRequest::RequestContextImage: |
| return "image"; |
| case WebURLRequest::RequestContextImageSet: |
| return "imageset"; |
| case WebURLRequest::RequestContextImport: |
| return "import"; |
| case WebURLRequest::RequestContextInternal: |
| return "internal"; |
| case WebURLRequest::RequestContextLocation: |
| return "location"; |
| case WebURLRequest::RequestContextManifest: |
| return "manifest"; |
| case WebURLRequest::RequestContextObject: |
| return "object"; |
| case WebURLRequest::RequestContextPing: |
| return "ping"; |
| case WebURLRequest::RequestContextPlugin: |
| return "plugin"; |
| case WebURLRequest::RequestContextPrefetch: |
| return "prefetch"; |
| case WebURLRequest::RequestContextScript: |
| return "script"; |
| case WebURLRequest::RequestContextServiceWorker: |
| return "serviceworker"; |
| case WebURLRequest::RequestContextSharedWorker: |
| return "sharedworker"; |
| case WebURLRequest::RequestContextSubresource: |
| return "subresource"; |
| case WebURLRequest::RequestContextStyle: |
| return "style"; |
| case WebURLRequest::RequestContextTrack: |
| return "track"; |
| case WebURLRequest::RequestContextVideo: |
| return "video"; |
| case WebURLRequest::RequestContextWorker: |
| return "worker"; |
| case WebURLRequest::RequestContextXMLHttpRequest: |
| return "xmlhttprequest"; |
| case WebURLRequest::RequestContextXSLT: |
| return "xslt"; |
| } |
| ASSERT_NOT_REACHED(); |
| return ""; |
| } |
| |
| String Request::referrer() const |
| { |
| // "The referrer attribute's getter must return the empty string if |
| // request's referrer is no referrer, "about:client" if request's referrer |
| // is client and request's referrer, serialized, otherwise." |
| ASSERT(FetchRequestData::noReferrerString() == AtomicString()); |
| ASSERT(FetchRequestData::clientReferrerString() == AtomicString("about:client")); |
| return m_request->referrerString(); |
| } |
| |
| String Request::mode() const |
| { |
| // "The mode attribute's getter must return the value corresponding to the |
| // first matching statement, switching on request's mode:" |
| switch (m_request->mode()) { |
| case WebURLRequest::FetchRequestModeSameOrigin: |
| return "same-origin"; |
| case WebURLRequest::FetchRequestModeNoCORS: |
| return "no-cors"; |
| case WebURLRequest::FetchRequestModeCORS: |
| case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: |
| return "cors"; |
| case WebURLRequest::FetchRequestModeNavigate: |
| return "navigate"; |
| } |
| ASSERT_NOT_REACHED(); |
| return ""; |
| } |
| |
| String Request::credentials() const |
| { |
| // "The credentials attribute's getter must return the value corresponding |
| // to the first matching statement, switching on request's credentials |
| // mode:" |
| switch (m_request->credentials()) { |
| case WebURLRequest::FetchCredentialsModeOmit: |
| return "omit"; |
| case WebURLRequest::FetchCredentialsModeSameOrigin: |
| return "same-origin"; |
| case WebURLRequest::FetchCredentialsModeInclude: |
| return "include"; |
| case WebURLRequest::FetchCredentialsModePassword: |
| return "password"; |
| } |
| ASSERT_NOT_REACHED(); |
| return ""; |
| } |
| |
| String Request::redirect() const |
| { |
| // "The redirect attribute's getter must return request's redirect mode." |
| switch (m_request->redirect()) { |
| case WebURLRequest::FetchRedirectModeFollow: |
| return "follow"; |
| case WebURLRequest::FetchRedirectModeError: |
| return "error"; |
| case WebURLRequest::FetchRedirectModeManual: |
| return "manual"; |
| } |
| ASSERT_NOT_REACHED(); |
| return ""; |
| } |
| |
| String Request::integrity() const |
| { |
| return m_request->integrity(); |
| } |
| |
| Request* Request::clone(ExceptionState& exceptionState) |
| { |
| if (isBodyLocked() || bodyUsed()) { |
| exceptionState.throwTypeError("Request body is already used"); |
| return nullptr; |
| } |
| |
| FetchRequestData* request = m_request->clone(getExecutionContext()); |
| Headers* headers = Headers::create(request->headerList()); |
| headers->setGuard(m_headers->getGuard()); |
| return new Request(getExecutionContext(), request, headers); |
| } |
| |
| FetchRequestData* Request::passRequestData() |
| { |
| ASSERT(!bodyUsed()); |
| return m_request->pass(getExecutionContext()); |
| } |
| |
| bool Request::hasBody() const |
| { |
| return bodyBuffer(); |
| } |
| |
| void Request::stop() |
| { |
| if (bodyBuffer()) |
| bodyBuffer()->stop(); |
| } |
| |
| void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webRequest) const |
| { |
| webRequest.setMethod(method()); |
| webRequest.setRequestContext(m_request->context()); |
| // This strips off the fragment part. |
| webRequest.setURL(url()); |
| |
| const FetchHeaderList* headerList = m_headers->headerList(); |
| for (size_t i = 0, size = headerList->size(); i < size; ++i) { |
| const FetchHeaderList::Header& header = headerList->entry(i); |
| webRequest.appendHeader(header.first, header.second); |
| } |
| |
| webRequest.setReferrer(m_request->referrerString(), static_cast<WebReferrerPolicy>(m_request->getReferrerPolicy())); |
| // FIXME: How can we set isReload properly? What is the correct place to load it in to the Request object? We should investigate the right way |
| // to plumb this information in to here. |
| } |
| |
| String Request::mimeType() const |
| { |
| return m_request->mimeType(); |
| } |
| |
| DEFINE_TRACE(Request) |
| { |
| Body::trace(visitor); |
| visitor->trace(m_request); |
| visitor->trace(m_headers); |
| } |
| |
| } // namespace blink |