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 "modules/fetch/Request.h" | 5 #include "modules/fetch/Request.h" |
6 | 6 |
7 #include "bindings/core/v8/Dictionary.h" | 7 #include "bindings/core/v8/Dictionary.h" |
8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
9 #include "core/dom/ExecutionContext.h" | 9 #include "core/dom/ExecutionContext.h" |
10 #include "core/fetch/FetchUtils.h" | 10 #include "core/fetch/FetchUtils.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 FetchRequestData* request = FetchRequestData::create(); | 29 FetchRequestData* request = FetchRequestData::create(); |
30 request->setURL(original->url()); | 30 request->setURL(original->url()); |
31 request->setMethod(original->method()); | 31 request->setMethod(original->method()); |
32 request->setHeaderList(original->headerList()->clone()); | 32 request->setHeaderList(original->headerList()->clone()); |
33 request->setUnsafeRequestFlag(true); | 33 request->setUnsafeRequestFlag(true); |
34 // FIXME: Set client. | 34 // FIXME: Set client. |
35 DOMWrapperWorld& world = scriptState->world(); | 35 DOMWrapperWorld& world = scriptState->world(); |
36 if (world.isIsolatedWorld()) | 36 if (world.isIsolatedWorld()) |
37 request->setOrigin(world.isolatedWorldSecurityOrigin()); | 37 request->setOrigin(world.isolatedWorldSecurityOrigin()); |
38 else | 38 else |
39 request->setOrigin(scriptState->executionContext()->securityOrigin()); | 39 request->setOrigin(scriptState->getExecutionContext()->getSecurityOrigin
()); |
40 // FIXME: Set ForceOriginHeaderFlag. | 40 // FIXME: Set ForceOriginHeaderFlag. |
41 request->setSameOriginDataURLFlag(true); | 41 request->setSameOriginDataURLFlag(true); |
42 request->setReferrer(original->referrer()); | 42 request->setReferrer(original->referrer()); |
43 request->setMode(original->mode()); | 43 request->setMode(original->mode()); |
44 request->setCredentials(original->credentials()); | 44 request->setCredentials(original->credentials()); |
45 request->setRedirect(original->redirect()); | 45 request->setRedirect(original->redirect()); |
46 request->setIntegrity(original->integrity()); | 46 request->setIntegrity(original->integrity()); |
47 // FIXME: Set cache mode. | 47 // FIXME: Set cache mode. |
48 // TODO(yhirano): Set redirect mode. | 48 // TODO(yhirano): Set redirect mode. |
49 return request; | 49 return request; |
50 } | 50 } |
51 | 51 |
52 Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req
uest* inputRequest, const String& inputString, RequestInit& init, ExceptionState
& exceptionState) | 52 Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req
uest* inputRequest, const String& inputString, RequestInit& init, ExceptionState
& exceptionState) |
53 { | 53 { |
54 // - "If |input| is a Request object and it is disturbed, throw a | 54 // - "If |input| is a Request object and it is disturbed, throw a |
55 // TypeError." | 55 // TypeError." |
56 if (inputRequest && inputRequest->bodyUsed()) { | 56 if (inputRequest && inputRequest->bodyUsed()) { |
57 exceptionState.throwTypeError("Cannot construct a Request with a Request
object that has already been used."); | 57 exceptionState.throwTypeError("Cannot construct a Request with a Request
object that has already been used."); |
58 return nullptr; | 58 return nullptr; |
59 } | 59 } |
60 // - "Let |temporaryBody| be |input|'s request's body if |input| is a | 60 // - "Let |temporaryBody| be |input|'s request's body if |input| is a |
61 // Request object, and null otherwise." | 61 // Request object, and null otherwise." |
62 BodyStreamBuffer* temporaryBody = inputRequest ? inputRequest->bodyBuffer()
: nullptr; | 62 BodyStreamBuffer* temporaryBody = inputRequest ? inputRequest->bodyBuffer()
: nullptr; |
63 | 63 |
64 // "Let |request| be |input|'s request, if |input| is a Request object, | 64 // "Let |request| be |input|'s request, if |input| is a Request object, |
65 // and a new request otherwise." | 65 // and a new request otherwise." |
66 | 66 |
67 RefPtr<SecurityOrigin> origin = scriptState->executionContext()->securityOri
gin(); | 67 RefPtr<SecurityOrigin> origin = scriptState->getExecutionContext()->getSecur
ityOrigin(); |
68 | 68 |
69 // TODO(yhirano): Implement the following steps: | 69 // TODO(yhirano): Implement the following steps: |
70 // - "Let |window| be client." | 70 // - "Let |window| be client." |
71 // - "If |request|'s window is an environment settings object and its | 71 // - "If |request|'s window is an environment settings object and its |
72 // origin is same origin with entry settings object's origin, set | 72 // origin is same origin with entry settings object's origin, set |
73 // |window| to |request|'s window." | 73 // |window| to |request|'s window." |
74 // - "If |init|'s window member is present and it is not null, throw a | 74 // - "If |init|'s window member is present and it is not null, throw a |
75 // TypeError." | 75 // TypeError." |
76 // - "If |init|'s window member is present, set |window| to no-window." | 76 // - "If |init|'s window member is present, set |window| to no-window." |
77 // | 77 // |
(...skipping 10 matching lines...) Expand all Loading... |
88 FetchRequestData* request = createCopyOfFetchRequestDataForFetch(scriptState
, inputRequest ? inputRequest->request() : FetchRequestData::create()); | 88 FetchRequestData* request = createCopyOfFetchRequestDataForFetch(scriptState
, inputRequest ? inputRequest->request() : FetchRequestData::create()); |
89 | 89 |
90 // We don't use fallback values. We set these flags directly in below. | 90 // We don't use fallback values. We set these flags directly in below. |
91 // - "Let |fallbackMode| be null." | 91 // - "Let |fallbackMode| be null." |
92 // - "Let |fallbackCredentials| be null." | 92 // - "Let |fallbackCredentials| be null." |
93 // - "Let |baseURL| be entry settings object's API base URL." | 93 // - "Let |baseURL| be entry settings object's API base URL." |
94 | 94 |
95 // "If |input| is a string, run these substeps:" | 95 // "If |input| is a string, run these substeps:" |
96 if (!inputRequest) { | 96 if (!inputRequest) { |
97 // "Let |parsedURL| be the result of parsing |input| with |baseURL|." | 97 // "Let |parsedURL| be the result of parsing |input| with |baseURL|." |
98 KURL parsedURL = scriptState->executionContext()->completeURL(inputStrin
g); | 98 KURL parsedURL = scriptState->getExecutionContext()->completeURL(inputSt
ring); |
99 // "If |parsedURL| is failure, throw a TypeError." | 99 // "If |parsedURL| is failure, throw a TypeError." |
100 if (!parsedURL.isValid()) { | 100 if (!parsedURL.isValid()) { |
101 exceptionState.throwTypeError("Failed to parse URL from " + inputStr
ing); | 101 exceptionState.throwTypeError("Failed to parse URL from " + inputStr
ing); |
102 return nullptr; | 102 return nullptr; |
103 } | 103 } |
104 // "If |parsedURL| includes credentials, throw a TypeError." | 104 // "If |parsedURL| includes credentials, throw a TypeError." |
105 if (!parsedURL.user().isEmpty() || !parsedURL.pass().isEmpty()) { | 105 if (!parsedURL.user().isEmpty() || !parsedURL.pass().isEmpty()) { |
106 exceptionState.throwTypeError("Request cannot be constructed from a
URL that includes credentials: " + inputString); | 106 exceptionState.throwTypeError("Request cannot be constructed from a
URL that includes credentials: " + inputString); |
107 return nullptr; | 107 return nullptr; |
108 } | 108 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // Nothing to do for the step "Let |referrer| be |init|'s referrer | 152 // Nothing to do for the step "Let |referrer| be |init|'s referrer |
153 // member." | 153 // member." |
154 | 154 |
155 if (init.referrer.referrer.isEmpty()) { | 155 if (init.referrer.referrer.isEmpty()) { |
156 // "If |referrer| is the empty string, set |request|'s referrer to | 156 // "If |referrer| is the empty string, set |request|'s referrer to |
157 // "no-referrer" and terminate these substeps." | 157 // "no-referrer" and terminate these substeps." |
158 request->setReferrerString(FetchRequestData::noReferrerString()); | 158 request->setReferrerString(FetchRequestData::noReferrerString()); |
159 } else { | 159 } else { |
160 // "Let |parsedReferrer| be the result of parsing |referrer| with | 160 // "Let |parsedReferrer| be the result of parsing |referrer| with |
161 // |baseURL|." | 161 // |baseURL|." |
162 KURL parsedReferrer = scriptState->executionContext()->completeURL(i
nit.referrer.referrer); | 162 KURL parsedReferrer = scriptState->getExecutionContext()->completeUR
L(init.referrer.referrer); |
163 if (!parsedReferrer.isValid()) { | 163 if (!parsedReferrer.isValid()) { |
164 // "If |parsedReferrer| is failure, throw a TypeError." | 164 // "If |parsedReferrer| is failure, throw a TypeError." |
165 exceptionState.throwTypeError("Referrer '" + init.referrer.refer
rer + "' is not a valid URL."); | 165 exceptionState.throwTypeError("Referrer '" + init.referrer.refer
rer + "' is not a valid URL."); |
166 return nullptr; | 166 return nullptr; |
167 } | 167 } |
168 if (parsedReferrer.protocolIsAbout() && parsedReferrer.host().isEmpt
y() && parsedReferrer.path() == "client") { | 168 if (parsedReferrer.protocolIsAbout() && parsedReferrer.host().isEmpt
y() && parsedReferrer.path() == "client") { |
169 // "If |parsedReferrer|'s non-relative flag is set, scheme is | 169 // "If |parsedReferrer|'s non-relative flag is set, scheme is |
170 // "about", and path contains a single string "client", set | 170 // "about", and path contains a single string "client", set |
171 // request's referrer to "client" and terminate these | 171 // request's referrer to "client" and terminate these |
172 // substeps." | 172 // substeps." |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 if (FetchUtils::isForbiddenMethod(init.method)) { | 252 if (FetchUtils::isForbiddenMethod(init.method)) { |
253 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); | 253 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); |
254 return nullptr; | 254 return nullptr; |
255 } | 255 } |
256 // "Normalize |method|." | 256 // "Normalize |method|." |
257 // "Set |request|'s method to |method|." | 257 // "Set |request|'s method to |method|." |
258 request->setMethod(FetchUtils::normalizeMethod(AtomicString(init.method)
)); | 258 request->setMethod(FetchUtils::normalizeMethod(AtomicString(init.method)
)); |
259 } | 259 } |
260 // "Let |r| be a new Request object associated with |request| and a new | 260 // "Let |r| be a new Request object associated with |request| and a new |
261 // Headers object whose guard is "request"." | 261 // Headers object whose guard is "request"." |
262 Request* r = Request::create(scriptState->executionContext(), request); | 262 Request* r = Request::create(scriptState->getExecutionContext(), request); |
263 // Perform the following steps: | 263 // Perform the following steps: |
264 // - "Let |headers| be a copy of |r|'s Headers object." | 264 // - "Let |headers| be a copy of |r|'s Headers object." |
265 // - "If |init|'s headers member is present, set |headers| to |init|'s | 265 // - "If |init|'s headers member is present, set |headers| to |init|'s |
266 // headers member." | 266 // headers member." |
267 // | 267 // |
268 // We don't create a copy of r's Headers object when init's headers member | 268 // We don't create a copy of r's Headers object when init's headers member |
269 // is present. | 269 // is present. |
270 Headers* headers = nullptr; | 270 Headers* headers = nullptr; |
271 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { | 271 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { |
272 headers = r->headers()->clone(); | 272 headers = r->getHeaders()->clone(); |
273 } | 273 } |
274 // "Empty |r|'s request's header list." | 274 // "Empty |r|'s request's header list." |
275 r->m_request->headerList()->clearList(); | 275 r->m_request->headerList()->clearList(); |
276 // "If |r|'s request's mode is "no-cors", run these substeps: | 276 // "If |r|'s request's mode is "no-cors", run these substeps: |
277 if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { | 277 if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { |
278 // "If |r|'s request's method is not a simple method, throw a | 278 // "If |r|'s request's method is not a simple method, throw a |
279 // TypeError." | 279 // TypeError." |
280 if (!FetchUtils::isSimpleMethod(r->request()->method())) { | 280 if (!FetchUtils::isSimpleMethod(r->request()->method())) { |
281 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); | 281 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); |
282 return nullptr; | 282 return nullptr; |
283 } | 283 } |
284 // "If |request|'s integrity metadata is not the empty string, throw a | 284 // "If |request|'s integrity metadata is not the empty string, throw a |
285 // TypeError." | 285 // TypeError." |
286 if (!request->integrity().isEmpty()) { | 286 if (!request->integrity().isEmpty()) { |
287 exceptionState.throwTypeError("The integrity attribute is unsupporte
d in no-cors mode."); | 287 exceptionState.throwTypeError("The integrity attribute is unsupporte
d in no-cors mode."); |
288 return nullptr; | 288 return nullptr; |
289 } | 289 } |
290 // "Set |r|'s Headers object's guard to "request-no-cors"." | 290 // "Set |r|'s Headers object's guard to "request-no-cors"." |
291 r->headers()->setGuard(Headers::RequestNoCORSGuard); | 291 r->getHeaders()->setGuard(Headers::RequestNoCORSGuard); |
292 } | 292 } |
293 // "Fill |r|'s Headers object with |headers|. Rethrow any exceptions." | 293 // "Fill |r|'s Headers object with |headers|. Rethrow any exceptions." |
294 if (init.headers) { | 294 if (init.headers) { |
295 ASSERT(init.headersDictionary.isUndefinedOrNull()); | 295 ASSERT(init.headersDictionary.isUndefinedOrNull()); |
296 r->headers()->fillWith(init.headers.get(), exceptionState); | 296 r->getHeaders()->fillWith(init.headers.get(), exceptionState); |
297 } else if (!init.headersDictionary.isUndefinedOrNull()) { | 297 } else if (!init.headersDictionary.isUndefinedOrNull()) { |
298 r->headers()->fillWith(init.headersDictionary, exceptionState); | 298 r->getHeaders()->fillWith(init.headersDictionary, exceptionState); |
299 } else { | 299 } else { |
300 ASSERT(headers); | 300 ASSERT(headers); |
301 r->headers()->fillWith(headers, exceptionState); | 301 r->getHeaders()->fillWith(headers, exceptionState); |
302 } | 302 } |
303 if (exceptionState.hadException()) | 303 if (exceptionState.hadException()) |
304 return nullptr; | 304 return nullptr; |
305 | 305 |
306 // "If either |init|'s body member is present or |temporaryBody| is | 306 // "If either |init|'s body member is present or |temporaryBody| is |
307 // non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError. | 307 // non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError. |
308 if (init.body || temporaryBody) { | 308 if (init.body || temporaryBody) { |
309 if (request->method() == HTTPNames::GET || request->method() == HTTPName
s::HEAD) { | 309 if (request->method() == HTTPNames::GET || request->method() == HTTPName
s::HEAD) { |
310 exceptionState.throwTypeError("Request with GET/HEAD method cannot h
ave body."); | 310 exceptionState.throwTypeError("Request with GET/HEAD method cannot h
ave body."); |
311 return nullptr; | 311 return nullptr; |
312 } | 312 } |
313 } | 313 } |
314 | 314 |
315 // "If |init|'s body member is present, run these substeps:" | 315 // "If |init|'s body member is present, run these substeps:" |
316 if (init.body) { | 316 if (init.body) { |
317 // Perform the following steps: | 317 // Perform the following steps: |
318 // - "Let |stream| and |Content-Type| be the result of extracting | 318 // - "Let |stream| and |Content-Type| be the result of extracting |
319 // |init|'s body member." | 319 // |init|'s body member." |
320 // - "Set |temporaryBody| to |stream|. | 320 // - "Set |temporaryBody| to |stream|. |
321 // - "If |Content-Type| is non-null and |r|'s request's header list | 321 // - "If |Content-Type| is non-null and |r|'s request's header list |
322 // contains no header named `Content-Type`, append | 322 // contains no header named `Content-Type`, append |
323 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any | 323 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any |
324 // exception." | 324 // exception." |
325 temporaryBody = new BodyStreamBuffer(init.body.release()); | 325 temporaryBody = new BodyStreamBuffer(init.body.release()); |
326 if (!init.contentType.isEmpty() && !r->headers()->has(HTTPNames::Content
_Type, exceptionState)) { | 326 if (!init.contentType.isEmpty() && !r->getHeaders()->has(HTTPNames::Cont
ent_Type, exceptionState)) { |
327 r->headers()->append(HTTPNames::Content_Type, init.contentType, exce
ptionState); | 327 r->getHeaders()->append(HTTPNames::Content_Type, init.contentType, e
xceptionState); |
328 } | 328 } |
329 if (exceptionState.hadException()) | 329 if (exceptionState.hadException()) |
330 return nullptr; | 330 return nullptr; |
331 } | 331 } |
332 | 332 |
333 // "Set |r|'s request's body to |temporaryBody|. | 333 // "Set |r|'s request's body to |temporaryBody|. |
334 if (temporaryBody) | 334 if (temporaryBody) |
335 r->m_request->setBuffer(temporaryBody); | 335 r->m_request->setBuffer(temporaryBody); |
336 | 336 |
337 // https://w3c.github.io/webappsec-credential-management/#monkey-patching-fe
tch-3 | 337 // https://w3c.github.io/webappsec-credential-management/#monkey-patching-fe
tch-3 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 return create(scriptState, input.getAsRequest(), init, exceptionState); | 375 return create(scriptState, input.getAsRequest(), init, exceptionState); |
376 } | 376 } |
377 | 377 |
378 Request* Request::create(ScriptState* scriptState, const String& input, Exceptio
nState& exceptionState) | 378 Request* Request::create(ScriptState* scriptState, const String& input, Exceptio
nState& exceptionState) |
379 { | 379 { |
380 return create(scriptState, input, Dictionary(), exceptionState); | 380 return create(scriptState, input, Dictionary(), exceptionState); |
381 } | 381 } |
382 | 382 |
383 Request* Request::create(ScriptState* scriptState, const String& input, const Di
ctionary& init, ExceptionState& exceptionState) | 383 Request* Request::create(ScriptState* scriptState, const String& input, const Di
ctionary& init, ExceptionState& exceptionState) |
384 { | 384 { |
385 RequestInit requestInit(scriptState->executionContext(), init, exceptionStat
e); | 385 RequestInit requestInit(scriptState->getExecutionContext(), init, exceptionS
tate); |
386 return createRequestWithRequestOrString(scriptState, nullptr, input, request
Init, exceptionState); | 386 return createRequestWithRequestOrString(scriptState, nullptr, input, request
Init, exceptionState); |
387 } | 387 } |
388 | 388 |
389 Request* Request::create(ScriptState* scriptState, Request* input, ExceptionStat
e& exceptionState) | 389 Request* Request::create(ScriptState* scriptState, Request* input, ExceptionStat
e& exceptionState) |
390 { | 390 { |
391 return create(scriptState, input, Dictionary(), exceptionState); | 391 return create(scriptState, input, Dictionary(), exceptionState); |
392 } | 392 } |
393 | 393 |
394 Request* Request::create(ScriptState* scriptState, Request* input, const Diction
ary& init, ExceptionState& exceptionState) | 394 Request* Request::create(ScriptState* scriptState, Request* input, const Diction
ary& init, ExceptionState& exceptionState) |
395 { | 395 { |
396 RequestInit requestInit(scriptState->executionContext(), init, exceptionStat
e); | 396 RequestInit requestInit(scriptState->getExecutionContext(), init, exceptionS
tate); |
397 return createRequestWithRequestOrString(scriptState, input, String(), reques
tInit, exceptionState); | 397 return createRequestWithRequestOrString(scriptState, input, String(), reques
tInit, exceptionState); |
398 } | 398 } |
399 | 399 |
400 Request* Request::create(ExecutionContext* context, FetchRequestData* request) | 400 Request* Request::create(ExecutionContext* context, FetchRequestData* request) |
401 { | 401 { |
402 return new Request(context, request); | 402 return new Request(context, request); |
403 } | 403 } |
404 | 404 |
405 Request::Request(ExecutionContext* context, FetchRequestData* request) | 405 Request::Request(ExecutionContext* context, FetchRequestData* request) |
406 : Body(context) | 406 : Body(context) |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 return m_request->integrity(); | 585 return m_request->integrity(); |
586 } | 586 } |
587 | 587 |
588 Request* Request::clone(ExceptionState& exceptionState) | 588 Request* Request::clone(ExceptionState& exceptionState) |
589 { | 589 { |
590 if (isBodyLocked() || bodyUsed()) { | 590 if (isBodyLocked() || bodyUsed()) { |
591 exceptionState.throwTypeError("Request body is already used"); | 591 exceptionState.throwTypeError("Request body is already used"); |
592 return nullptr; | 592 return nullptr; |
593 } | 593 } |
594 | 594 |
595 FetchRequestData* request = m_request->clone(executionContext()); | 595 FetchRequestData* request = m_request->clone(getExecutionContext()); |
596 Headers* headers = Headers::create(request->headerList()); | 596 Headers* headers = Headers::create(request->headerList()); |
597 headers->setGuard(m_headers->getGuard()); | 597 headers->setGuard(m_headers->getGuard()); |
598 return new Request(executionContext(), request, headers); | 598 return new Request(getExecutionContext(), request, headers); |
599 } | 599 } |
600 | 600 |
601 FetchRequestData* Request::passRequestData() | 601 FetchRequestData* Request::passRequestData() |
602 { | 602 { |
603 ASSERT(!bodyUsed()); | 603 ASSERT(!bodyUsed()); |
604 return m_request->pass(executionContext()); | 604 return m_request->pass(getExecutionContext()); |
605 } | 605 } |
606 | 606 |
607 bool Request::hasBody() const | 607 bool Request::hasBody() const |
608 { | 608 { |
609 return bodyBuffer(); | 609 return bodyBuffer(); |
610 } | 610 } |
611 | 611 |
612 void Request::stop() | 612 void Request::stop() |
613 { | 613 { |
614 if (bodyBuffer()) | 614 if (bodyBuffer()) |
(...skipping 24 matching lines...) Expand all Loading... |
639 } | 639 } |
640 | 640 |
641 DEFINE_TRACE(Request) | 641 DEFINE_TRACE(Request) |
642 { | 642 { |
643 Body::trace(visitor); | 643 Body::trace(visitor); |
644 visitor->trace(m_request); | 644 visitor->trace(m_request); |
645 visitor->trace(m_headers); | 645 visitor->trace(m_headers); |
646 } | 646 } |
647 | 647 |
648 } // namespace blink | 648 } // namespace blink |
OLD | NEW |