diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 2904ebe88355..f15b00d98350 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -1690,7 +1690,7 @@ nsXMLHttpRequest::StreamReaderFunc(nsIInputStream* in, return rv; } -void nsXMLHttpRequest::CreateResponseBlob(nsIRequest *request) +bool nsXMLHttpRequest::CreateResponseBlob(nsIRequest *request) { nsCOMPtr file; nsCOMPtr cc(do_QueryInterface(request)); @@ -1702,18 +1702,27 @@ void nsXMLHttpRequest::CreateResponseBlob(nsIRequest *request) fc->GetFile(getter_AddRefs(file)); } } + bool fromFile = false; if (file) { nsCAutoString contentType; mChannel->GetContentType(contentType); nsCOMPtr cacheToken; if (cc) { cc->GetCacheToken(getter_AddRefs(cacheToken)); + // We need to call IsFromCache to determine whether the response is + // fully cached (i.e. whether we can skip reading the response). + cc->IsFromCache(&fromFile); + } else { + // If the response is coming from the local resource, we can skip + // reading the response unconditionally. + fromFile = true; } mResponseBlob = new nsDOMFileFile(file, NS_ConvertASCIItoUTF16(contentType), cacheToken); mResponseBody.Truncate(); } + return fromFile; } NS_IMETHODIMP @@ -1727,12 +1736,17 @@ nsXMLHttpRequest::OnDataAvailable(nsIRequest *request, NS_ABORT_IF_FALSE(mContext.get() == ctxt,"start context different from OnDataAvailable context"); - if (mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB && !mResponseBlob) { - CreateResponseBlob(request); - } - mProgressSinceLastProgressEvent = true; + if (mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB && !mResponseBlob) { + if (CreateResponseBlob(request)) { + // We don't have to read from the local file for the blob response + mResponseBlob->GetSize(&mLoadTransferred); + ChangeState(XML_HTTP_REQUEST_LOADING); + return request->Cancel(NS_OK); + } + } + PRUint32 totalRead; nsresult rv = inStr->ReadSegments(nsXMLHttpRequest::StreamReaderFunc, (void*)this, count, &totalRead); diff --git a/content/base/src/nsXMLHttpRequest.h b/content/base/src/nsXMLHttpRequest.h index 57d756a7c5f7..9412b03deeca 100644 --- a/content/base/src/nsXMLHttpRequest.h +++ b/content/base/src/nsXMLHttpRequest.h @@ -217,7 +217,7 @@ protected: PRUint32 *writeCount); nsresult CreateResponseParsedJSON(JSContext* aCx); nsresult CreateResponseArrayBuffer(JSContext* aCx); - void CreateResponseBlob(nsIRequest *request); + bool CreateResponseBlob(nsIRequest *request); // Change the state of the object with this. The broadcast argument // determines if the onreadystatechange listener should be called. nsresult ChangeState(PRUint32 aState, bool aBroadcast = true);