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

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

Issue 1192913007: Change BodyStreamBuffer to be FetchDataConsumerHandle-based and enable backpressure in Fetch API (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase. Created 5 years, 5 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
« no previous file with comments | « Source/modules/fetch/Response.h ('k') | Source/modules/fetch/ResponseTest.cpp » ('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/Response.h" 6 #include "modules/fetch/Response.h"
7 7
8 #include "bindings/core/v8/Dictionary.h" 8 #include "bindings/core/v8/Dictionary.h"
9 #include "bindings/core/v8/ExceptionState.h" 9 #include "bindings/core/v8/ExceptionState.h"
10 #include "core/dom/DOMArrayBuffer.h" 10 #include "core/dom/DOMArrayBuffer.h"
11 #include "core/dom/DOMArrayBufferView.h" 11 #include "core/dom/DOMArrayBufferView.h"
12 #include "core/fileapi/Blob.h" 12 #include "core/fileapi/Blob.h"
13 #include "core/html/DOMFormData.h" 13 #include "core/html/DOMFormData.h"
14 #include "modules/fetch/BodyStreamBuffer.h"
15 #include "modules/fetch/FetchBlobDataConsumerHandle.h"
14 #include "modules/fetch/ResponseInit.h" 16 #include "modules/fetch/ResponseInit.h"
15 #include "platform/network/FormData.h" 17 #include "platform/network/FormData.h"
16 #include "platform/network/HTTPHeaderMap.h" 18 #include "platform/network/HTTPHeaderMap.h"
17 #include "public/platform/WebServiceWorkerResponse.h" 19 #include "public/platform/WebServiceWorkerResponse.h"
18 #include "wtf/RefPtr.h" 20 #include "wtf/RefPtr.h"
19 21
20 namespace blink { 22 namespace blink {
21 23
22 namespace { 24 namespace {
23 25
24 FetchResponseData* createFetchResponseDataFromWebResponse(const WebServiceWorker Response& webResponse) 26 FetchResponseData* createFetchResponseDataFromWebResponse(ExecutionContext* exec utionContext, const WebServiceWorkerResponse& webResponse)
25 { 27 {
26 FetchResponseData* response = 0; 28 FetchResponseData* response = 0;
27 if (200 <= webResponse.status() && webResponse.status() < 300) 29 if (200 <= webResponse.status() && webResponse.status() < 300)
28 response = FetchResponseData::create(); 30 response = FetchResponseData::create();
29 else 31 else
30 response = FetchResponseData::createNetworkErrorResponse(); 32 response = FetchResponseData::createNetworkErrorResponse();
31 33
32 response->setURL(webResponse.url()); 34 response->setURL(webResponse.url());
33 response->setStatus(webResponse.status()); 35 response->setStatus(webResponse.status());
34 response->setStatusMessage(webResponse.statusText()); 36 response->setStatusMessage(webResponse.statusText());
35 37
36 for (HTTPHeaderMap::const_iterator i = webResponse.headers().begin(), end = webResponse.headers().end(); i != end; ++i) { 38 for (HTTPHeaderMap::const_iterator i = webResponse.headers().begin(), end = webResponse.headers().end(); i != end; ++i) {
37 response->headerList()->append(i->key, i->value); 39 response->headerList()->append(i->key, i->value);
38 } 40 }
39 41
40 response->setBlobDataHandle(webResponse.blobDataHandle()); 42 response->replaceBodyStreamBuffer(BodyStreamBuffer::create(FetchBlobDataCons umerHandle::create(executionContext, webResponse.blobDataHandle())));
41 43
42 // Filter the response according to |webResponse|'s ResponseType. 44 // Filter the response according to |webResponse|'s ResponseType.
43 switch (webResponse.responseType()) { 45 switch (webResponse.responseType()) {
44 case WebServiceWorkerResponseTypeBasic: 46 case WebServiceWorkerResponseTypeBasic:
45 response = response->createBasicFilteredResponse(); 47 response = response->createBasicFilteredResponse();
46 break; 48 break;
47 case WebServiceWorkerResponseTypeCORS: 49 case WebServiceWorkerResponseTypeCORS:
48 response = response->createCORSFilteredResponse(); 50 response = response->createCORSFilteredResponse();
49 break; 51 break;
50 case WebServiceWorkerResponseTypeOpaque: 52 case WebServiceWorkerResponseTypeOpaque:
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 if (body) { 200 if (body) {
199 // "1. Let |stream| and |Content-Type| be the result of extracting body. " 201 // "1. Let |stream| and |Content-Type| be the result of extracting body. "
200 // "2. Set |r|'s response's body to |stream|." 202 // "2. Set |r|'s response's body to |stream|."
201 // "3. If |Content-Type| is non-null and |r|'s response's header list 203 // "3. If |Content-Type| is non-null and |r|'s response's header list
202 // contains no header named `Content-Type`, append `Content-Type`/ 204 // contains no header named `Content-Type`, append `Content-Type`/
203 // |Content-Type| to |r|'s response's header list." 205 // |Content-Type| to |r|'s response's header list."
204 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract 206 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
205 // Step 3, Blob: 207 // Step 3, Blob:
206 // "If object's type attribute is not the empty byte sequence, set 208 // "If object's type attribute is not the empty byte sequence, set
207 // Content-Type to its value." 209 // Content-Type to its value."
208 r->m_response->setBlobDataHandle(body->blobDataHandle()); 210 r->m_response->replaceBodyStreamBuffer(BodyStreamBuffer::create(FetchBlo bDataConsumerHandle::create(context, body->blobDataHandle())));
209 r->setBody(body->blobDataHandle()); 211 r->refreshBody();
210 if (!body->type().isEmpty() && !r->m_response->headerList()->has("Conten t-Type")) 212 if (!body->type().isEmpty() && !r->m_response->headerList()->has("Conten t-Type"))
211 r->m_response->headerList()->append("Content-Type", body->type()); 213 r->m_response->headerList()->append("Content-Type", body->type());
212 } 214 }
213 215
214 // "8. Set |r|'s MIME type to the result of extracting a MIME type 216 // "8. Set |r|'s MIME type to the result of extracting a MIME type
215 // from |r|'s response's header list." 217 // from |r|'s response's header list."
216 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType()); 218 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType());
217 219
218 // "9. Return |r|." 220 // "9. Return |r|."
219 return r; 221 return r;
220 } 222 }
221 223
222 Response* Response::create(ExecutionContext* context, FetchResponseData* respons e) 224 Response* Response::create(ExecutionContext* context, FetchResponseData* respons e)
223 { 225 {
224 Response* r = new Response(context, response); 226 Response* r = new Response(context, response);
225 r->suspendIfNeeded(); 227 r->suspendIfNeeded();
226 return r; 228 return r;
227 } 229 }
228 230
229 Response* Response::create(ExecutionContext* context, const WebServiceWorkerResp onse& webResponse) 231 Response* Response::create(ExecutionContext* context, const WebServiceWorkerResp onse& webResponse)
230 { 232 {
231 FetchResponseData* responseData = createFetchResponseDataFromWebResponse(web Response); 233 FetchResponseData* responseData = createFetchResponseDataFromWebResponse(con text, webResponse);
232 Response* r = new Response(context, responseData); 234 Response* r = new Response(context, responseData);
233 r->suspendIfNeeded(); 235 r->suspendIfNeeded();
234 return r; 236 return r;
235 } 237 }
236 238
237 Response* Response::error(ExecutionContext* context) 239 Response* Response::error(ExecutionContext* context)
238 { 240 {
239 FetchResponseData* responseData = FetchResponseData::createNetworkErrorRespo nse(); 241 FetchResponseData* responseData = FetchResponseData::createNetworkErrorRespo nse();
240 Response* r = new Response(context, responseData); 242 Response* r = new Response(context, responseData);
241 r->m_headers->setGuard(Headers::ImmutableGuard); 243 r->m_headers->setGuard(Headers::ImmutableGuard);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 // "The headers attribute's getter must return the associated Headers object ." 322 // "The headers attribute's getter must return the associated Headers object ."
321 return m_headers; 323 return m_headers;
322 } 324 }
323 325
324 Response* Response::clone(ExceptionState& exceptionState) 326 Response* Response::clone(ExceptionState& exceptionState)
325 { 327 {
326 if (bodyUsed()) { 328 if (bodyUsed()) {
327 exceptionState.throwTypeError("Response body is already used"); 329 exceptionState.throwTypeError("Response body is already used");
328 return nullptr; 330 return nullptr;
329 } 331 }
330 if (isBodyConsumed()) {
331 BodyStreamBuffer* drainingStream = createDrainingStream();
332 m_response->replaceBodyStreamBuffer(drainingStream);
333 }
334 332
335 FetchResponseData* response = m_response->clone(); 333 if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream())
334 m_response->replaceBodyStreamBuffer(buffer->leakBuffer());
335
336 FetchResponseData* response = m_response->clone(executionContext());
336 Headers* headers = Headers::create(response->headerList()); 337 Headers* headers = Headers::create(response->headerList());
337 headers->setGuard(m_headers->guard()); 338 headers->setGuard(m_headers->guard());
338 Response* r = new Response(executionContext(), response, headers); 339 Response* r = new Response(executionContext(), response, headers);
339 r->suspendIfNeeded(); 340 r->suspendIfNeeded();
340 341
341 // Lock the old body and set |body| property to the new one. 342 // Lock the old body and set |body| property to the new one.
342 lockBody(); 343 lockBody();
343 refreshBody(); 344 refreshBody();
344 345
345 return r; 346 return r;
(...skipping 23 matching lines...) Expand all
369 } 370 }
370 371
371 Response::Response(ExecutionContext* context, FetchResponseData* response, Heade rs* headers) 372 Response::Response(ExecutionContext* context, FetchResponseData* response, Heade rs* headers)
372 : Body(context) , m_response(response) , m_headers(headers) 373 : Body(context) , m_response(response) , m_headers(headers)
373 { 374 {
374 refreshBody(); 375 refreshBody();
375 } 376 }
376 377
377 bool Response::hasBody() const 378 bool Response::hasBody() const
378 { 379 {
379 return internalBlobDataHandle() || internalBuffer(); 380 return m_response->internalBuffer();
380 } 381 }
381 382
382 PassRefPtr<BlobDataHandle> Response::blobDataHandle() const 383 void* Response::bufferForTest() const
383 {
384 return m_response->blobDataHandle();
385 }
386
387 BodyStreamBuffer* Response::buffer() const
388 { 384 {
389 return m_response->buffer(); 385 return m_response->buffer();
390 } 386 }
391 387
392 String Response::mimeType() const 388 String Response::mimeType() const
393 { 389 {
394 return m_response->mimeType(); 390 return m_response->mimeType();
395 } 391 }
396 392
397 PassRefPtr<BlobDataHandle> Response::internalBlobDataHandle() const 393 void* Response::internalBufferForTest() const
398 {
399 return m_response->internalBlobDataHandle();
400 }
401
402 BodyStreamBuffer* Response::internalBuffer() const
403 { 394 {
404 return m_response->internalBuffer(); 395 return m_response->internalBuffer();
405 } 396 }
406 397
407 String Response::internalMIMEType() const 398 String Response::internalMIMEType() const
408 { 399 {
409 return m_response->internalMIMEType(); 400 return m_response->internalMIMEType();
410 } 401 }
411 402
403 PassOwnPtr<DrainingBodyStreamBuffer> Response::createInternalDrainingStream()
404 {
405 if (BodyStreamBuffer* buffer = m_response->internalBuffer()) {
406 if (buffer == m_response->buffer())
407 return createDrainingStream();
408 return DrainingBodyStreamBuffer::create(buffer, nullptr);
409 }
410 return nullptr;
411 }
412
412 void Response::refreshBody() 413 void Response::refreshBody()
413 { 414 {
414 if (m_response->buffer()) 415 setBody(m_response->buffer());
415 setBody(m_response->buffer());
416 else
417 setBody(m_response->blobDataHandle());
418 } 416 }
419 417
420 DEFINE_TRACE(Response) 418 DEFINE_TRACE(Response)
421 { 419 {
422 Body::trace(visitor); 420 Body::trace(visitor);
423 visitor->trace(m_response); 421 visitor->trace(m_response);
424 visitor->trace(m_headers); 422 visitor->trace(m_headers);
425 } 423 }
426 424
427 } // namespace blink 425 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/fetch/Response.h ('k') | Source/modules/fetch/ResponseTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698