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

Side by Side Diff: Source/modules/fetch/Response.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/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" 14 #include "modules/fetch/BodyStreamBuffer.h"
15 #include "modules/fetch/FetchBlobDataConsumerHandle.h" 15 #include "modules/fetch/FetchBlobDataConsumerHandle.h"
16 #include "modules/fetch/ResponseInit.h" 16 #include "modules/fetch/ResponseInit.h"
17 #include "platform/network/FormData.h" 17 #include "platform/network/FormData.h"
18 #include "platform/network/HTTPHeaderMap.h" 18 #include "platform/network/HTTPHeaderMap.h"
19 #include "public/platform/WebServiceWorkerResponse.h" 19 #include "public/platform/WebServiceWorkerResponse.h"
20 #include "wtf/RefPtr.h" 20 #include "wtf/RefPtr.h"
21 21
22 namespace blink { 22 namespace blink {
23 23
24 namespace { 24 namespace {
25 25
26 FetchResponseData* createFetchResponseDataFromWebResponse(ExecutionContext* exec utionContext, const WebServiceWorkerResponse& webResponse) 26 FetchResponseData* createFetchResponseDataFromWebResponse(ExecutionContext* exec utionContext, const WebServiceWorkerResponse& webResponse)
27 { 27 {
28 FetchResponseData* response = 0; 28 FetchResponseData* response = nullptr;
29 if (webResponse.status() > 0) 29 if (webResponse.status() > 0)
30 response = FetchResponseData::create(); 30 response = FetchResponseData::create();
31 else 31 else
32 response = FetchResponseData::createNetworkErrorResponse(); 32 response = FetchResponseData::createNetworkErrorResponse();
33 33
34 response->setURL(webResponse.url()); 34 response->setURL(webResponse.url());
35 response->setStatus(webResponse.status()); 35 response->setStatus(webResponse.status());
36 response->setStatusMessage(webResponse.statusText()); 36 response->setStatusMessage(webResponse.statusText());
37 37
38 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) {
39 response->headerList()->append(i->key, i->value); 39 response->headerList()->append(i->key, i->value);
40 } 40 }
41 41
42 response->replaceBodyStreamBuffer(BodyStreamBuffer::create(FetchBlobDataCons umerHandle::create(executionContext, webResponse.blobDataHandle()))); 42 response->replaceBodyStreamBuffer(new BodyStreamBuffer(FetchBlobDataConsumer Handle::create(executionContext, webResponse.blobDataHandle())));
43 43
44 // Filter the response according to |webResponse|'s ResponseType. 44 // Filter the response according to |webResponse|'s ResponseType.
45 switch (webResponse.responseType()) { 45 switch (webResponse.responseType()) {
46 case WebServiceWorkerResponseTypeBasic: 46 case WebServiceWorkerResponseTypeBasic:
47 response = response->createBasicFilteredResponse(); 47 response = response->createBasicFilteredResponse();
48 break; 48 break;
49 case WebServiceWorkerResponseTypeCORS: 49 case WebServiceWorkerResponseTypeCORS:
50 response = response->createCORSFilteredResponse(); 50 response = response->createCORSFilteredResponse();
51 break; 51 break;
52 case WebServiceWorkerResponseTypeOpaque: 52 case WebServiceWorkerResponseTypeOpaque:
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // "2. If |init|'s statusText member does not match the Reason-Phrase 163 // "2. If |init|'s statusText member does not match the Reason-Phrase
164 // token production, throw a TypeError." 164 // token production, throw a TypeError."
165 if (!isValidReasonPhrase(responseInit.statusText)) { 165 if (!isValidReasonPhrase(responseInit.statusText)) {
166 exceptionState.throwTypeError("Invalid statusText"); 166 exceptionState.throwTypeError("Invalid statusText");
167 return 0; 167 return 0;
168 } 168 }
169 169
170 // "3. Let |r| be a new Response object, associated with a new response, 170 // "3. Let |r| be a new Response object, associated with a new response,
171 // Headers object, and Body object." 171 // Headers object, and Body object."
172 Response* r = new Response(context); 172 Response* r = new Response(context);
173 r->suspendIfNeeded();
174 173
175 // "4. Set |r|'s response's status to |init|'s status member." 174 // "4. Set |r|'s response's status to |init|'s status member."
176 r->m_response->setStatus(responseInit.status); 175 r->m_response->setStatus(responseInit.status);
177 176
178 // "5. Set |r|'s response's status message to |init|'s statusText member." 177 // "5. Set |r|'s response's status message to |init|'s statusText member."
179 r->m_response->setStatusMessage(AtomicString(responseInit.statusText)); 178 r->m_response->setStatusMessage(AtomicString(responseInit.statusText));
180 179
181 // "6. If |init|'s headers member is present, run these substeps:" 180 // "6. If |init|'s headers member is present, run these substeps:"
182 if (responseInit.headers) { 181 if (responseInit.headers) {
183 // "1. Empty |r|'s response's header list." 182 // "1. Empty |r|'s response's header list."
(...skipping 16 matching lines...) Expand all
200 if (body) { 199 if (body) {
201 // "1. Let |stream| and |Content-Type| be the result of extracting body. " 200 // "1. Let |stream| and |Content-Type| be the result of extracting body. "
202 // "2. Set |r|'s response's body to |stream|." 201 // "2. Set |r|'s response's body to |stream|."
203 // "3. If |Content-Type| is non-null and |r|'s response's header list 202 // "3. If |Content-Type| is non-null and |r|'s response's header list
204 // contains no header named `Content-Type`, append `Content-Type`/ 203 // contains no header named `Content-Type`, append `Content-Type`/
205 // |Content-Type| to |r|'s response's header list." 204 // |Content-Type| to |r|'s response's header list."
206 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract 205 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
207 // Step 3, Blob: 206 // Step 3, Blob:
208 // "If object's type attribute is not the empty byte sequence, set 207 // "If object's type attribute is not the empty byte sequence, set
209 // Content-Type to its value." 208 // Content-Type to its value."
210 r->m_response->replaceBodyStreamBuffer(BodyStreamBuffer::create(FetchBlo bDataConsumerHandle::create(context, body->blobDataHandle()))); 209 r->m_response->replaceBodyStreamBuffer(new BodyStreamBuffer(FetchBlobDat aConsumerHandle::create(context, body->blobDataHandle())));
211 r->refreshBody();
212 if (!body->type().isEmpty() && !r->m_response->headerList()->has("Conten t-Type")) 210 if (!body->type().isEmpty() && !r->m_response->headerList()->has("Conten t-Type"))
213 r->m_response->headerList()->append("Content-Type", body->type()); 211 r->m_response->headerList()->append("Content-Type", body->type());
214 } 212 }
215 213
216 // "8. Set |r|'s MIME type to the result of extracting a MIME type 214 // "8. Set |r|'s MIME type to the result of extracting a MIME type
217 // from |r|'s response's header list." 215 // from |r|'s response's header list."
218 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType()); 216 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType());
219 217
220 // "9. Return |r|." 218 // "9. Return |r|."
221 return r; 219 return r;
222 } 220 }
223 221
224 Response* Response::create(ExecutionContext* context, FetchResponseData* respons e) 222 Response* Response::create(ExecutionContext* context, FetchResponseData* respons e)
225 { 223 {
226 Response* r = new Response(context, response); 224 return new Response(context, response);
227 r->suspendIfNeeded();
228 return r;
229 } 225 }
230 226
231 Response* Response::create(ExecutionContext* context, const WebServiceWorkerResp onse& webResponse) 227 Response* Response::create(ExecutionContext* context, const WebServiceWorkerResp onse& webResponse)
232 { 228 {
233 FetchResponseData* responseData = createFetchResponseDataFromWebResponse(con text, webResponse); 229 FetchResponseData* responseData = createFetchResponseDataFromWebResponse(con text, webResponse);
234 Response* r = new Response(context, responseData); 230 return new Response(context, responseData);
235 r->suspendIfNeeded();
236 return r;
237 } 231 }
238 232
239 Response* Response::error(ExecutionContext* context) 233 Response* Response::error(ExecutionContext* context)
240 { 234 {
241 FetchResponseData* responseData = FetchResponseData::createNetworkErrorRespo nse(); 235 FetchResponseData* responseData = FetchResponseData::createNetworkErrorRespo nse();
242 Response* r = new Response(context, responseData); 236 Response* r = new Response(context, responseData);
243 r->m_headers->setGuard(Headers::ImmutableGuard); 237 r->m_headers->setGuard(Headers::ImmutableGuard);
244 r->suspendIfNeeded();
245 return r; 238 return r;
246 } 239 }
247 240
248 Response* Response::redirect(ExecutionContext* context, const String& url, unsig ned short status, ExceptionState& exceptionState) 241 Response* Response::redirect(ExecutionContext* context, const String& url, unsig ned short status, ExceptionState& exceptionState)
249 { 242 {
250 KURL parsedURL = context->completeURL(url); 243 KURL parsedURL = context->completeURL(url);
251 if (!parsedURL.isValid()) { 244 if (!parsedURL.isValid()) {
252 exceptionState.throwTypeError("Failed to parse URL from " + url); 245 exceptionState.throwTypeError("Failed to parse URL from " + url);
253 return nullptr; 246 return nullptr;
254 } 247 }
255 248
256 if (status != 301 && status != 302 && status != 303 && status != 307 && stat us != 308) { 249 if (status != 301 && status != 302 && status != 303 && status != 307 && stat us != 308) {
257 exceptionState.throwRangeError("Invalid status code"); 250 exceptionState.throwRangeError("Invalid status code");
258 return nullptr; 251 return nullptr;
259 } 252 }
260 253
261 Response* r = new Response(context); 254 Response* r = new Response(context);
262 r->suspendIfNeeded();
263 r->m_headers->setGuard(Headers::ImmutableGuard); 255 r->m_headers->setGuard(Headers::ImmutableGuard);
264 r->m_response->setStatus(status); 256 r->m_response->setStatus(status);
265 r->m_response->headerList()->set("Location", parsedURL); 257 r->m_response->headerList()->set("Location", parsedURL);
266 258
267 return r; 259 return r;
268 } 260 }
269 261
270 String Response::type() const 262 String Response::type() const
271 { 263 {
272 // "The type attribute's getter must return response's type." 264 // "The type attribute's getter must return response's type."
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 return m_headers; 315 return m_headers;
324 } 316 }
325 317
326 Response* Response::clone(ExceptionState& exceptionState) 318 Response* Response::clone(ExceptionState& exceptionState)
327 { 319 {
328 if (bodyUsed()) { 320 if (bodyUsed()) {
329 exceptionState.throwTypeError("Response body is already used"); 321 exceptionState.throwTypeError("Response body is already used");
330 return nullptr; 322 return nullptr;
331 } 323 }
332 324
333 if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream())
334 m_response->replaceBodyStreamBuffer(buffer->leakBuffer());
335
336 FetchResponseData* response = m_response->clone(executionContext()); 325 FetchResponseData* response = m_response->clone(executionContext());
337 Headers* headers = Headers::create(response->headerList()); 326 Headers* headers = Headers::create(response->headerList());
338 headers->setGuard(m_headers->guard()); 327 headers->setGuard(m_headers->guard());
339 Response* r = new Response(executionContext(), response, headers); 328 return new Response(executionContext(), response, headers);
340 r->suspendIfNeeded();
341
342 // Lock the old body and set |body| property to the new one.
343 lockBody();
344 refreshBody();
345
346 return r;
347 } 329 }
348 330
349 bool Response::hasPendingActivity() const 331 bool Response::hasPendingActivity() const
350 { 332 {
351 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) 333 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
352 return false; 334 return false;
353 if (m_isInternalDrained) 335 if (internalBodyBuffer()->hasPendingActivity())
354 return true; 336 return true;
355 return Body::hasPendingActivity(); 337 return Body::hasPendingActivity();
356 } 338 }
357 339
358 void Response::populateWebServiceWorkerResponse(WebServiceWorkerResponse& respon se) 340 void Response::populateWebServiceWorkerResponse(WebServiceWorkerResponse& respon se)
359 { 341 {
360 m_response->populateWebServiceWorkerResponse(response); 342 m_response->populateWebServiceWorkerResponse(response);
361 } 343 }
362 344
363 Response::Response(ExecutionContext* context) 345 Response::Response(ExecutionContext* context)
364 : Body(context) 346 : Body(context)
365 , m_response(FetchResponseData::create()) 347 , m_response(FetchResponseData::create())
366 , m_headers(Headers::create(m_response->headerList())) 348 , m_headers(Headers::create(m_response->headerList()))
367 , m_isInternalDrained(false)
368 { 349 {
369 m_headers->setGuard(Headers::ResponseGuard); 350 m_headers->setGuard(Headers::ResponseGuard);
370 } 351 }
371 352
372 Response::Response(ExecutionContext* context, FetchResponseData* response) 353 Response::Response(ExecutionContext* context, FetchResponseData* response)
373 : Body(context) 354 : Body(context)
374 , m_response(response) 355 , m_response(response)
375 , m_headers(Headers::create(m_response->headerList())) 356 , m_headers(Headers::create(m_response->headerList()))
376 , m_isInternalDrained(false)
377 { 357 {
378 m_headers->setGuard(Headers::ResponseGuard); 358 m_headers->setGuard(Headers::ResponseGuard);
379
380 refreshBody();
381 } 359 }
382 360
383 Response::Response(ExecutionContext* context, FetchResponseData* response, Heade rs* headers) 361 Response::Response(ExecutionContext* context, FetchResponseData* response, Heade rs* headers)
384 : Body(context) , m_response(response) , m_headers(headers), m_isInternalDra ined(false) 362 : Body(context) , m_response(response) , m_headers(headers) {}
385 {
386 refreshBody();
387 }
388 363
389 bool Response::hasBody() const 364 bool Response::hasBody() const
390 { 365 {
391 return m_response->internalBuffer(); 366 return m_response->internalBuffer()->hasBody();
392 }
393
394 void* Response::bufferForTest() const
395 {
396 return m_response->buffer();
397 } 367 }
398 368
399 String Response::mimeType() const 369 String Response::mimeType() const
400 { 370 {
401 return m_response->mimeType(); 371 return m_response->mimeType();
402 } 372 }
403 373
404 void* Response::internalBufferForTest() const
405 {
406 return m_response->internalBuffer();
407 }
408
409 String Response::internalMIMEType() const 374 String Response::internalMIMEType() const
410 { 375 {
411 return m_response->internalMIMEType(); 376 return m_response->internalMIMEType();
412 } 377 }
413 378
414 PassOwnPtr<DrainingBodyStreamBuffer> Response::createInternalDrainingStream()
415 {
416 if (BodyStreamBuffer* buffer = m_response->internalBuffer()) {
417 if (buffer == m_response->buffer())
418 return createDrainingStream();
419 m_isInternalDrained = true;
420 return DrainingBodyStreamBuffer::create(buffer, this);
421 }
422 return nullptr;
423 }
424
425 void Response::didFetchDataLoadFinishedFromDrainingStream()
426 {
427 ASSERT(m_isInternalDrained);
428 m_isInternalDrained = false;
429 }
430
431 void Response::refreshBody()
432 {
433 setBody(m_response->buffer());
434 }
435
436 DEFINE_TRACE(Response) 379 DEFINE_TRACE(Response)
437 { 380 {
438 Body::trace(visitor); 381 Body::trace(visitor);
439 visitor->trace(m_response); 382 visitor->trace(m_response);
440 visitor->trace(m_headers); 383 visitor->trace(m_headers);
441 } 384 }
442 385
443 } // namespace blink 386 } // 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