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

Unified Diff: Source/core/xml/XMLHttpRequest.cpp

Issue 311593002: Reenable optimization on XMLHttpRequest's receive-as-blob functionality (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 7 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
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/xml/XMLHttpRequest.cpp
diff --git a/Source/core/xml/XMLHttpRequest.cpp b/Source/core/xml/XMLHttpRequest.cpp
index 155d442a87685d72eb63d6880596e1f05334d727..2a585245b23d0b254675ac78d083214150baeb33 100644
--- a/Source/core/xml/XMLHttpRequest.cpp
+++ b/Source/core/xml/XMLHttpRequest.cpp
@@ -171,6 +171,7 @@ XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri
, m_timeoutMilliseconds(0)
, m_state(UNSENT)
, m_createdDocument(false)
+ , m_downloadedBlobLength(0)
, m_error(false)
, m_uploadEventsAllowed(true)
, m_uploadComplete(false)
@@ -276,26 +277,26 @@ Document* XMLHttpRequest::responseXML(ExceptionState& exceptionState)
Blob* XMLHttpRequest::responseBlob()
{
ASSERT(m_responseTypeCode == ResponseTypeBlob);
+ ASSERT(!m_binaryResponseBuilder.get());
// We always return null before DONE.
if (m_error || m_state != DONE)
return 0;
if (!m_responseBlob) {
- // FIXME: Once RedirectToFileResourceHandler is fixed in Chromium,
- // re-enable download-to-file optimization introduced by Blink revision
- // 163141.
+ // When responseType is set to "blob", we redirect the downloaded data
+ // to a file-handle directly in the browser process. We get the
+ // file-path from the ResourceResponse directly instead of copying the
+ // bytes between the browser and the renderer.
OwnPtr<BlobData> blobData = BlobData::create();
- size_t size = 0;
- if (m_binaryResponseBuilder.get() && m_binaryResponseBuilder->size() > 0) {
- RefPtr<RawData> rawData = RawData::create();
- size = m_binaryResponseBuilder->size();
- rawData->mutableData()->append(m_binaryResponseBuilder->data(), size);
- blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile);
+ String filePath = m_response.downloadedFilePath();
+ // If we errored out or got no data, we still return a blob, just an
+ // empty one.
+ if (!filePath.isEmpty() && m_downloadedBlobLength) {
+ blobData->appendFile(filePath);
blobData->setContentType(responseMIMEType()); // responseMIMEType defaults to text/xml which may be incorrect.
- m_binaryResponseBuilder.clear();
}
- m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), size));
+ m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength));
}
return m_responseBlob.get();
@@ -854,6 +855,13 @@ void XMLHttpRequest::createRequest(ExceptionState& exceptionState)
// TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303.
resourceLoaderOptions.mixedContentBlockingTreatment = TreatAsPassiveContent;
+ // When responseType is set to "blob", we redirect the downloaded data to a
+ // file-handle directly.
+ if (responseTypeCode() == ResponseTypeBlob) {
+ request.setDownloadToFile(true);
+ resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
+ }
+
m_exceptionCode = 0;
m_error = false;
@@ -977,6 +985,7 @@ void XMLHttpRequest::clearResponse()
m_responseDocument = nullptr;
m_responseBlob = nullptr;
+ m_downloadedBlobLength = 0;
m_responseStream = nullptr;
@@ -1314,6 +1323,8 @@ void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource
void XMLHttpRequest::didReceiveData(const char* data, int len)
{
+ ASSERT(m_responseTypeCode != ResponseTypeBlob);
+
if (m_error)
return;
@@ -1346,7 +1357,7 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
if (useDecoder) {
m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
- } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) {
+ } else if (m_responseTypeCode == ResponseTypeArrayBuffer) {
// Buffer binary data.
if (!m_binaryResponseBuilder)
m_binaryResponseBuilder = SharedBuffer::create();
@@ -1363,6 +1374,29 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
trackProgress(len);
}
+void XMLHttpRequest::didDownloadData(int dataLength)
+{
+ ASSERT(m_responseTypeCode == ResponseTypeBlob);
+
+ if (m_error)
+ return;
+
+ if (m_state < HEADERS_RECEIVED)
+ changeState(HEADERS_RECEIVED);
+
+ if (!dataLength)
+ return;
+
+ // readystatechange event handler may do something to put this XHR in error
+ // state. We need to check m_error again here.
+ if (m_error)
+ return;
+
+ m_downloadedBlobLength += dataLength;
+
+ trackProgress(dataLength);
+}
+
void XMLHttpRequest::handleDidTimeout()
{
WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698