// 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 "core/fetch/Request.h"

#include "bindings/core/v8/Dictionary.h"
#include "core/dom/ExecutionContext.h"
#include "core/fetch/BodyStreamBuffer.h"
#include "core/fetch/FetchManager.h"
#include "core/fetch/RequestInit.h"
#include "core/loader/ThreadableLoader.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/network/http_names.h"
#include "platform/runtime_enabled_features.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());
  // 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->SetRedirect(original->Redirect());
  request->SetIntegrity(original->Integrity());
  request->SetKeepalive(original->Keepalive());
  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."

  scoped_refptr<const 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."
  const KURL base_url = ExecutionContext::From(script_state)->BaseURL();

  // "If |input| is a string, run these substeps:"
  if (!input_request) {
    // "Let |parsedURL| be the result of parsing |input| with |baseURL|."
    KURL parsed_url = KURL(base_url, 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.AreAnyMembersSet()) {
    // "If |request|'s |mode| is "navigate", throw a TypeError."
    if (request->Mode() == network::mojom::FetchRequestMode::kNavigate) {
      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.AreAnyMembersSet()) {
    // Nothing to do for the step "Let |referrer| be |init|'s referrer
    // member."

    if (init.GetReferrer().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.GetReferrer().referrer);
      if (!parsed_referrer.IsValid()) {
        // "If |parsedReferrer| is failure, throw a TypeError."
        exception_state.ThrowTypeError("Referrer '" +
                                       init.GetReferrer().referrer +
                                       "' is not a valid URL.");
        return nullptr;
      }
      if ((parsed_referrer.ProtocolIsAbout() &&
           parsed_referrer.Host().IsEmpty() &&
           parsed_referrer.GetPath() == "client") ||
          !origin->IsSameSchemeHostPortAndSuborigin(
              SecurityOrigin::Create(parsed_referrer).get())) {
        // If |parsedReferrer|'s host is empty
        // it's cannot-be-a-base-URL flag must be set

        // "If one of the following conditions is true, then set
        // request’s referrer to "client":
        //
        //     |parsedReferrer|’s cannot-be-a-base-URL flag is set,
        //     scheme is "about", and path contains a single string "client".
        //
        //     parsedReferrer’s origin is not same origin with origin"
        //
        request->SetReferrerString(FetchRequestData::ClientReferrerString());
      } else {
        // "Set |request|'s referrer to |parsedReferrer|."
        request->SetReferrerString(AtomicString(parsed_referrer.GetString()));
      }
    }
    request->SetReferrerPolicy(init.GetReferrer().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(network::mojom::FetchRequestMode::kSameOrigin);
  } else if (init.Mode() == "no-cors") {
    request->SetMode(network::mojom::FetchRequestMode::kNoCORS);
  } else if (init.Mode() == "cors") {
    request->SetMode(network::mojom::FetchRequestMode::kCORS);
  } else {
    // |inputRequest| is directly checked here instead of setting and
    // checking |fallbackMode| as specified in the spec.
    if (!input_request)
      request->SetMode(network::mojom::FetchRequestMode::kCORS);
  }

  // "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|."

  network::mojom::FetchCredentialsMode credentials_mode;
  if (ParseCredentialsMode(init.Credentials(), &credentials_mode)) {
    request->SetCredentials(credentials_mode);
  } else if (!input_request) {
    request->SetCredentials(network::mojom::FetchCredentialsMode::kOmit);
  }

  // "If |init|'s cache member is present, set |request|'s cache mode to it."
  if (init.CacheMode() == "default") {
    request->SetCacheMode(mojom::FetchCacheMode::kDefault);
  } else if (init.CacheMode() == "no-store") {
    request->SetCacheMode(mojom::FetchCacheMode::kNoStore);
  } else if (init.CacheMode() == "reload") {
    request->SetCacheMode(mojom::FetchCacheMode::kBypassCache);
  } else if (init.CacheMode() == "no-cache") {
    request->SetCacheMode(mojom::FetchCacheMode::kValidateCache);
  } else if (init.CacheMode() == "force-cache") {
    request->SetCacheMode(mojom::FetchCacheMode::kForceCache);
  } else if (init.CacheMode() == "only-if-cached") {
    request->SetCacheMode(mojom::FetchCacheMode::kOnlyIfCached);
  }

  // If |request|’s cache mode is "only-if-cached" and |request|’s mode is not
  // "same-origin", then throw a TypeError.
  if (request->CacheMode() == mojom::FetchCacheMode::kOnlyIfCached &&
      request->Mode() != network::mojom::FetchRequestMode::kSameOrigin) {
    exception_state.ThrowTypeError(
        "'only-if-cached' can be set only with 'same-origin' mode");
    return nullptr;
  }

  // "If |init|'s redirect member is present, set |request|'s redirect mode
  // to it."
  if (init.Redirect() == "follow") {
    request->SetRedirect(network::mojom::FetchRedirectMode::kFollow);
  } else if (init.Redirect() == "error") {
    request->SetRedirect(network::mojom::FetchRedirectMode::kError);
  } 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.Keepalive().has_value())
    request->SetKeepalive(*init.Keepalive());

  // "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.GetHeaders().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() == network::mojom::FetchRequestMode::kNoCORS) {
    // "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;
    }
    // "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.GetHeaders().IsNull()) {
    r->getHeaders()->FillWith(init.GetHeaders(), 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.GetBody() || temporary_body) {
    if (request->Method() == HTTPNames::GET ||
        request->Method() == HTTPNames::HEAD) {
      exception_state.ThrowTypeError(
          "Request with GET/HEAD method cannot have body.");
      return nullptr;
    }
  }

  // "If |init|'s body member is present, run these substeps:"
  if (init.GetBody()) {
    // TODO(yhirano): Throw if keepalive flag is set and body is a
    // ReadableStream. We don't support body stream setting for Request yet.

    // 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.GetBody()));
    if (!init.ContentType().IsEmpty() &&
        !r->getHeaders()->has(HTTPNames::Content_Type, exception_state)) {
      r->getHeaders()->append(HTTPNames::Content_Type, init.ContentType(),
                              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);
}

bool Request::ParseCredentialsMode(
    const String& credentials_mode,
    network::mojom::FetchCredentialsMode* result) {
  if (credentials_mode == "omit") {
    *result = network::mojom::FetchCredentialsMode::kOmit;
    return true;
  }
  if (credentials_mode == "same-origin") {
    *result = network::mojom::FetchCredentialsMode::kSameOrigin;
    return true;
  }
  if (credentials_mode == "include") {
    *result = network::mojom::FetchCredentialsMode::kInclude;
    return true;
  }
  return false;
}

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::destination() const {
  // "The destination attribute’s getter must return request’s destination."
  switch (request_->Context()) {
    case WebURLRequest::kRequestContextUnspecified:
    case WebURLRequest::kRequestContextBeacon:
    case WebURLRequest::kRequestContextDownload:
    case WebURLRequest::kRequestContextEventSource:
    case WebURLRequest::kRequestContextFetch:
    case WebURLRequest::kRequestContextPing:
    case WebURLRequest::kRequestContextXMLHttpRequest:
    case WebURLRequest::kRequestContextSubresource:
      return "";
    case WebURLRequest::kRequestContextCSPReport:
      return "report";
    case WebURLRequest::kRequestContextAudio:
      return "audio";
    case WebURLRequest::kRequestContextEmbed:
      return "embed";
    case WebURLRequest::kRequestContextFont:
      return "font";
    case WebURLRequest::kRequestContextFrame:
    case WebURLRequest::kRequestContextHyperlink:
    case WebURLRequest::kRequestContextIframe:
    case WebURLRequest::kRequestContextLocation:
    case WebURLRequest::kRequestContextForm:
      return "document";
    case WebURLRequest::kRequestContextImage:
    case WebURLRequest::kRequestContextFavicon:
    case WebURLRequest::kRequestContextImageSet:
      return "image";
    case WebURLRequest::kRequestContextManifest:
      return "manifest";
    case WebURLRequest::kRequestContextObject:
      return "object";
    case WebURLRequest::kRequestContextScript:
      return "script";
    case WebURLRequest::kRequestContextSharedWorker:
      return "sharedworker";
    case WebURLRequest::kRequestContextStyle:
      return "style";
    case WebURLRequest::kRequestContextTrack:
      return "track";
    case WebURLRequest::kRequestContextVideo:
      return "video";
    case WebURLRequest::kRequestContextWorker:
      return "worker";
    case WebURLRequest::kRequestContextXSLT:
      return "xslt";
    case WebURLRequest::kRequestContextImport:
    case WebURLRequest::kRequestContextInternal:
    case WebURLRequest::kRequestContextPlugin:
    case WebURLRequest::kRequestContextPrefetch:
    case WebURLRequest::kRequestContextServiceWorker:
      return "unknown";
  }
  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 network::mojom::FetchRequestMode::kSameOrigin:
      return "same-origin";
    case network::mojom::FetchRequestMode::kNoCORS:
      return "no-cors";
    case network::mojom::FetchRequestMode::kCORS:
    case network::mojom::FetchRequestMode::kCORSWithForcedPreflight:
      return "cors";
    case network::mojom::FetchRequestMode::kNavigate:
      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 network::mojom::FetchCredentialsMode::kOmit:
      return "omit";
    case network::mojom::FetchCredentialsMode::kSameOrigin:
      return "same-origin";
    case network::mojom::FetchCredentialsMode::kInclude:
      return "include";
  }
  NOTREACHED();
  return "";
}

String Request::cache() const {
  // "The cache attribute's getter must return request's cache mode."
  switch (request_->CacheMode()) {
    case mojom::FetchCacheMode::kDefault:
      return "default";
    case mojom::FetchCacheMode::kNoStore:
      return "no-store";
    case mojom::FetchCacheMode::kBypassCache:
      return "reload";
    case mojom::FetchCacheMode::kValidateCache:
      return "no-cache";
    case mojom::FetchCacheMode::kForceCache:
      return "force-cache";
    case mojom::FetchCacheMode::kOnlyIfCached:
      return "only-if-cached";
    case mojom::FetchCacheMode::kUnspecifiedOnlyIfCachedStrict:
    case mojom::FetchCacheMode::kUnspecifiedForceCacheMiss:
      NOTREACHED();
      break;
  }
  NOTREACHED();
  return "";
}

String Request::redirect() const {
  // "The redirect attribute's getter must return request's redirect mode."
  switch (request_->Redirect()) {
    case network::mojom::FetchRedirectMode::kFollow:
      return "follow";
    case network::mojom::FetchRedirectMode::kError:
      return "error";
    case network::mojom::FetchRedirectMode::kManual:
      return "manual";
  }
  NOTREACHED();
  return "";
}

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

bool Request::keepalive() const {
  return request_->Keepalive();
}

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);
}

void Request::Trace(blink::Visitor* visitor) {
  Body::Trace(visitor);
  visitor->Trace(request_);
  visitor->Trace(headers_);
}

}  // namespace blink
