// 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/loader/ThreadableLoader.h"
#include "modules/fetch/BodyStreamBuffer.h"
#include "modules/fetch/FetchManager.h"
#include "modules/fetch/RequestInit.h"
#include "platform/HTTPNames.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/bindings/V8PrivateProperty.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h"
#include "platform/loader/fetch/ResourceRequest.h"
#include "platform/network/HTTPParsers.h"
#include "platform/weborigin/OriginAccessEntry.h"
#include "platform/weborigin/Referrer.h"
#include "public/platform/WebURLRequest.h"
#include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h"

namespace blink {

FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
    ScriptState* script_state,
    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 = script_state->World();
  if (world.IsIsolatedWorld()) {
    request->SetOrigin(world.IsolatedWorldSecurityOrigin());
  } else {
    request->SetOrigin(
        ExecutionContext::From(script_state)->GetSecurityOrigin());
  }
  // FIXME: Set ForceOriginHeaderFlag.
  request->SetSameOriginDataURLFlag(true);
  request->SetReferrer(original->GetReferrer());
  request->SetMode(original->Mode());
  request->SetCredentials(original->Credentials());
  request->SetCacheMode(original->CacheMode());
  request->SetAttachedCredential(original->AttachedCredential());
  request->SetRedirect(original->Redirect());
  request->SetIntegrity(original->Integrity());
  return request;
}

Request* Request::CreateRequestWithRequestOrString(
    ScriptState* script_state,
    Request* input_request,
    const String& input_string,
    RequestInit& init,
    ExceptionState& exception_state) {
  // - "If |input| is a Request object and it is disturbed, throw a
  //   TypeError."
  if (input_request && input_request->bodyUsed()) {
    exception_state.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* temporary_body =
      input_request ? input_request->BodyBuffer() : nullptr;

  // "Let |request| be |input|'s request, if |input| is a Request object,
  // and a new request otherwise."

  RefPtr<SecurityOrigin> origin =
      ExecutionContext::From(script_state)->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(
      script_state,
      input_request ? input_request->GetRequest() : 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 (!input_request) {
    // "Let |parsedURL| be the result of parsing |input| with |baseURL|."
    KURL parsed_url =
        ExecutionContext::From(script_state)->CompleteURL(input_string);
    // "If |parsedURL| is failure, throw a TypeError."
    if (!parsed_url.IsValid()) {
      exception_state.ThrowTypeError("Failed to parse URL from " +
                                     input_string);
      return nullptr;
    }
    //   "If |parsedURL| includes credentials, throw a TypeError."
    if (!parsed_url.User().IsEmpty() || !parsed_url.Pass().IsEmpty()) {
      exception_state.ThrowTypeError(
          "Request cannot be constructed from a URL that includes "
          "credentials: " +
          input_string);
      return nullptr;
    }
    // "Set |request|'s url to |parsedURL| and replace |request|'s url list
    // single URL with a copy of |parsedURL|."
    request->SetURL(parsed_url);

    // 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.are_any_members_set) {
    // "If |request|'s |mode| is "navigate", throw a TypeError."
    if (request->Mode() == WebURLRequest::kFetchRequestModeNavigate) {
      exception_state.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:"
  //   "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.are_any_members_set) {
    // 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(AtomicString(Referrer::NoReferrer()));
    } else {
      // "Let |parsedReferrer| be the result of parsing |referrer| with
      // |baseURL|."
      KURL parsed_referrer = ExecutionContext::From(script_state)
                                 ->CompleteURL(init.referrer.referrer);
      if (!parsed_referrer.IsValid()) {
        // "If |parsedReferrer| is failure, throw a TypeError."
        exception_state.ThrowTypeError("Referrer '" + init.referrer.referrer +
                                       "' is not a valid URL.");
        return nullptr;
      }
      if (parsed_referrer.ProtocolIsAbout() &&
          parsed_referrer.Host().IsEmpty() &&
          parsed_referrer.GetPath() == "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(parsed_referrer).Get())) {
        // "If |parsedReferrer|'s origin is not same origin with
        // |origin|, throw a TypeError."
        exception_state.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(parsed_referrer.GetString()));
      }
    }
    request->SetReferrerPolicy(init.referrer.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") {
    exception_state.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::kFetchRequestModeSameOrigin);
  } else if (init.mode == "no-cors") {
    request->SetMode(WebURLRequest::kFetchRequestModeNoCORS);
  } else if (init.mode == "cors") {
    request->SetMode(WebURLRequest::kFetchRequestModeCORS);
  } else {
    // |inputRequest| is directly checked here instead of setting and
    // checking |fallbackMode| as specified in the spec.
    if (!input_request)
      request->SetMode(WebURLRequest::kFetchRequestModeCORS);
  }

  // "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::kFetchCredentialsModeOmit);
  } else if (init.credentials == "same-origin") {
    request->SetCredentials(WebURLRequest::kFetchCredentialsModeSameOrigin);
  } else if (init.credentials == "include") {
    request->SetCredentials(WebURLRequest::kFetchCredentialsModeInclude);
  } else if (init.credentials == "password") {
    if (!init.attached_credential.Get()) {
      exception_state.ThrowTypeError(
          "Cannot construct a Request with a credential mode of 'password' "
          "without a PasswordCredential.");
      return nullptr;
    }
    request->SetCredentials(WebURLRequest::kFetchCredentialsModePassword);
    request->SetAttachedCredential(init.attached_credential);
    request->SetRedirect(WebURLRequest::kFetchRedirectModeManual);
  } else {
    if (!input_request)
      request->SetCredentials(WebURLRequest::kFetchCredentialsModeOmit);
  }

  // "If |init|'s cache member is present, set |request|'s cache mode to it."
  if (init.cache == "default") {
    request->SetCacheMode(WebURLRequest::kFetchRequestCacheModeDefault);
  } else if (init.cache == "no-store") {
    request->SetCacheMode(WebURLRequest::kFetchRequestCacheModeNoStore);
  } else if (init.cache == "reload") {
    request->SetCacheMode(WebURLRequest::kFetchRequestCacheModeReload);
  } else if (init.cache == "no-cache") {
    request->SetCacheMode(WebURLRequest::kFetchRequestCacheModeNoCache);
  } else if (init.cache == "force-cache") {
    request->SetCacheMode(WebURLRequest::kFetchRequestCacheModeForceCache);
  } else if (init.cache == "only-if-cached") {
    request->SetCacheMode(WebURLRequest::kFetchRequestCacheModeOnlyIfCached);
  }

  // "If |init|'s redirect member is present, set |request|'s redirect mode
  // to it."
  if (init.redirect == "follow") {
    request->SetRedirect(WebURLRequest::kFetchRedirectModeFollow);
  } else if (init.redirect == "error") {
    request->SetRedirect(WebURLRequest::kFetchRedirectModeError);
  } else if (init.redirect == "manual") {
    request->SetRedirect(WebURLRequest::kFetchRedirectModeManual);
  }

  // "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)) {
      exception_state.ThrowTypeError("'" + init.method +
                                     "' is not a valid HTTP method.");
      return nullptr;
    }
    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)));
  }
  // "Let |r| be a new Request object associated with |request| and a new
  // Headers object whose guard is "request"."
  Request* r = Request::Create(script_state, 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.isNull()) {
    headers = r->getHeaders()->Clone();
  }
  // "Empty |r|'s request's header list."
  r->request_->HeaderList()->ClearList();
  // "If |r|'s request's mode is "no-cors", run these substeps:
  if (r->GetRequest()->Mode() == WebURLRequest::kFetchRequestModeNoCORS) {
    // "If |r|'s request's method is not a CORS-safelisted method, throw a
    // TypeError."
    if (!FetchUtils::IsCORSSafelistedMethod(r->GetRequest()->Method())) {
      exception_state.ThrowTypeError("'" + r->GetRequest()->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()) {
      exception_state.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::kRequestNoCORSGuard);
  }
  // "Fill |r|'s Headers object with |headers|. Rethrow any exceptions."
  if (!init.headers.isNull()) {
    r->getHeaders()->FillWith(init.headers, exception_state);
  } else {
    DCHECK(headers);
    r->getHeaders()->FillWith(headers, exception_state);
  }
  if (exception_state.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 || temporary_body ||
      request->Credentials() == WebURLRequest::kFetchCredentialsModePassword) {
    if (request->Method() == HTTPNames::GET ||
        request->Method() == HTTPNames::HEAD) {
      exception_state.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::kFetchCredentialsModePassword) {
    r->getHeaders()->append(HTTPNames::Content_Type, init.content_type,
                            exception_state);

    const OriginAccessEntry access_entry =
        OriginAccessEntry(r->url().Protocol(), r->url().Host(),
                          OriginAccessEntry::kAllowRegisterableDomains);
    if (access_entry.MatchesDomain(*origin) ==
        OriginAccessEntry::kDoesNotMatchOrigin) {
      exception_state.ThrowTypeError(
          "Credentials may only be submitted to endpoints on the same "
          "registrable domain.");
      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."
    temporary_body = new BodyStreamBuffer(script_state, std::move(init.body));
    if (!init.content_type.IsEmpty() &&
        !r->getHeaders()->has(HTTPNames::Content_Type, exception_state)) {
      r->getHeaders()->append(HTTPNames::Content_Type, init.content_type,
                              exception_state);
    }
    if (exception_state.HadException())
      return nullptr;
  }

  // "Set |r|'s request's body to |temporaryBody|.
  if (temporary_body) {
    r->request_->SetBuffer(temporary_body);
    r->RefreshBody(script_state);
  }

  // "Set |r|'s MIME type to the result of extracting a MIME type from |r|'s
  // request's header list."
  r->request_->SetMIMEType(r->request_->HeaderList()->ExtractMIMEType());

  // "If |input| is a Request object and |input|'s request's body is
  // non-null, run these substeps:"
  if (input_request && input_request->BodyBuffer()) {
    // "Let |dummyStream| be an empty ReadableStream object."
    auto dummy_stream =
        new BodyStreamBuffer(script_state, BytesConsumer::CreateClosed());
    // "Set |input|'s request's body to a new body whose stream is
    // |dummyStream|."
    input_request->request_->SetBuffer(dummy_stream);
    input_request->RefreshBody(script_state);
    // "Let |reader| be the result of getting reader from |dummyStream|."
    // "Read all bytes from |dummyStream| with |reader|."
    input_request->BodyBuffer()->CloseAndLockAndDisturb();
  }

  // "Return |r|."
  return r;
}

Request* Request::Create(ScriptState* script_state,
                         const RequestInfo& input,
                         const Dictionary& init,
                         ExceptionState& exception_state) {
  DCHECK(!input.isNull());
  if (input.isUSVString())
    return Create(script_state, input.getAsUSVString(), init, exception_state);
  return Create(script_state, input.getAsRequest(), init, exception_state);
}

Request* Request::Create(ScriptState* script_state,
                         const String& input,
                         ExceptionState& exception_state) {
  return Create(script_state, input, Dictionary(), exception_state);
}

Request* Request::Create(ScriptState* script_state,
                         const String& input,
                         const Dictionary& init,
                         ExceptionState& exception_state) {
  RequestInit request_init(ExecutionContext::From(script_state), init,
                           exception_state);
  return CreateRequestWithRequestOrString(script_state, nullptr, input,
                                          request_init, exception_state);
}

Request* Request::Create(ScriptState* script_state,
                         Request* input,
                         ExceptionState& exception_state) {
  return Create(script_state, input, Dictionary(), exception_state);
}

Request* Request::Create(ScriptState* script_state,
                         Request* input,
                         const Dictionary& init,
                         ExceptionState& exception_state) {
  RequestInit request_init(ExecutionContext::From(script_state), init,
                           exception_state);
  return CreateRequestWithRequestOrString(script_state, input, String(),
                                          request_init, exception_state);
}

Request* Request::Create(ScriptState* script_state, FetchRequestData* request) {
  return new Request(script_state, request);
}

Request* Request::Create(ScriptState* script_state,
                         const WebServiceWorkerRequest& web_request) {
  FetchRequestData* request =
      FetchRequestData::Create(script_state, web_request);
  return new Request(script_state, request);
}

Request::Request(ScriptState* script_state,
                 FetchRequestData* request,
                 Headers* headers)
    : Body(ExecutionContext::From(script_state)),
      request_(request),
      headers_(headers) {
  RefreshBody(script_state);
}

Request::Request(ScriptState* script_state, FetchRequestData* request)
    : Request(script_state, request, Headers::Create(request->HeaderList())) {
  headers_->SetGuard(Headers::kRequestGuard);
}

String Request::method() const {
  // "The method attribute's getter must return request's method."
  return request_->Method();
}

KURL Request::url() const {
  return request_->Url();
}

String Request::Context() const {
  // "The context attribute's getter must return request's context"
  switch (request_->Context()) {
    case WebURLRequest::kRequestContextUnspecified:
      return "";
    case WebURLRequest::kRequestContextAudio:
      return "audio";
    case WebURLRequest::kRequestContextBeacon:
      return "beacon";
    case WebURLRequest::kRequestContextCSPReport:
      return "cspreport";
    case WebURLRequest::kRequestContextDownload:
      return "download";
    case WebURLRequest::kRequestContextEmbed:
      return "embed";
    case WebURLRequest::kRequestContextEventSource:
      return "eventsource";
    case WebURLRequest::kRequestContextFavicon:
      return "favicon";
    case WebURLRequest::kRequestContextFetch:
      return "fetch";
    case WebURLRequest::kRequestContextFont:
      return "font";
    case WebURLRequest::kRequestContextForm:
      return "form";
    case WebURLRequest::kRequestContextFrame:
      return "frame";
    case WebURLRequest::kRequestContextHyperlink:
      return "hyperlink";
    case WebURLRequest::kRequestContextIframe:
      return "iframe";
    case WebURLRequest::kRequestContextImage:
      return "image";
    case WebURLRequest::kRequestContextImageSet:
      return "imageset";
    case WebURLRequest::kRequestContextImport:
      return "import";
    case WebURLRequest::kRequestContextInternal:
      return "internal";
    case WebURLRequest::kRequestContextLocation:
      return "location";
    case WebURLRequest::kRequestContextManifest:
      return "manifest";
    case WebURLRequest::kRequestContextObject:
      return "object";
    case WebURLRequest::kRequestContextPing:
      return "ping";
    case WebURLRequest::kRequestContextPlugin:
      return "plugin";
    case WebURLRequest::kRequestContextPrefetch:
      return "prefetch";
    case WebURLRequest::kRequestContextScript:
      return "script";
    case WebURLRequest::kRequestContextServiceWorker:
      return "serviceworker";
    case WebURLRequest::kRequestContextSharedWorker:
      return "sharedworker";
    case WebURLRequest::kRequestContextSubresource:
      return "subresource";
    case WebURLRequest::kRequestContextStyle:
      return "style";
    case WebURLRequest::kRequestContextTrack:
      return "track";
    case WebURLRequest::kRequestContextVideo:
      return "video";
    case WebURLRequest::kRequestContextWorker:
      return "worker";
    case WebURLRequest::kRequestContextXMLHttpRequest:
      return "xmlhttprequest";
    case WebURLRequest::kRequestContextXSLT:
      return "xslt";
  }
  NOTREACHED();
  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."
  DCHECK_EQ(FetchRequestData::NoReferrerString(), AtomicString());
  DCHECK_EQ(FetchRequestData::ClientReferrerString(),
            AtomicString("about:client"));
  return request_->ReferrerString();
}

String Request::getReferrerPolicy() const {
  switch (request_->GetReferrerPolicy()) {
    case kReferrerPolicyAlways:
      return "unsafe-url";
    case kReferrerPolicyDefault:
      return "";
    case kReferrerPolicyNoReferrerWhenDowngrade:
      return "no-referrer-when-downgrade";
    case kReferrerPolicyNever:
      return "no-referrer";
    case kReferrerPolicyOrigin:
      return "origin";
    case kReferrerPolicyOriginWhenCrossOrigin:
      return "origin-when-cross-origin";
    case kReferrerPolicySameOrigin:
      return "same-origin";
    case kReferrerPolicyStrictOrigin:
      return "strict-origin";
    case kReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin:
      return "strict-origin-when-cross-origin";
  }
  NOTREACHED();
  return String();
}

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 (request_->Mode()) {
    case WebURLRequest::kFetchRequestModeSameOrigin:
      return "same-origin";
    case WebURLRequest::kFetchRequestModeNoCORS:
      return "no-cors";
    case WebURLRequest::kFetchRequestModeCORS:
    case WebURLRequest::kFetchRequestModeCORSWithForcedPreflight:
      return "cors";
    case WebURLRequest::kFetchRequestModeNavigate:
      return "navigate";
  }
  NOTREACHED();
  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 (request_->Credentials()) {
    case WebURLRequest::kFetchCredentialsModeOmit:
      return "omit";
    case WebURLRequest::kFetchCredentialsModeSameOrigin:
      return "same-origin";
    case WebURLRequest::kFetchCredentialsModeInclude:
      return "include";
    case WebURLRequest::kFetchCredentialsModePassword:
      return "password";
  }
  NOTREACHED();
  return "";
}

String Request::cache() const {
  // "The cache attribute's getter must return request's cache mode."
  switch (request_->CacheMode()) {
    case WebURLRequest::kFetchRequestCacheModeDefault:
      return "default";
    case WebURLRequest::kFetchRequestCacheModeNoStore:
      return "no-store";
    case WebURLRequest::kFetchRequestCacheModeReload:
      return "reload";
    case WebURLRequest::kFetchRequestCacheModeNoCache:
      return "no-cache";
    case WebURLRequest::kFetchRequestCacheModeForceCache:
      return "force-cache";
    case WebURLRequest::kFetchRequestCacheModeOnlyIfCached:
      return "only-if-cached";
  }
  NOTREACHED();
  return "";
}

String Request::redirect() const {
  // "The redirect attribute's getter must return request's redirect mode."
  switch (request_->Redirect()) {
    case WebURLRequest::kFetchRedirectModeFollow:
      return "follow";
    case WebURLRequest::kFetchRedirectModeError:
      return "error";
    case WebURLRequest::kFetchRedirectModeManual:
      return "manual";
  }
  NOTREACHED();
  return "";
}

String Request::integrity() const {
  return request_->Integrity();
}

Request* Request::clone(ScriptState* script_state,
                        ExceptionState& exception_state) {
  if (IsBodyLocked() || bodyUsed()) {
    exception_state.ThrowTypeError("Request body is already used");
    return nullptr;
  }

  FetchRequestData* request = request_->Clone(script_state);
  RefreshBody(script_state);
  Headers* headers = Headers::Create(request->HeaderList());
  headers->SetGuard(headers_->GetGuard());
  return new Request(script_state, request, headers);
}

FetchRequestData* Request::PassRequestData(ScriptState* script_state) {
  DCHECK(!bodyUsed());
  FetchRequestData* data = request_->Pass(script_state);
  RefreshBody(script_state);
  // |data|'s buffer('s js wrapper) has no retainer, but it's OK because
  // the only caller is the fetch function and it uses the body buffer
  // immediately.
  return data;
}

bool Request::HasBody() const {
  return BodyBuffer();
}

void Request::PopulateWebServiceWorkerRequest(
    WebServiceWorkerRequest& web_request) const {
  web_request.SetMethod(method());
  web_request.SetMode(request_->Mode());
  web_request.SetCredentialsMode(request_->Credentials());
  web_request.SetCacheMode(request_->CacheMode());
  web_request.SetRedirectMode(request_->Redirect());
  web_request.SetIntegrity(request_->Integrity());
  web_request.SetRequestContext(request_->Context());

  // Strip off the fragment part of URL. So far, all users of
  // WebServiceWorkerRequest expect the fragment to be excluded.
  KURL url(request_->Url());
  if (request_->Url().HasFragmentIdentifier())
    url.RemoveFragmentIdentifier();
  web_request.SetURL(url);

  const FetchHeaderList* header_list = headers_->HeaderList();
  for (const auto& header : header_list->List()) {
    web_request.AppendHeader(header.first, header.second);
  }

  web_request.SetReferrer(
      request_->ReferrerString(),
      static_cast<WebReferrerPolicy>(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 request_->MimeType();
}

String Request::ContentType() const {
  String result;
  request_->HeaderList()->Get(HTTPNames::Content_Type, result);
  return result;
}

void Request::RefreshBody(ScriptState* script_state) {
  v8::Local<v8::Value> request = ToV8(this, script_state);
  if (request.IsEmpty()) {
    // |toV8| can return an empty handle when the worker is terminating.
    // We don't want the renderer to crash in such cases.
    // TODO(yhirano): Delete this block after the graceful shutdown
    // mechanism is introduced.
    return;
  }
  DCHECK(request->IsObject());
  v8::Local<v8::Value> body_buffer = ToV8(this->BodyBuffer(), script_state);
  V8PrivateProperty::GetInternalBodyBuffer(script_state->GetIsolate())
      .Set(request.As<v8::Object>(), body_buffer);
}

DEFINE_TRACE(Request) {
  Body::Trace(visitor);
  visitor->Trace(request_);
  visitor->Trace(headers_);
}

}  // namespace blink
