| 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 "modules/fetch/Request.h" | 6 #include "modules/fetch/Request.h" | 
| 7 | 7 | 
| 8 #include "bindings/core/v8/Dictionary.h" | 8 #include "bindings/core/v8/Dictionary.h" | 
| 9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" | 
| 10 #include "core/dom/ExecutionContext.h" | 10 #include "core/dom/ExecutionContext.h" | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 63 | 63 | 
| 64     // "2. If |input| is a Request object and |input|'s body is non-null, run | 64     // "2. If |input| is a Request object and |input|'s body is non-null, run | 
| 65     // these substeps:" | 65     // these substeps:" | 
| 66     if (inputRequest && inputRequest->hasBody()) { | 66     if (inputRequest && inputRequest->hasBody()) { | 
| 67         // "1. If |input|'s used flag is set, throw a TypeError." | 67         // "1. If |input|'s used flag is set, throw a TypeError." | 
| 68         // "2. Set |temporaryBody| to |input|'s body." | 68         // "2. Set |temporaryBody| to |input|'s body." | 
| 69         if (inputRequest->bodyUsed()) { | 69         if (inputRequest->bodyUsed()) { | 
| 70             exceptionState.throwTypeError("Cannot construct a Request with a Req
     uest object that has already been used."); | 70             exceptionState.throwTypeError("Cannot construct a Request with a Req
     uest object that has already been used."); | 
| 71             return nullptr; | 71             return nullptr; | 
| 72         } | 72         } | 
| 73         // We call createDrainingStream() later and not here, because |  | 
| 74         // createDrainingStream() has side effects on |inputRequest|'s body. |  | 
| 75         temporaryBodyRequest = inputRequest; | 73         temporaryBodyRequest = inputRequest; | 
| 76     } | 74     } | 
| 77 | 75 | 
| 78     // "3. Let |request| be |input|'s request, if |input| is a Request object, | 76     // "3. Let |request| be |input|'s request, if |input| is a Request object, | 
| 79     // and a new request otherwise." | 77     // and a new request otherwise." | 
| 80     // "4. Set |request| to a new request whose url is |request|'s url, method | 78     // "4. Set |request| to a new request whose url is |request|'s url, method | 
| 81     // is |request|'s method, header list is a copy of |request|'s header list, | 79     // is |request|'s method, header list is a copy of |request|'s header list, | 
| 82     // unsafe request flag is set, client is entry settings object, origin is | 80     // unsafe request flag is set, client is entry settings object, origin is | 
| 83     // entry settings object's origin, force Origin header flag is set, | 81     // entry settings object's origin, force Origin header flag is set, | 
| 84     // same-origin data URL flag is set, context is the empty string, mode is | 82     // same-origin data URL flag is set, context is the empty string, mode is | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 179     // "22. Let |headers| be a copy of |r|'s Headers object." | 177     // "22. Let |headers| be a copy of |r|'s Headers object." | 
| 180     // "23. If |init|'s headers member is present, set |headers| to |init|'s | 178     // "23. If |init|'s headers member is present, set |headers| to |init|'s | 
| 181     // headers member." | 179     // headers member." | 
| 182     // We don't create a copy of r's Headers object when init's headers member | 180     // We don't create a copy of r's Headers object when init's headers member | 
| 183     // is present. | 181     // is present. | 
| 184     Headers* headers = nullptr; | 182     Headers* headers = nullptr; | 
| 185     if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { | 183     if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { | 
| 186         headers = r->headers()->clone(); | 184         headers = r->headers()->clone(); | 
| 187     } | 185     } | 
| 188     // "24. Empty |r|'s request's header list." | 186     // "24. Empty |r|'s request's header list." | 
| 189     r->clearHeaderList(); | 187     r->m_request->headerList()->clearList(); | 
| 190     // "25. If |r|'s request's mode is no CORS, run these substeps: | 188     // "25. If |r|'s request's mode is no CORS, run these substeps: | 
| 191     if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { | 189     if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { | 
| 192         // "1. If |r|'s request's method is not a simple method, throw a | 190         // "1. If |r|'s request's method is not a simple method, throw a | 
| 193         // TypeError." | 191         // TypeError." | 
| 194         if (!FetchUtils::isSimpleMethod(r->request()->method())) { | 192         if (!FetchUtils::isSimpleMethod(r->request()->method())) { | 
| 195             exceptionState.throwTypeError("'" + r->request()->method() + "' is u
     nsupported in no-cors mode."); | 193             exceptionState.throwTypeError("'" + r->request()->method() + "' is u
     nsupported in no-cors mode."); | 
| 196             return nullptr; | 194             return nullptr; | 
| 197         } | 195         } | 
| 198         // "Set |r|'s Headers object's guard to |request-no-CORS|. | 196         // "Set |r|'s Headers object's guard to |request-no-CORS|. | 
| 199         r->headers()->setGuard(Headers::RequestNoCORSGuard); | 197         r->headers()->setGuard(Headers::RequestNoCORSGuard); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 222 | 220 | 
| 223     // "28. If |init|'s body member is present, run these substeps:" | 221     // "28. If |init|'s body member is present, run these substeps:" | 
| 224     if (init.bodyBlobHandle) { | 222     if (init.bodyBlobHandle) { | 
| 225         // "1. Let |stream| and |Content-Type| be the result of extracting | 223         // "1. Let |stream| and |Content-Type| be the result of extracting | 
| 226         //  |init|'s body member." | 224         //  |init|'s body member." | 
| 227         // "2. Set |temporaryBody| to |stream|. | 225         // "2. Set |temporaryBody| to |stream|. | 
| 228         // "3. If |Content-Type| is non-null and |r|'s request's header list | 226         // "3. If |Content-Type| is non-null and |r|'s request's header list | 
| 229         //  contains no header named `Content-Type`, append | 227         //  contains no header named `Content-Type`, append | 
| 230         //  `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any | 228         //  `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any | 
| 231         //  exception." | 229         //  exception." | 
| 232         temporaryBodyBuffer = BodyStreamBuffer::create(FetchBlobDataConsumerHand
     le::create(scriptState->executionContext(), init.bodyBlobHandle)); | 230         temporaryBodyBuffer = new BodyStreamBuffer(FetchBlobDataConsumerHandle::
     create(scriptState->executionContext(), init.bodyBlobHandle)); | 
| 233         temporaryBodyRequest = nullptr; | 231         temporaryBodyRequest = nullptr; | 
| 234         if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten
     t-Type", exceptionState)) { | 232         if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten
     t-Type", exceptionState)) { | 
| 235             r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex
     ceptionState); | 233             r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex
     ceptionState); | 
| 236         } | 234         } | 
| 237         if (exceptionState.hadException()) | 235         if (exceptionState.hadException()) | 
| 238             return nullptr; | 236             return nullptr; | 
| 239     } | 237     } | 
| 240 | 238 | 
| 241     // "29. Set |r|'s body to |temporaryBody|. | 239     // "29. Set |r|'s body to |temporaryBody|. | 
| 242     if (temporaryBodyBuffer) | 240     if (temporaryBodyBuffer) | 
| 243         r->setBuffer(temporaryBodyBuffer); | 241         r->m_request->setBuffer(temporaryBodyBuffer); | 
| 244     else if (temporaryBodyRequest) | 242     else if (temporaryBodyRequest) | 
| 245         r->setBuffer(temporaryBodyRequest->createDrainingStream()->leakBuffer())
     ; | 243         r->m_request->setBuffer(temporaryBodyRequest->bodyBuffer()); | 
| 246 | 244 | 
| 247     // "30. Set |r|'s MIME type to the result of extracting a MIME type from | 245     // "30. Set |r|'s MIME type to the result of extracting a MIME type from | 
| 248     // |r|'s request's header list." | 246     // |r|'s request's header list." | 
| 249     r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType()); | 247     r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType()); | 
| 250 | 248 | 
| 251     // "31. If |input| is a Request object and |input|'s body is non-null, run | 249     // "31. If |input| is a Request object and |input|'s body is non-null, run | 
| 252     // these substeps:" | 250     // these substeps:" | 
| 253     // We set bodyUsed even when the body is null in spite of the | 251     // We set bodyUsed even when the body is null in spite of the | 
| 254     // spec. See https://github.com/whatwg/fetch/issues/61 for details. | 252     // spec. See https://github.com/whatwg/fetch/issues/61 for details. | 
| 255     if (inputRequest) { | 253     if (inputRequest) { | 
| 256         // "1. Set |input|'s body to null." | 254         // "1. Set |input|'s body to null." | 
| 257         inputRequest->setBuffer(nullptr); | 255         inputRequest->m_request->setBuffer(new BodyStreamBuffer); | 
| 258         // "2. Set |input|'s used flag." | 256         // "2. Set |input|'s used flag." | 
| 259         inputRequest->lockBody(PassBody); | 257         inputRequest->setBodyPassed(); | 
| 260     } | 258     } | 
| 261 | 259 | 
| 262     // "32. Return |r|." | 260     // "32. Return |r|." | 
| 263     return r; | 261     return r; | 
| 264 } | 262 } | 
| 265 | 263 | 
| 266 Request* Request::create(ScriptState* scriptState, const RequestInfo& input, con
     st Dictionary& init, ExceptionState& exceptionState) | 264 Request* Request::create(ScriptState* scriptState, const RequestInfo& input, con
     st Dictionary& init, ExceptionState& exceptionState) | 
| 267 { | 265 { | 
| 268     ASSERT(!input.isNull()); | 266     ASSERT(!input.isNull()); | 
| 269     if (input.isUSVString()) | 267     if (input.isUSVString()) | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 286     return create(scriptState, input, Dictionary(), exceptionState); | 284     return create(scriptState, input, Dictionary(), exceptionState); | 
| 287 } | 285 } | 
| 288 | 286 | 
| 289 Request* Request::create(ScriptState* scriptState, Request* input, const Diction
     ary& init, ExceptionState& exceptionState) | 287 Request* Request::create(ScriptState* scriptState, Request* input, const Diction
     ary& init, ExceptionState& exceptionState) | 
| 290 { | 288 { | 
| 291     return createRequestWithRequestOrString(scriptState, input, String(), Reques
     tInit(scriptState->executionContext(), init, exceptionState), exceptionState); | 289     return createRequestWithRequestOrString(scriptState, input, String(), Reques
     tInit(scriptState->executionContext(), init, exceptionState), exceptionState); | 
| 292 } | 290 } | 
| 293 | 291 | 
| 294 Request* Request::create(ExecutionContext* context, FetchRequestData* request) | 292 Request* Request::create(ExecutionContext* context, FetchRequestData* request) | 
| 295 { | 293 { | 
| 296     Request* r = new Request(context, request); | 294     return new Request(context, request); | 
| 297     r->suspendIfNeeded(); |  | 
| 298     return r; |  | 
| 299 } | 295 } | 
| 300 | 296 | 
| 301 Request::Request(ExecutionContext* context, FetchRequestData* request) | 297 Request::Request(ExecutionContext* context, FetchRequestData* request) | 
| 302     : Body(context) | 298     : Body(context) | 
| 303     , m_request(request) | 299     , m_request(request) | 
| 304     , m_headers(Headers::create(m_request->headerList())) | 300     , m_headers(Headers::create(m_request->headerList())) | 
| 305 { | 301 { | 
| 306     m_headers->setGuard(Headers::RequestGuard); | 302     m_headers->setGuard(Headers::RequestGuard); | 
| 307 |  | 
| 308     refreshBody(); |  | 
| 309 } | 303 } | 
| 310 | 304 | 
| 311 Request::Request(ExecutionContext* context, FetchRequestData* request, Headers* 
     headers) | 305 Request::Request(ExecutionContext* context, FetchRequestData* request, Headers* 
     headers) | 
| 312     : Body(context) , m_request(request) , m_headers(headers) | 306     : Body(context) , m_request(request) , m_headers(headers) {} | 
| 313 { |  | 
| 314     refreshBody(); |  | 
| 315 } |  | 
| 316 | 307 | 
| 317 Request* Request::create(ExecutionContext* context, const WebServiceWorkerReques
     t& webRequest) | 308 Request* Request::create(ExecutionContext* context, const WebServiceWorkerReques
     t& webRequest) | 
| 318 { | 309 { | 
| 319     Request* r = new Request(context, webRequest); | 310     return new Request(context, webRequest); | 
| 320     r->suspendIfNeeded(); |  | 
| 321     return r; |  | 
| 322 } | 311 } | 
| 323 | 312 | 
| 324 Request::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRe
     quest) | 313 Request::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRe
     quest) | 
| 325     : Body(context) | 314     : Body(context) | 
| 326     , m_request(FetchRequestData::create(context, webRequest)) | 315     , m_request(FetchRequestData::create(context, webRequest)) | 
| 327     , m_headers(Headers::create(m_request->headerList())) | 316     , m_headers(Headers::create(m_request->headerList())) | 
| 328 { | 317 { | 
| 329     m_headers->setGuard(Headers::RequestGuard); | 318     m_headers->setGuard(Headers::RequestGuard); | 
| 330 |  | 
| 331     refreshBody(); |  | 
| 332 } | 319 } | 
| 333 | 320 | 
| 334 String Request::method() const | 321 String Request::method() const | 
| 335 { | 322 { | 
| 336     // "The method attribute's getter must return request's method." | 323     // "The method attribute's getter must return request's method." | 
| 337     return m_request->method(); | 324     return m_request->method(); | 
| 338 } | 325 } | 
| 339 | 326 | 
| 340 KURL Request::url() const | 327 KURL Request::url() const | 
| 341 { | 328 { | 
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 470     return ""; | 457     return ""; | 
| 471 } | 458 } | 
| 472 | 459 | 
| 473 Request* Request::clone(ExceptionState& exceptionState) | 460 Request* Request::clone(ExceptionState& exceptionState) | 
| 474 { | 461 { | 
| 475     if (bodyUsed()) { | 462     if (bodyUsed()) { | 
| 476         exceptionState.throwTypeError("Request body is already used"); | 463         exceptionState.throwTypeError("Request body is already used"); | 
| 477         return nullptr; | 464         return nullptr; | 
| 478     } | 465     } | 
| 479 | 466 | 
| 480     if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream()) |  | 
| 481         m_request->setBuffer(buffer->leakBuffer()); |  | 
| 482 |  | 
| 483     FetchRequestData* request = m_request->clone(executionContext()); | 467     FetchRequestData* request = m_request->clone(executionContext()); | 
| 484     Headers* headers = Headers::create(request->headerList()); | 468     Headers* headers = Headers::create(request->headerList()); | 
| 485     headers->setGuard(m_headers->guard()); | 469     headers->setGuard(m_headers->guard()); | 
| 486     Request* r = new Request(executionContext(), request, headers); | 470     return new Request(executionContext(), request, headers); | 
| 487     r->suspendIfNeeded(); |  | 
| 488 |  | 
| 489     // Lock the old body and set |body| property to the new one. |  | 
| 490     lockBody(); |  | 
| 491     refreshBody(); |  | 
| 492     return r; |  | 
| 493 } | 471 } | 
| 494 | 472 | 
| 495 FetchRequestData* Request::passRequestData() | 473 FetchRequestData* Request::passRequestData() | 
| 496 { | 474 { | 
| 497     ASSERT(!bodyUsed()); | 475     ASSERT(!bodyUsed()); | 
|  | 476     setBodyPassed(); | 
|  | 477     FetchRequestData* newRequestData = m_request->pass(executionContext()); | 
|  | 478     return newRequestData; | 
|  | 479 } | 
| 498 | 480 | 
| 499     if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream()) | 481 bool Request::hasBody() const | 
| 500         m_request->setBuffer(buffer->leakBuffer()); | 482 { | 
| 501 | 483     return bodyBuffer()->hasBody(); | 
| 502     lockBody(PassBody); |  | 
| 503     FetchRequestData* newRequestData = m_request->pass(executionContext()); |  | 
| 504     refreshBody(); |  | 
| 505     return newRequestData; |  | 
| 506 } | 484 } | 
| 507 | 485 | 
| 508 void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webReques
     t) const | 486 void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webReques
     t) const | 
| 509 { | 487 { | 
| 510     webRequest.setMethod(method()); | 488     webRequest.setMethod(method()); | 
| 511     webRequest.setRequestContext(m_request->context()); | 489     webRequest.setRequestContext(m_request->context()); | 
| 512     // This strips off the fragment part. | 490     // This strips off the fragment part. | 
| 513     webRequest.setURL(url()); | 491     webRequest.setURL(url()); | 
| 514 | 492 | 
| 515     const FetchHeaderList* headerList = m_headers->headerList(); | 493     const FetchHeaderList* headerList = m_headers->headerList(); | 
| 516     for (size_t i = 0, size = headerList->size(); i < size; ++i) { | 494     for (size_t i = 0, size = headerList->size(); i < size; ++i) { | 
| 517         const FetchHeaderList::Header& header = headerList->entry(i); | 495         const FetchHeaderList::Header& header = headerList->entry(i); | 
| 518         webRequest.appendHeader(header.first, header.second); | 496         webRequest.appendHeader(header.first, header.second); | 
| 519     } | 497     } | 
| 520 | 498 | 
| 521     webRequest.setReferrer(m_request->referrer().referrer().referrer, static_cas
     t<WebReferrerPolicy>(m_request->referrer().referrer().referrerPolicy)); | 499     webRequest.setReferrer(m_request->referrer().referrer().referrer, static_cas
     t<WebReferrerPolicy>(m_request->referrer().referrer().referrerPolicy)); | 
| 522     // FIXME: How can we set isReload properly? What is the correct place to loa
     d it in to the Request object? We should investigate the right way | 500     // FIXME: How can we set isReload properly? What is the correct place to loa
     d it in to the Request object? We should investigate the right way | 
| 523     // to plumb this information in to here. | 501     // to plumb this information in to here. | 
| 524 } | 502 } | 
| 525 | 503 | 
| 526 void Request::setBuffer(BodyStreamBuffer* buffer) |  | 
| 527 { |  | 
| 528     m_request->setBuffer(buffer); |  | 
| 529     refreshBody(); |  | 
| 530 } |  | 
| 531 |  | 
| 532 void Request::refreshBody() |  | 
| 533 { |  | 
| 534     setBody(m_request->buffer()); |  | 
| 535 } |  | 
| 536 |  | 
| 537 void Request::clearHeaderList() |  | 
| 538 { |  | 
| 539     m_request->headerList()->clearList(); |  | 
| 540 } |  | 
| 541 |  | 
| 542 String Request::mimeType() const | 504 String Request::mimeType() const | 
| 543 { | 505 { | 
| 544     return m_request->mimeType(); | 506     return m_request->mimeType(); | 
| 545 } | 507 } | 
| 546 | 508 | 
| 547 DEFINE_TRACE(Request) | 509 DEFINE_TRACE(Request) | 
| 548 { | 510 { | 
| 549     Body::trace(visitor); | 511     Body::trace(visitor); | 
| 550     visitor->trace(m_request); | 512     visitor->trace(m_request); | 
| 551     visitor->trace(m_headers); | 513     visitor->trace(m_headers); | 
| 552 } | 514 } | 
| 553 | 515 | 
| 554 } // namespace blink | 516 } // namespace blink | 
| OLD | NEW | 
|---|