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

Unified Diff: Source/modules/fetch/Request.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: (temp) alternative to calling didGetReadable in sync. Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698