Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: Source/modules/fetch/Request.cpp

Issue 1233573002: [Fetch API] Remove DrainingBuffer. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/modules/fetch/Request.h ('k') | Source/modules/fetch/Response.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 request->setMode(original->mode()); 42 request->setMode(original->mode());
43 request->setCredentials(original->credentials()); 43 request->setCredentials(original->credentials());
44 // FIXME: Set cache mode. 44 // FIXME: Set cache mode.
45 // TODO(yhirano): Set redirect mode. 45 // TODO(yhirano): Set redirect mode.
46 return request; 46 return request;
47 } 47 }
48 48
49 Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req uest* inputRequest, const String& inputString, const RequestInit& init, Exceptio nState& exceptionState) 49 Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req uest* inputRequest, const String& inputString, const RequestInit& init, Exceptio nState& exceptionState)
50 { 50 {
51 // "1. Let |temporaryBody| be null." 51 // "1. Let |temporaryBody| be null."
52 Request* temporaryBodyRequest = nullptr; 52 BodyStreamBuffer* temporaryBody = nullptr;
53 BodyStreamBuffer* temporaryBodyBuffer = nullptr;
54 53
55 if (inputRequest) { 54 if (inputRequest) {
56 // We check bodyUsed even when the body is null in spite of the 55 // We check bodyUsed even when the body is null in spite of the
57 // spec. See https://github.com/whatwg/fetch/issues/61 for details. 56 // spec. See https://github.com/whatwg/fetch/issues/61 for details.
58 if (inputRequest->bodyUsed()) { 57 if (inputRequest->bodyUsed()) {
59 exceptionState.throwTypeError("Cannot construct a Request with a Req uest object that has already been used."); 58 exceptionState.throwTypeError("Cannot construct a Request with a Req uest object that has already been used.");
60 return nullptr; 59 return nullptr;
61 } 60 }
62 } 61 }
63 62
64 // "2. If |input| is a Request object and |input|'s body is non-null, run 63 // "2. If |input| is a Request object and |input|'s body is non-null, run
65 // these substeps:" 64 // these substeps:"
66 if (inputRequest && inputRequest->hasBody()) { 65 if (inputRequest && inputRequest->hasBody()) {
67 // "1. If |input|'s used flag is set, throw a TypeError." 66 // "1. If |input|'s used flag is set, throw a TypeError."
68 // "2. Set |temporaryBody| to |input|'s body." 67 // "2. Set |temporaryBody| to |input|'s body."
69 if (inputRequest->bodyUsed()) { 68 if (inputRequest->bodyUsed()) {
70 exceptionState.throwTypeError("Cannot construct a Request with a Req uest object that has already been used."); 69 exceptionState.throwTypeError("Cannot construct a Request with a Req uest object that has already been used.");
71 return nullptr; 70 return nullptr;
72 } 71 }
73 // We call createDrainingStream() later and not here, because 72 temporaryBody = inputRequest->bodyBuffer();
74 // createDrainingStream() has side effects on |inputRequest|'s body.
75 temporaryBodyRequest = inputRequest;
76 } 73 }
77 74
78 // "3. Let |request| be |input|'s request, if |input| is a Request object, 75 // "3. Let |request| be |input|'s request, if |input| is a Request object,
79 // and a new request otherwise." 76 // and a new request otherwise."
80 // "4. Set |request| to a new request whose url is |request|'s url, method 77 // "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, 78 // 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 79 // unsafe request flag is set, client is entry settings object, origin is
83 // entry settings object's origin, force Origin header flag is set, 80 // 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 81 // same-origin data URL flag is set, context is the empty string, mode is
85 // |request|'s mode, credentials mode is |request|'s credentials mode, 82 // |request|'s mode, credentials mode is |request|'s credentials mode,
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 // "22. Let |headers| be a copy of |r|'s Headers object." 176 // "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 177 // "23. If |init|'s headers member is present, set |headers| to |init|'s
181 // headers member." 178 // headers member."
182 // We don't create a copy of r's Headers object when init's headers member 179 // We don't create a copy of r's Headers object when init's headers member
183 // is present. 180 // is present.
184 Headers* headers = nullptr; 181 Headers* headers = nullptr;
185 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { 182 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) {
186 headers = r->headers()->clone(); 183 headers = r->headers()->clone();
187 } 184 }
188 // "24. Empty |r|'s request's header list." 185 // "24. Empty |r|'s request's header list."
189 r->clearHeaderList(); 186 r->m_request->headerList()->clearList();
190 // "25. If |r|'s request's mode is no CORS, run these substeps: 187 // "25. If |r|'s request's mode is no CORS, run these substeps:
191 if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { 188 if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) {
192 // "1. If |r|'s request's method is not a simple method, throw a 189 // "1. If |r|'s request's method is not a simple method, throw a
193 // TypeError." 190 // TypeError."
194 if (!FetchUtils::isSimpleMethod(r->request()->method())) { 191 if (!FetchUtils::isSimpleMethod(r->request()->method())) {
195 exceptionState.throwTypeError("'" + r->request()->method() + "' is u nsupported in no-cors mode."); 192 exceptionState.throwTypeError("'" + r->request()->method() + "' is u nsupported in no-cors mode.");
196 return nullptr; 193 return nullptr;
197 } 194 }
198 // "Set |r|'s Headers object's guard to |request-no-CORS|. 195 // "Set |r|'s Headers object's guard to |request-no-CORS|.
199 r->headers()->setGuard(Headers::RequestNoCORSGuard); 196 r->headers()->setGuard(Headers::RequestNoCORSGuard);
200 } 197 }
201 // "26. Fill |r|'s Headers object with |headers|. Rethrow any exceptions." 198 // "26. Fill |r|'s Headers object with |headers|. Rethrow any exceptions."
202 if (init.headers) { 199 if (init.headers) {
203 ASSERT(init.headersDictionary.isUndefinedOrNull()); 200 ASSERT(init.headersDictionary.isUndefinedOrNull());
204 r->headers()->fillWith(init.headers.get(), exceptionState); 201 r->headers()->fillWith(init.headers.get(), exceptionState);
205 } else if (!init.headersDictionary.isUndefinedOrNull()) { 202 } else if (!init.headersDictionary.isUndefinedOrNull()) {
206 r->headers()->fillWith(init.headersDictionary, exceptionState); 203 r->headers()->fillWith(init.headersDictionary, exceptionState);
207 } else { 204 } else {
208 ASSERT(headers); 205 ASSERT(headers);
209 r->headers()->fillWith(headers, exceptionState); 206 r->headers()->fillWith(headers, exceptionState);
210 } 207 }
211 if (exceptionState.hadException()) 208 if (exceptionState.hadException())
212 return nullptr; 209 return nullptr;
213 210
214 // "27. If either |init|'s body member is present or |temporaryBody| is 211 // "27. If either |init|'s body member is present or |temporaryBody| is
215 // non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError. 212 // non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError.
216 if (init.bodyBlobHandle || temporaryBodyRequest) { 213 if (init.bodyBlobHandle || temporaryBody) {
217 if (request->method() == "GET" || request->method() == "HEAD") { 214 if (request->method() == "GET" || request->method() == "HEAD") {
218 exceptionState.throwTypeError("Request with GET/HEAD method cannot h ave body."); 215 exceptionState.throwTypeError("Request with GET/HEAD method cannot h ave body.");
219 return nullptr; 216 return nullptr;
220 } 217 }
221 } 218 }
222 219
223 // "28. If |init|'s body member is present, run these substeps:" 220 // "28. If |init|'s body member is present, run these substeps:"
224 if (init.bodyBlobHandle) { 221 if (init.bodyBlobHandle) {
225 // "1. Let |stream| and |Content-Type| be the result of extracting 222 // "1. Let |stream| and |Content-Type| be the result of extracting
226 // |init|'s body member." 223 // |init|'s body member."
227 // "2. Set |temporaryBody| to |stream|. 224 // "2. Set |temporaryBody| to |stream|.
228 // "3. If |Content-Type| is non-null and |r|'s request's header list 225 // "3. If |Content-Type| is non-null and |r|'s request's header list
229 // contains no header named `Content-Type`, append 226 // contains no header named `Content-Type`, append
230 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any 227 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any
231 // exception." 228 // exception."
232 temporaryBodyBuffer = BodyStreamBuffer::create(FetchBlobDataConsumerHand le::create(scriptState->executionContext(), init.bodyBlobHandle)); 229 temporaryBody = new BodyStreamBuffer(FetchBlobDataConsumerHandle::create (scriptState->executionContext(), init.bodyBlobHandle));
233 temporaryBodyRequest = nullptr;
234 if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten t-Type", exceptionState)) { 230 if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten t-Type", exceptionState)) {
235 r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex ceptionState); 231 r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex ceptionState);
236 } 232 }
237 if (exceptionState.hadException()) 233 if (exceptionState.hadException())
238 return nullptr; 234 return nullptr;
239 } 235 }
240 236
241 // "29. Set |r|'s body to |temporaryBody|. 237 // "29. Set |r|'s body to |temporaryBody|.
242 if (temporaryBodyBuffer) 238 if (temporaryBody)
243 r->setBuffer(temporaryBodyBuffer); 239 r->m_request->setBuffer(temporaryBody);
244 else if (temporaryBodyRequest)
245 r->setBuffer(temporaryBodyRequest->createDrainingStream()->leakBuffer()) ;
246 240
247 // "30. Set |r|'s MIME type to the result of extracting a MIME type from 241 // "30. Set |r|'s MIME type to the result of extracting a MIME type from
248 // |r|'s request's header list." 242 // |r|'s request's header list."
249 r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType()); 243 r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType());
250 244
251 // "31. If |input| is a Request object and |input|'s body is non-null, run 245 // "31. If |input| is a Request object and |input|'s body is non-null, run
252 // these substeps:" 246 // these substeps:"
253 // We set bodyUsed even when the body is null in spite of the 247 // 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. 248 // spec. See https://github.com/whatwg/fetch/issues/61 for details.
255 if (inputRequest) { 249 if (inputRequest) {
256 // "1. Set |input|'s body to null." 250 // "1. Set |input|'s body to null."
257 inputRequest->setBuffer(nullptr); 251 inputRequest->m_request->setBuffer(new BodyStreamBuffer);
258 // "2. Set |input|'s used flag." 252 // "2. Set |input|'s used flag."
259 inputRequest->lockBody(PassBody); 253 inputRequest->setBodyPassed();
260 } 254 }
261 255
262 // "32. Return |r|." 256 // "32. Return |r|."
263 return r; 257 return r;
264 } 258 }
265 259
266 Request* Request::create(ScriptState* scriptState, const RequestInfo& input, con st Dictionary& init, ExceptionState& exceptionState) 260 Request* Request::create(ScriptState* scriptState, const RequestInfo& input, con st Dictionary& init, ExceptionState& exceptionState)
267 { 261 {
268 ASSERT(!input.isNull()); 262 ASSERT(!input.isNull());
269 if (input.isUSVString()) 263 if (input.isUSVString())
(...skipping 16 matching lines...) Expand all
286 return create(scriptState, input, Dictionary(), exceptionState); 280 return create(scriptState, input, Dictionary(), exceptionState);
287 } 281 }
288 282
289 Request* Request::create(ScriptState* scriptState, Request* input, const Diction ary& init, ExceptionState& exceptionState) 283 Request* Request::create(ScriptState* scriptState, Request* input, const Diction ary& init, ExceptionState& exceptionState)
290 { 284 {
291 return createRequestWithRequestOrString(scriptState, input, String(), Reques tInit(scriptState->executionContext(), init, exceptionState), exceptionState); 285 return createRequestWithRequestOrString(scriptState, input, String(), Reques tInit(scriptState->executionContext(), init, exceptionState), exceptionState);
292 } 286 }
293 287
294 Request* Request::create(ExecutionContext* context, FetchRequestData* request) 288 Request* Request::create(ExecutionContext* context, FetchRequestData* request)
295 { 289 {
296 Request* r = new Request(context, request); 290 return new Request(context, request);
297 r->suspendIfNeeded();
298 return r;
299 } 291 }
300 292
301 Request::Request(ExecutionContext* context, FetchRequestData* request) 293 Request::Request(ExecutionContext* context, FetchRequestData* request)
302 : Body(context) 294 : Body(context)
303 , m_request(request) 295 , m_request(request)
304 , m_headers(Headers::create(m_request->headerList())) 296 , m_headers(Headers::create(m_request->headerList()))
305 { 297 {
306 m_headers->setGuard(Headers::RequestGuard); 298 m_headers->setGuard(Headers::RequestGuard);
307
308 refreshBody();
309 } 299 }
310 300
311 Request::Request(ExecutionContext* context, FetchRequestData* request, Headers* headers) 301 Request::Request(ExecutionContext* context, FetchRequestData* request, Headers* headers)
312 : Body(context) , m_request(request) , m_headers(headers) 302 : Body(context) , m_request(request) , m_headers(headers) {}
313 {
314 refreshBody();
315 }
316 303
317 Request* Request::create(ExecutionContext* context, const WebServiceWorkerReques t& webRequest) 304 Request* Request::create(ExecutionContext* context, const WebServiceWorkerReques t& webRequest)
318 { 305 {
319 Request* r = new Request(context, webRequest); 306 return new Request(context, webRequest);
320 r->suspendIfNeeded();
321 return r;
322 } 307 }
323 308
324 Request::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRe quest) 309 Request::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRe quest)
325 : Body(context) 310 : Body(context)
326 , m_request(FetchRequestData::create(context, webRequest)) 311 , m_request(FetchRequestData::create(context, webRequest))
327 , m_headers(Headers::create(m_request->headerList())) 312 , m_headers(Headers::create(m_request->headerList()))
328 { 313 {
329 m_headers->setGuard(Headers::RequestGuard); 314 m_headers->setGuard(Headers::RequestGuard);
330
331 refreshBody();
332 } 315 }
333 316
334 String Request::method() const 317 String Request::method() const
335 { 318 {
336 // "The method attribute's getter must return request's method." 319 // "The method attribute's getter must return request's method."
337 return m_request->method(); 320 return m_request->method();
338 } 321 }
339 322
340 KURL Request::url() const 323 KURL Request::url() const
341 { 324 {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 return ""; 453 return "";
471 } 454 }
472 455
473 Request* Request::clone(ExceptionState& exceptionState) 456 Request* Request::clone(ExceptionState& exceptionState)
474 { 457 {
475 if (bodyUsed()) { 458 if (bodyUsed()) {
476 exceptionState.throwTypeError("Request body is already used"); 459 exceptionState.throwTypeError("Request body is already used");
477 return nullptr; 460 return nullptr;
478 } 461 }
479 462
480 if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream())
481 m_request->setBuffer(buffer->leakBuffer());
482
483 FetchRequestData* request = m_request->clone(executionContext()); 463 FetchRequestData* request = m_request->clone(executionContext());
484 Headers* headers = Headers::create(request->headerList()); 464 Headers* headers = Headers::create(request->headerList());
485 headers->setGuard(m_headers->guard()); 465 headers->setGuard(m_headers->guard());
486 Request* r = new Request(executionContext(), request, headers); 466 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 } 467 }
494 468
495 FetchRequestData* Request::passRequestData() 469 FetchRequestData* Request::passRequestData()
496 { 470 {
497 ASSERT(!bodyUsed()); 471 ASSERT(!bodyUsed());
472 setBodyPassed();
473 FetchRequestData* newRequestData = m_request->pass(executionContext());
474 return newRequestData;
475 }
498 476
499 if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream()) 477 bool Request::hasBody() const
500 m_request->setBuffer(buffer->leakBuffer()); 478 {
501 479 return bodyBuffer()->hasBody();
502 lockBody(PassBody);
503 FetchRequestData* newRequestData = m_request->pass(executionContext());
504 refreshBody();
505 return newRequestData;
506 } 480 }
507 481
508 void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webReques t) const 482 void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webReques t) const
509 { 483 {
510 webRequest.setMethod(method()); 484 webRequest.setMethod(method());
511 webRequest.setRequestContext(m_request->context()); 485 webRequest.setRequestContext(m_request->context());
512 // This strips off the fragment part. 486 // This strips off the fragment part.
513 webRequest.setURL(url()); 487 webRequest.setURL(url());
514 488
515 const FetchHeaderList* headerList = m_headers->headerList(); 489 const FetchHeaderList* headerList = m_headers->headerList();
516 for (size_t i = 0, size = headerList->size(); i < size; ++i) { 490 for (size_t i = 0, size = headerList->size(); i < size; ++i) {
517 const FetchHeaderList::Header& header = headerList->entry(i); 491 const FetchHeaderList::Header& header = headerList->entry(i);
518 webRequest.appendHeader(header.first, header.second); 492 webRequest.appendHeader(header.first, header.second);
519 } 493 }
520 494
521 webRequest.setReferrer(m_request->referrer().referrer().referrer, static_cas t<WebReferrerPolicy>(m_request->referrer().referrer().referrerPolicy)); 495 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 496 // 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. 497 // to plumb this information in to here.
524 } 498 }
525 499
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 500 String Request::mimeType() const
543 { 501 {
544 return m_request->mimeType(); 502 return m_request->mimeType();
545 } 503 }
546 504
547 DEFINE_TRACE(Request) 505 DEFINE_TRACE(Request)
548 { 506 {
549 Body::trace(visitor); 507 Body::trace(visitor);
550 visitor->trace(m_request); 508 visitor->trace(m_request);
551 visitor->trace(m_headers); 509 visitor->trace(m_headers);
552 } 510 }
553 511
554 } // namespace blink 512 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/fetch/Request.h ('k') | Source/modules/fetch/Response.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698