1f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// found in the LICENSE file.
4f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
5f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "config.h"
6f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "Request.h"
7f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
8197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/Dictionary.h"
9197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/ExecutionContext.h"
10c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/fetch/FetchUtils.h"
11197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/fetch/ResourceLoaderOptions.h"
12197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/loader/ThreadableLoader.h"
13197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/xml/XMLHttpRequest.h"
14197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "modules/serviceworkers/FetchManager.h"
157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "modules/serviceworkers/HeadersForEachCallback.h"
16f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "modules/serviceworkers/RequestInit.h"
17f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "platform/NotImplemented.h"
18197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/network/HTTPParsers.h"
195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "platform/network/ResourceRequest.h"
20197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/weborigin/Referrer.h"
21f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "public/platform/WebServiceWorkerRequest.h"
22f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
23c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
24f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
25197021e6b966cfb06891637935ef33fff06433d1Ben Murdochnamespace {
26f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass FillWebRequestHeaders : public HeadersForEachCallback {
287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic:
297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FillWebRequestHeaders(WebServiceWorkerRequest* webRequest) : m_webRequest(webRequest) { }
307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual bool handleItem(ScriptValue, const String&, const String&, Headers*)
327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT_NOT_REACHED();
347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return false;
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual bool handleItem(const String& value, const String& key, Headers*)
387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_webRequest->appendHeader(key, value);
407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return true;
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate:
447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WebServiceWorkerRequest* m_webRequest;
457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // namespace
487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::createRequestWithRequestData(ExecutionContext* context, FetchRequestData* request, const RequestInit& init, FetchRequestData::Mode mode, FetchRequestData::Credentials credentials, ExceptionState& exceptionState)
50f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "7. Let |mode| be |init|'s mode member if it is present, and
52197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // |fallbackMode| otherwise."
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "8. If |mode| is non-null, set |request|'s mode to |mode|."
54197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (init.mode == "same-origin") {
55197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setMode(FetchRequestData::SameOriginMode);
56197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else if (init.mode == "no-cors") {
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setMode(mode = FetchRequestData::NoCORSMode);
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else if (init.mode == "cors") {
59197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setMode(FetchRequestData::CORSMode);
60197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else {
61197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Instead of using null as a special fallback value, we pass the
62197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // current mode in Request::create(). So we just set here.
63197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setMode(mode);
64197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "9. Let |credentials| be |init|'s credentials member if it is present,
67197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // and |fallbackCredentials| otherwise."
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "10. If |credentials| is non-null, set |request|'s credentials mode to
69197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // |credentials|.
70197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (init.credentials == "omit") {
71197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setCredentials(FetchRequestData::OmitCredentials);
72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else if (init.credentials == "same-origin") {
73197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setCredentials(FetchRequestData::SameOriginCredentials);
74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else if (init.credentials == "include") {
75197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setCredentials(FetchRequestData::IncludeCredentials);
76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else {
77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Instead of using null as a special fallback value, we pass the
78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // current credentials in Request::create(). So we just set here.
79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setCredentials(credentials);
80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "11. If |init|'s method member is present, let |method| be it and run
83197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // these substeps:"
84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!init.method.isEmpty()) {
85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // "1. If |method| is not a useful method, throw a TypeError."
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (!FetchUtils::isUsefulMethod(init.method)) {
87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            exceptionState.throwTypeError("'" + init.method + "' HTTP method is unsupported.");
887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
89197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
90197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!isValidHTTPToken(init.method)) {
91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            exceptionState.throwTypeError("'" + init.method + "' is not a valid HTTP method.");
927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
93197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // FIXME: "2. Add case correction as in XMLHttpRequest?"
95197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // "3. Set |request|'s method to |method|."
96197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        request->setMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(AtomicString(init.method)));
97197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "12. Let |r| be a new Request object associated with |request|, Headers
997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // object."
1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Request* r = Request::create(context, request);
101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "13. Let |headers| be a copy of |r|'s Headers object."
1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "14. If |init|'s headers member is present, set |headers| to |init|'s
104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // headers member."
105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // We don't create a copy of r's Headers object when init's headers member
106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // is present.
1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Headers* headers = 0;
108197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!init.headers && init.headersDictionary.isUndefinedOrNull()) {
109197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        headers = r->headers()->createCopy();
110197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "15. Empty |r|'s request's header list."
1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    r->clearHeaderList();
113197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "16. If |r|'s request's mode is no CORS, run these substeps:
115197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (r->request()->mode() == FetchRequestData::NoCORSMode) {
116197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // "1. If |r|'s request's method is not a simple method, throw a
117197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // TypeError."
118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (!FetchUtils::isSimpleMethod(r->request()->method())) {
119197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            exceptionState.throwTypeError("'" + r->request()->method() + "' is unsupported in no-cors mode.");
1207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
122197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // "Set |r|'s Headers object's guard to |request-no-CORS|.
123197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        r->headers()->setGuard(Headers::RequestNoCORSGuard);
124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
125197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "17. Fill |r|'s Headers object with |headers|. Rethrow any exceptions."
127197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (init.headers) {
128197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ASSERT(init.headersDictionary.isUndefinedOrNull());
129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        r->headers()->fillWith(init.headers.get(), exceptionState);
130197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else if (!init.headersDictionary.isUndefinedOrNull()) {
131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        r->headers()->fillWith(init.headersDictionary, exceptionState);
132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else {
133197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ASSERT(headers);
1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        r->headers()->fillWith(headers, exceptionState);
135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (exceptionState.hadException())
1377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
1387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "18. If |init|'s body member is present, run these substeps:"
1397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (init.bodyBlobHandle) {
1407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // "1. Let |stream| and |Content-Type| be the result of extracting
1417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // |init|'s body member."
1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // "2. Set |r|'s request's body to |stream|."
1437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // "3.If |Content-Type| is non-null and |r|'s request's header list
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //  contains no header named `Content-Type`, append
1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any
1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // exception."
1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        r->setBodyBlobHandle(init.bodyBlobHandle);
1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Content-Type", exceptionState)) {
1497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            r->headers()->append("Content-Type", init.bodyBlobHandle->type(), exceptionState);
1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (exceptionState.hadException())
1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "19. Set |r|'s MIME type to the result of extracting a MIME type from
1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // |r|'s request's header list."
1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // FIXME: We don't have MIME type in Request object yet.
1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "20. Return |r|."
1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return r;
160f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
161f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::create(ExecutionContext* context, const String& input, ExceptionState& exceptionState)
163f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
164197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return create(context, input, Dictionary(), exceptionState);
165f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
166f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::create(ExecutionContext* context, const String& input, const Dictionary& init, ExceptionState& exceptionState)
168f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "2. Let |request| be |input|'s associated request, if |input| is a
170197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Request object, and a new request otherwise."
1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FetchRequestData* request(FetchRequestData::create(context));
1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "3. Set |request| to a restricted copy of itself."
173197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    request = request->createRestrictedCopy(context, SecurityOrigin::create(context->url()));
1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "6. If |input| is a string, run these substeps:"
175197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "1. Let |parsedURL| be the result of parsing |input| with entry settings
176197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // object's API base URL."
177197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    KURL parsedURL = context->completeURL(input);
178197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "2. If |parsedURL| is failure, throw a TypeError."
179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!parsedURL.isValid()) {
180197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        exceptionState.throwTypeError("Invalid URL");
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
183197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "3. Set |request|'s url to |parsedURL|."
184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    request->setURL(parsedURL);
185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "4. Set |fallbackMode| to CORS."
186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "5. Set |fallbackCredentials| to omit."
1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return createRequestWithRequestData(context, request, RequestInit(context, init, exceptionState), FetchRequestData::CORSMode, FetchRequestData::OmitCredentials, exceptionState);
188f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
189f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::create(ExecutionContext* context, Request* input, ExceptionState& exceptionState)
191f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
192197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return create(context, input, Dictionary(), exceptionState);
193f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
194f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
1957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::create(ExecutionContext* context, Request* input, const Dictionary& init, ExceptionState& exceptionState)
196f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
1977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "1. If input is a Request object, run these substeps:"
1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "  1. If input's used flag is set, throw a TypeError."
1997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "  2. Set input's used flag."
2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (input->bodyUsed()) {
2017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        exceptionState.throwTypeError(
2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            "Cannot construct a Request with a Request object that has already been used.");
2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    input->setBodyUsed();
2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "2. Let |request| be |input|'s associated request, if |input| is a
207197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Request object, and a new request otherwise."
2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "3. Set |request| to a restricted copy of itself."
2097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FetchRequestData* request(input->request()->createRestrictedCopy(context, SecurityOrigin::create(context->url())));
2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "4. Let |fallbackMode| be null."
2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // "5. Let |fallbackCredentials| be null."
212197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Instead of using null as a special fallback value, just pass the current
213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // mode and credentials; it has the same effect.
214197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const FetchRequestData::Mode currentMode = request->mode();
215197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const FetchRequestData::Credentials currentCredentials = request->credentials();
2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return createRequestWithRequestData(context, request, RequestInit(context, init, exceptionState), currentMode, currentCredentials, exceptionState);
217f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
218f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::create(ExecutionContext* context, FetchRequestData* request)
2205d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){
2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Request* r = new Request(context, request);
2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    r->suspendIfNeeded();
2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return r;
2245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}
2255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
2267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest::Request(ExecutionContext* context, FetchRequestData* request)
2277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    : Body(context)
2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    , m_request(request)
229197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    , m_headers(Headers::create(m_request->headerList()))
230f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
231197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_headers->setGuard(Headers::RequestGuard);
232197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
233f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::create(ExecutionContext* context, const WebServiceWorkerRequest& webRequest)
235197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Request* r = new Request(context, webRequest);
2377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    r->suspendIfNeeded();
2387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return r;
239f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
240f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::create(const Request& copyFrom)
2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
2437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Request* r = new Request(copyFrom);
2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    r->suspendIfNeeded();
2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return r;
2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRequest)
2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    : Body(context)
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    , m_request(FetchRequestData::create(webRequest))
251197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    , m_headers(Headers::create(m_request->headerList()))
252f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
253197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_headers->setGuard(Headers::RequestGuard);
254f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
255f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
2567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest::Request(const Request& copy_from)
2577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    : Body(copy_from)
2587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    , m_request(copy_from.m_request)
2597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    , m_headers(copy_from.m_headers->createCopy())
2607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
2617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
2627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
264197021e6b966cfb06891637935ef33fff06433d1Ben MurdochString Request::method() const
265197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
266197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "The method attribute's getter must return request's method."
267197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return m_request->method();
268197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
269197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
270197021e6b966cfb06891637935ef33fff06433d1Ben MurdochString Request::url() const
271197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
272197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // The url attribute's getter must return request's url, serialized with the exclude fragment flag set.
273197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!m_request->url().hasFragmentIdentifier())
274197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return m_request->url();
275197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    KURL url(m_request->url());
276197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    url.removeFragmentIdentifier();
277197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return url;
278197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
279197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
280197021e6b966cfb06891637935ef33fff06433d1Ben MurdochString Request::referrer() const
281197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
282197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "The referrer attribute's getter must return the empty string if
283197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // request's referrer is none, and request's referrer, serialized,
284197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // otherwise."
285197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return m_request->referrer().referrer().referrer;
286197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
287197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
288197021e6b966cfb06891637935ef33fff06433d1Ben MurdochString Request::mode() const
289197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
290197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "The mode attribute's getter must return the value corresponding to the
291197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // first matching statement, switching on request's mode:"
292197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    switch (m_request->mode()) {
293197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case FetchRequestData::SameOriginMode:
294197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return "same-origin";
295197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case FetchRequestData::NoCORSMode:
296197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return "no-cors";
297197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case FetchRequestData::CORSMode:
298197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case FetchRequestData::CORSWithForcedPreflight:
299197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return "cors";
300197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
301197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT_NOT_REACHED();
302197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return "";
303197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
304197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
305197021e6b966cfb06891637935ef33fff06433d1Ben MurdochString Request::credentials() const
306197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
307197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // "The credentials attribute's getter must return the value corresponding
308197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // to the first matching statement, switching on request's credentials
309197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // mode:"
310197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    switch (m_request->credentials()) {
311197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case FetchRequestData::OmitCredentials:
312197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return "omit";
313197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case FetchRequestData::SameOriginCredentials:
314197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return "same-origin";
315197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case FetchRequestData::IncludeCredentials:
316197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return "include";
317197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
318197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT_NOT_REACHED();
319197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return "";
320197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
321197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
3227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRequest* Request::clone() const
3237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return Request::create(*this);
3257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webRequest)
3287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    webRequest.setMethod(method());
3307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    webRequest.setURL(m_request->url());
3317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_headers->forEach(new FillWebRequestHeaders(&webRequest));
3327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    webRequest.setReferrer(m_request->referrer().referrer().referrer, static_cast<WebReferrerPolicy>(m_request->referrer().referrer().referrerPolicy));
3337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // 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
3347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // to plumb this information in to here.
3357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Request::setBodyBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle)
3387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_request->setBlobDataHandle(blobDataHandle);
3407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Request::clearHeaderList()
3437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_request->headerList()->clearList();
3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciPassRefPtr<BlobDataHandle> Request::blobDataHandle()
3487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return m_request->blobDataHandle();
3507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
352197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid Request::trace(Visitor* visitor)
353197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
3547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Body::trace(visitor);
355197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    visitor->trace(m_request);
356197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    visitor->trace(m_headers);
357197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
358197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
359c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
360