Chromium Code Reviews| Index: Source/modules/fetch/Request.cpp |
| diff --git a/Source/modules/fetch/Request.cpp b/Source/modules/fetch/Request.cpp |
| index 82e6f5ad415045af0344498b0e441dcafa50d56b..f9d28bacadf709c16988d60818c1c51c7770a0fe 100644 |
| --- a/Source/modules/fetch/Request.cpp |
| +++ b/Source/modules/fetch/Request.cpp |
| @@ -11,6 +11,8 @@ |
| #include "core/fetch/FetchUtils.h" |
| #include "core/fetch/ResourceLoaderOptions.h" |
| #include "core/loader/ThreadableLoader.h" |
| +#include "modules/fetch/BodyStreamBuffer.h" |
| +#include "modules/fetch/FetchBlobDataConsumerHandle.h" |
| #include "modules/fetch/FetchManager.h" |
| #include "modules/fetch/RequestInit.h" |
| #include "platform/network/HTTPParsers.h" |
| @@ -47,7 +49,7 @@ FetchRequestData* createCopyOfFetchRequestDataForFetch(ScriptState* scriptState, |
| Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Request* inputRequest, const String& inputString, const RequestInit& init, ExceptionState& exceptionState) |
| { |
| // "1. Let |temporaryBody| be null." |
| - RefPtr<BlobDataHandle> temporaryBody; |
| + OwnPtr<DrainingBodyStreamBuffer> temporaryBody = nullptr; |
| if (inputRequest) { |
| // We check bodyUsed even when the body is null in spite of the |
| @@ -67,18 +69,7 @@ Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req |
| exceptionState.throwTypeError("Cannot construct a Request with a Request object that has already been used."); |
| return nullptr; |
| } |
| - if (inputRequest->isBodyConsumed()) { |
| - // Currently the only methods that can consume body data without |
| - // setting 'body passed' flag consume entire body (e.g. text()). |
| - // Thus we can set an empty blob to the new request instead of |
| - // creating a draining stream. |
| - // TODO(yhirano): Fix this once Request.body is introduced. |
| - OwnPtr<BlobData> blobData = BlobData::create(); |
| - blobData->setContentType(inputRequest->blobDataHandle()->type()); |
| - temporaryBody = BlobDataHandle::create(blobData.release(), 0); |
| - } else { |
| - temporaryBody = inputRequest->m_request->blobDataHandle(); |
| - } |
| + temporaryBody = inputRequest->createDrainingStream(); |
|
yhirano
2015/07/03 04:42:28
The spec intends to not mutate |inputRequest|'s bo
hiroshige
2015/07/05 07:30:25
Yes.
I modified the code to remove the side effect
|
| } |
| // "3. Let |request| be |input|'s request, if |input| is a Request object, |
| @@ -235,7 +226,7 @@ Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req |
| // contains no header named `Content-Type`, append |
| // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any |
| // exception." |
| - temporaryBody = init.bodyBlobHandle; |
| + temporaryBody = DrainingBodyStreamBuffer::create(BodyStreamBuffer::create(FetchBlobDataConsumerHandle::create(scriptState->executionContext(), init.bodyBlobHandle)), nullptr); |
| if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Content-Type", exceptionState)) { |
| r->headers()->append("Content-Type", init.bodyBlobHandle->type(), exceptionState); |
| } |
| @@ -244,7 +235,8 @@ Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req |
| } |
| // "29. Set |r|'s body to |temporaryBody|. |
| - r->setBodyBlobHandle(temporaryBody.release()); |
| + if (temporaryBody) |
| + r->setBuffer(temporaryBody->leak()); |
| // "30. Set |r|'s MIME type to the result of extracting a MIME type from |
| // |r|'s request's header list." |
| @@ -256,7 +248,7 @@ Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req |
| // spec. See https://github.com/whatwg/fetch/issues/61 for details. |
| if (inputRequest) { |
| // "1. Set |input|'s body to null." |
| - inputRequest->setBodyBlobHandle(nullptr); |
| + inputRequest->setBuffer(nullptr); |
| // "2. Set |input|'s used flag." |
| inputRequest->lockBody(PassBody); |
| } |
| @@ -306,10 +298,15 @@ Request::Request(ExecutionContext* context, FetchRequestData* request) |
| , m_headers(Headers::create(m_request->headerList())) |
| { |
| m_headers->setGuard(Headers::RequestGuard); |
| + |
| + refreshBody(); |
| } |
| Request::Request(ExecutionContext* context, FetchRequestData* request, Headers* headers) |
| - : Body(context) , m_request(request) , m_headers(headers) { } |
| + : Body(context) , m_request(request) , m_headers(headers) |
| +{ |
| + refreshBody(); |
| +} |
| Request* Request::create(ExecutionContext* context, const WebServiceWorkerRequest& webRequest) |
| { |
| @@ -320,10 +317,12 @@ Request* Request::create(ExecutionContext* context, const WebServiceWorkerReques |
| Request::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRequest) |
| : Body(context) |
| - , m_request(FetchRequestData::create(webRequest)) |
| + , m_request(FetchRequestData::create(context, webRequest)) |
| , m_headers(Headers::create(m_request->headerList())) |
| { |
| m_headers->setGuard(Headers::RequestGuard); |
| + |
| + refreshBody(); |
| } |
| String Request::method() const |
| @@ -465,37 +464,39 @@ String Request::credentials() const |
| return ""; |
| } |
| -Request* Request::clone(ExceptionState& exceptionState) const |
| +Request* Request::clone(ExceptionState& exceptionState) |
| { |
| if (bodyUsed()) { |
| exceptionState.throwTypeError("Request body is already used"); |
| return nullptr; |
| } |
| - FetchRequestData* request = m_request->clone(); |
| - if (blobDataHandle() && isBodyConsumed()) { |
| - // Currently the only methods that can consume body data without |
| - // setting 'body passed' flag consume entire body (e.g. text()). Thus |
| - // we can set an empty blob to the new request instead of creating a |
| - // draining stream. |
| - // TODO(yhirano): Fix this once Request.body is introduced. |
| - OwnPtr<BlobData> blobData = BlobData::create(); |
| - blobData->setContentType(blobDataHandle()->type()); |
| - request->setBlobDataHandle(BlobDataHandle::create(blobData.release(), 0)); |
| - } |
| + if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream()) |
| + m_request->setBuffer(buffer->leak()); |
| + FetchRequestData* request = m_request->clone(executionContext()); |
| Headers* headers = Headers::create(request->headerList()); |
| headers->setGuard(m_headers->guard()); |
| Request* r = new Request(executionContext(), request, headers); |
| r->suspendIfNeeded(); |
| + |
| + // Lock the old body and set |body| property to the new one. |
| + lockBody(); |
| + refreshBody(); |
| return r; |
| } |
| FetchRequestData* Request::passRequestData() |
| { |
| ASSERT(!bodyUsed()); |
| + |
| + if (OwnPtr<DrainingBodyStreamBuffer> buffer = createDrainingStream()) |
| + m_request->setBuffer(buffer->leak()); |
| + |
| lockBody(PassBody); |
| - return m_request->pass(); |
| + FetchRequestData* newRequestData = m_request->pass(executionContext()); |
| + refreshBody(); |
| + return newRequestData; |
| } |
| void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webRequest) const |
| @@ -516,26 +517,20 @@ void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webReques |
| // to plumb this information in to here. |
| } |
| -void Request::setBodyBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) |
| -{ |
| - m_request->setBlobDataHandle(blobDataHandle); |
| - setBody(m_request->blobDataHandle()); |
| -} |
| - |
| -void Request::clearHeaderList() |
| +void Request::setBuffer(BodyStreamBuffer* buffer) |
| { |
| - m_request->headerList()->clearList(); |
| + m_request->setBuffer(buffer); |
| + refreshBody(); |
| } |
| -PassRefPtr<BlobDataHandle> Request::blobDataHandle() const |
| +void Request::refreshBody() |
| { |
| - return m_request->blobDataHandle(); |
| + setBody(m_request->buffer()); |
| } |
| -BodyStreamBuffer* Request::buffer() const |
| +void Request::clearHeaderList() |
| { |
| - // We don't support BodyStreamBuffer for Request yet. |
| - return nullptr; |
| + m_request->headerList()->clearList(); |
| } |
| String Request::mimeType() const |