| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |