OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "Request.h" | 6 #include "Request.h" |
7 | 7 |
8 #include "bindings/core/v8/Dictionary.h" | 8 #include "bindings/core/v8/Dictionary.h" |
9 #include "core/dom/DOMURLUtilsReadOnly.h" | 9 #include "core/dom/ExecutionContext.h" |
| 10 #include "core/fetch/CrossOriginAccessControl.h" |
| 11 #include "core/fetch/ResourceLoaderOptions.h" |
| 12 #include "core/loader/ThreadableLoader.h" |
| 13 #include "core/xml/XMLHttpRequest.h" |
| 14 #include "modules/serviceworkers/FetchManager.h" |
10 #include "modules/serviceworkers/RequestInit.h" | 15 #include "modules/serviceworkers/RequestInit.h" |
11 #include "platform/NotImplemented.h" | 16 #include "platform/NotImplemented.h" |
| 17 #include "platform/network/HTTPParsers.h" |
12 #include "platform/network/ResourceRequest.h" | 18 #include "platform/network/ResourceRequest.h" |
| 19 #include "platform/weborigin/Referrer.h" |
13 #include "public/platform/WebServiceWorkerRequest.h" | 20 #include "public/platform/WebServiceWorkerRequest.h" |
14 | 21 |
15 namespace WebCore { | 22 namespace WebCore { |
16 | 23 |
17 PassRefPtr<Request> Request::create() | 24 namespace { |
| 25 |
| 26 PassRefPtr<Request> createRequestWithRequestData(PassRefPtr<FetchRequestData> re
quest, const RequestInit& init, FetchRequestData::Mode mode, FetchRequestData::C
redentials credentials, ExceptionState& exceptionState) |
18 { | 27 { |
19 return create(Dictionary()); | 28 // "6. Let |mode| be |init|'s mode member if it is present, and |
| 29 // |fallbackMode| otherwise." |
| 30 // "7. If |mode| is non-null, set |request|'s mode to |mode|." |
| 31 if (init.mode == "same-origin") { |
| 32 request->setMode(FetchRequestData::SameOriginMode); |
| 33 } else if (init.mode == "no-cors") { |
| 34 request->setMode(mode = FetchRequestData::NoCORSMode); |
| 35 } else if (init.mode == "cors") { |
| 36 request->setMode(FetchRequestData::CORSMode); |
| 37 } else { |
| 38 // We use the current mode instead of null, so we just set here. |
| 39 request->setMode(mode); |
| 40 } |
| 41 |
| 42 // "8. Let |credentials| be |init|'s credentials member if it is present, |
| 43 // and |fallbackCredentials| otherwise." |
| 44 // "9. If |credentials| is non-null, set |request|'s credentials mode to |
| 45 // |credentials|. |
| 46 if (init.credentials == "omit") { |
| 47 request->setCredentials(FetchRequestData::OmitCredentials); |
| 48 } else if (init.credentials == "same-origin") { |
| 49 request->setCredentials(FetchRequestData::SameOriginCredentials); |
| 50 } else if (init.credentials == "include") { |
| 51 request->setCredentials(FetchRequestData::IncludeCredentials); |
| 52 } else { |
| 53 // We use the current mode instead of null, so we just set here. |
| 54 request->setCredentials(credentials); |
| 55 } |
| 56 |
| 57 // "10. If |init|'s method member is present, let |method| be it and run |
| 58 // these substeps:" |
| 59 if (!init.method.isEmpty()) { |
| 60 // "1. If |method| is not a useful method, throw a TypeError." |
| 61 if (!FetchManager::isUsefulMethod(init.method)) { |
| 62 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); |
| 63 return nullptr; |
| 64 } |
| 65 if (!isValidHTTPToken(init.method)) { |
| 66 exceptionState.throwTypeError("'" + init.method + "' is not a valid
HTTP method."); |
| 67 return nullptr; |
| 68 } |
| 69 // FIXME: "2. Add case correction as in XMLHttpRequest?" |
| 70 // "3. Set |request|'s method to |method|." |
| 71 request->setMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(AtomicString
(init.method))); |
| 72 } |
| 73 // "11. Let |r| be a new Request object associated with |request|, Headers |
| 74 // object, and FetchBodyStream object." |
| 75 RefPtr<Request> r = Request::create(request); |
| 76 // "12. If |r|'s request's mode is no CORS, run these substeps: |
| 77 if (r->request()->mode() == FetchRequestData::NoCORSMode) { |
| 78 // "1. If |r|'s request's method is not a simple method, throw a |
| 79 // TypeError." |
| 80 if (!FetchManager::isSimpleMethod(r->request()->method())) { |
| 81 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); |
| 82 return nullptr; |
| 83 } |
| 84 // "Set |r|'s Headers object's guard to |request-no-CORS|. |
| 85 r->headers()->setGuard(Headers::RequestNoCORSGuard); |
| 86 } |
| 87 |
| 88 // "13. If |init|'s headers member is present, run these substeps:" |
| 89 if (init.headers) { |
| 90 ASSERT(init.headersDictionary.isUndefinedOrNull()); |
| 91 // "1. Empty |r|'s request's header list." |
| 92 r->request()->headerList()->clearList(); |
| 93 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow |
| 94 // any exceptions." |
| 95 r->headers()->fillWith(init.headers.get(), exceptionState); |
| 96 if (exceptionState.hadException()) |
| 97 return nullptr; |
| 98 } else if (!init.headersDictionary.isUndefinedOrNull()) { |
| 99 // "1. Empty |r|'s request's header list." |
| 100 r->request()->headerList()->clearList(); |
| 101 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow |
| 102 // any exceptions." |
| 103 r->headers()->fillWith(init.headersDictionary, exceptionState); |
| 104 if (exceptionState.hadException()) |
| 105 return nullptr; |
| 106 } |
| 107 // FIXME: Support body. |
| 108 // "17. Return |r|." |
| 109 return r.release(); |
20 } | 110 } |
21 | 111 |
22 PassRefPtr<Request> Request::create(const Dictionary& requestInit) | 112 |
| 113 } // namespace |
| 114 |
| 115 PassRefPtr<Request> Request::create(ExecutionContext* context, const String& inp
ut, ExceptionState& exceptionState) |
23 { | 116 { |
24 return adoptRef(new Request(RequestInit(requestInit))); | 117 return create(context, input, Dictionary(), exceptionState); |
| 118 } |
| 119 |
| 120 PassRefPtr<Request> Request::create(ExecutionContext* context, const String& inp
ut, const Dictionary& init, ExceptionState& exceptionState) |
| 121 { |
| 122 // "1. Let |request| be |input|'s associated request, if |input| is a |
| 123 // Request object, and a new request otherwise." |
| 124 RefPtr<FetchRequestData> request(FetchRequestData::create(context)); |
| 125 // "2. Set |request| to a restricted copy of itself." |
| 126 request = request->createRestrictedCopy(context, SecurityOrigin::create(cont
ext->url())); |
| 127 // "5. If |input| is a string, run these substeps:" |
| 128 // "1. Let |parsedURL| be the result of parsing |input| with entry settings |
| 129 // object's API base URL." |
| 130 KURL parsedURL = context->completeURL(input); |
| 131 // "2. If |parsedURL| is failure, throw a TypeError." |
| 132 if (!parsedURL.isValid()) { |
| 133 exceptionState.throwTypeError("Invalid URL"); |
| 134 return nullptr; |
| 135 } |
| 136 // "3. Set |request|'s url to |parsedURL|." |
| 137 request->setURL(parsedURL); |
| 138 // "4. Set |fallbackMode| to CORS." |
| 139 // "5. Set |fallbackCredentials| to omit." |
| 140 return createRequestWithRequestData(request.release(), RequestInit(init), Fe
tchRequestData::CORSMode, FetchRequestData::OmitCredentials, exceptionState); |
| 141 } |
| 142 |
| 143 |
| 144 PassRefPtr<Request> Request::create(ExecutionContext* context, Request* input, E
xceptionState& exceptionState) |
| 145 { |
| 146 return create(context, input, Dictionary(), exceptionState); |
| 147 } |
| 148 |
| 149 PassRefPtr<Request> Request::create(ExecutionContext* context, Request* input, c
onst Dictionary& init, ExceptionState& exceptionState) |
| 150 { |
| 151 // "1. Let |request| be |input|'s associated request, if |input| is a |
| 152 // Request object, and a new request otherwise." |
| 153 // "2. Set |request| to a restricted copy of itself." |
| 154 RefPtr<FetchRequestData> request(input->request()->createRestrictedCopy(cont
ext, SecurityOrigin::create(context->url()))); |
| 155 // "3. Let |fallbackMode| be null." |
| 156 // "4. Let |fallbackCredentials| be null." |
| 157 // We use the current mode and the current credentials instead of null for |
| 158 // |fallbackMode| and |fallbackCredentials|. |
| 159 const FetchRequestData::Mode currentMode = request->mode(); |
| 160 const FetchRequestData::Credentials currentCredentials = request->credential
s(); |
| 161 return createRequestWithRequestData(request.release(), RequestInit(init), cu
rrentMode, currentCredentials, exceptionState); |
| 162 } |
| 163 |
| 164 PassRefPtr<Request> Request::create(PassRefPtr<FetchRequestData> request) |
| 165 { |
| 166 return adoptRef(new Request(request)); |
| 167 } |
| 168 |
| 169 Request::Request(PassRefPtr<FetchRequestData> request) |
| 170 : m_request(request) |
| 171 , m_headers(Headers::create(m_request->headerList())) |
| 172 { |
| 173 m_headers->setGuard(Headers::RequestGuard); |
| 174 ScriptWrappable::init(this); |
25 } | 175 } |
26 | 176 |
27 PassRefPtr<Request> Request::create(const blink::WebServiceWorkerRequest& webReq
uest) | 177 PassRefPtr<Request> Request::create(const blink::WebServiceWorkerRequest& webReq
uest) |
28 { | 178 { |
29 return adoptRef(new Request(webRequest)); | 179 return adoptRef(new Request(webRequest)); |
30 } | 180 } |
31 | 181 |
32 void Request::setURL(const String& value) | 182 Request::Request(const blink::WebServiceWorkerRequest& webRequest) |
| 183 : m_request(FetchRequestData::create(webRequest)) |
| 184 , m_headers(Headers::create(m_request->headerList())) |
33 { | 185 { |
34 m_url = KURL(ParsedURLString, value); | 186 m_headers->setGuard(Headers::RequestGuard); |
| 187 ScriptWrappable::init(this); |
35 } | 188 } |
36 | 189 |
37 void Request::setMethod(const String& value) | 190 String Request::method() const |
38 { | 191 { |
39 m_method = value; | 192 // "The method attribute's getter must return request's method." |
| 193 return m_request->method(); |
40 } | 194 } |
41 | 195 |
42 String Request::origin() const | 196 String Request::url() const |
43 { | 197 { |
44 return DOMURLUtilsReadOnly::origin(m_url); | 198 // The url attribute's getter must return request's url, serialized with the
exclude fragment flag set. |
| 199 if (!m_request->url().hasFragmentIdentifier()) |
| 200 return m_request->url(); |
| 201 KURL url(m_request->url()); |
| 202 url.removeFragmentIdentifier(); |
| 203 return url; |
| 204 } |
| 205 |
| 206 String Request::referrer() const |
| 207 { |
| 208 // "The referrer attribute's getter must return the empty string if |
| 209 // request's referrer is none, and request's referrer, serialized, |
| 210 // otherwise." |
| 211 return m_request->referrer().getUrl(); |
| 212 } |
| 213 |
| 214 String Request::mode() const |
| 215 { |
| 216 // "The mode attribute's getter must return the value corresponding to the |
| 217 // first matching statement, switching on request's mode:" |
| 218 switch (m_request->mode()) { |
| 219 case FetchRequestData::SameOriginMode: |
| 220 return "same-origin"; |
| 221 case FetchRequestData::NoCORSMode: |
| 222 return "no-cors"; |
| 223 case FetchRequestData::CORSMode: |
| 224 case FetchRequestData::CORSWithForcedPreflight: |
| 225 return "cors"; |
| 226 } |
| 227 ASSERT_NOT_REACHED(); |
| 228 return ""; |
| 229 } |
| 230 |
| 231 String Request::credentials() const |
| 232 { |
| 233 // "The credentials attribute's getter must return the value corresponding |
| 234 // to the first matching statement, switching on request's credentials |
| 235 // mode:" |
| 236 switch (m_request->credentials()) { |
| 237 case FetchRequestData::OmitCredentials: |
| 238 return "omit"; |
| 239 case FetchRequestData::SameOriginCredentials: |
| 240 return "same-origin"; |
| 241 case FetchRequestData::IncludeCredentials: |
| 242 return "include"; |
| 243 } |
| 244 ASSERT_NOT_REACHED(); |
| 245 return ""; |
45 } | 246 } |
46 | 247 |
47 PassOwnPtr<ResourceRequest> Request::createResourceRequest() const | 248 PassOwnPtr<ResourceRequest> Request::createResourceRequest() const |
48 { | 249 { |
49 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest(m_url)); | 250 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest(url())); |
50 request->setHTTPMethod("GET"); | 251 request->setHTTPMethod("GET"); |
51 // FIXME: Fill more info. | 252 // FIXME: Fill more info. |
52 return request.release(); | 253 return request.release(); |
53 } | 254 } |
54 | 255 |
55 Request::Request(const RequestInit& requestInit) | |
56 : m_url(KURL(ParsedURLString, requestInit.url)) | |
57 , m_method(requestInit.method) | |
58 , m_headers(requestInit.headers) | |
59 { | |
60 ScriptWrappable::init(this); | |
61 | |
62 if (!m_headers) | |
63 m_headers = HeaderMap::create(); | |
64 } | |
65 | |
66 Request::Request(const blink::WebServiceWorkerRequest& webRequest) | |
67 : m_url(webRequest.url()) | |
68 , m_method(webRequest.method()) | |
69 , m_headers(HeaderMap::create(webRequest.headers())) | |
70 { | |
71 ScriptWrappable::init(this); | |
72 } | |
73 | |
74 } // namespace WebCore | 256 } // namespace WebCore |
OLD | NEW |