Closed
Bug 687087
Opened 13 years ago
Closed 13 years ago
Support "chunked" data for XMLHttpRequest
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
RESOLVED
FIXED
mozilla9
People
(Reporter: sicking, Assigned: sicking)
References
Details
(Keywords: dev-doc-needed)
Attachments
(4 files, 1 obsolete file)
17.42 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
21.69 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
6.32 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
19.92 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
When downloading a large resource with XHR we currently load the whole thing into memory. If someone is able to incrementally consume the data, it would be nice to allow exposing only the data that was downloaded since the last progress event. For text data this is a bit extra complicated because at the time when we fire the progress event we might have only received half a surrogate. Anyhow, I've implemented this!
Assignee | ||
Comment 1•13 years ago
|
||
In order to keep things simple for the web author, we should let them only do data processing during the "progress" event when doing chunked download. To enable this we need to fire a "progress" event right before "load" if we've received data since the last "progress" event (which then presumably happened less than 50ms ago). This patch also cleans up how we track the total number of bytes downloaded. Currently we do this by measuring mResponseBody.Length(), however that doesn't work when responseType is "document" or "blob". I.e. for those types we currently have the wrong event.loaded values. Finally, this patch makes us fire the "progress" event from OnDataAvailable rather than OnProgress. This means that we can be more sure to have updated the .response* properties before firing the "progress" event. It also means that we don't have to worry about background requests which don't fire OnProgress for the download "progress" event. (The upload "progress" events are still a problem though).
Assignee: nobody → jonas
Attachment #560580 -
Flags: review?(Olli.Pettay)
Assignee | ||
Comment 2•13 years ago
|
||
We currently do this silly thing where the .responseText getter charset-decode *all* downloaded data if we've received *any* data since the last time .responseText was accessed. This is *sometimes* needed if we're also parsing into a document and the document-parser has detected a new charset since the last time .responseText was accessed. But this not the common case. This patch makes us continuously pass data to the charset decoder as we download it in the cases when we're not also parsing a document. When we're parsing a document we lazily pass things to the charset decoder whenever .responseText is accessed. And we only pass *all* data to the decoder if the charset has actually changed since last time .responseText was accessed.
Attachment #560586 -
Flags: review?(Olli.Pettay)
Assignee | ||
Comment 3•13 years ago
|
||
Also contains tests!! Lots of tests!
Attachment #560588 -
Flags: review?(Olli.Pettay)
Assignee | ||
Comment 4•13 years ago
|
||
We should throw if you try to set .responseType to any of the chunked types for sync XHR. This also improves our tests for moz-json since i had to change that test anyway to test the new throwing behavior.
Attachment #560747 -
Flags: review?(Olli.Pettay)
Assignee | ||
Comment 5•13 years ago
|
||
The previous version had a merge error with the JSON support patch. The only code change is to check for responseType=JSON when detecting charset and when receiving data. I also improved the tests to test progress events for responseType=""
Attachment #560586 -
Attachment is obsolete: true
Attachment #560586 -
Flags: review?(Olli.Pettay)
Attachment #560748 -
Flags: review?(Olli.Pettay)
Comment 6•13 years ago
|
||
Comment on attachment 560580 [details] [diff] [review] Part 1: Always fire "progress" event before load > // Reset responseBody > mResponseBody.Truncate(); > mResponseBodyUnicode.SetIsVoid(PR_TRUE); > mResponseBlob = nsnull; > mResultArrayBuffer = nsnull; >+ mLoadTransferred = 0; Could put this also to nsXMLHttpRequest::Send where we reset other things. Or, actually, would be good to have some ResetVariables() -like method which could be called in different places like in Abort, Send etc-
Attachment #560580 -
Flags: review?(Olli.Pettay) → review+
Comment 7•13 years ago
|
||
Comment on attachment 560747 [details] [diff] [review] Part 3b: Forbid chunked for sync XHR >diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp >--- a/content/base/src/nsXMLHttpRequest.cpp >+++ b/content/base/src/nsXMLHttpRequest.cpp >@@ -960,18 +960,24 @@ NS_IMETHODIMP nsXMLHttpRequest::SetRespo > mResponseType = XML_HTTP_RESPONSE_TYPE_BLOB; > } else if (aResponseType.EqualsLiteral("document")) { > mResponseType = XML_HTTP_RESPONSE_TYPE_DOCUMENT; > } else if (aResponseType.EqualsLiteral("text")) { > mResponseType = XML_HTTP_RESPONSE_TYPE_TEXT; > } else if (aResponseType.EqualsLiteral("moz-json")) { > mResponseType = XML_HTTP_RESPONSE_TYPE_JSON; > } else if (aResponseType.EqualsLiteral("moz-chunked-text")) { >+ if (!(mState & XML_HTTP_REQUEST_ASYNC)) { >+ return NS_ERROR_FAILURE; >+ } > mResponseType = XML_HTTP_RESPONSE_TYPE_CHUNKED_TEXT; > } else if (aResponseType.EqualsLiteral("moz-chunked-arraybuffer")) { >+ if (!(mState & XML_HTTP_REQUEST_ASYNC)) { >+ return NS_ERROR_FAILURE; >+ } I think NS_ERROR_DOM_INVALID_STATE_ERR would be better.
Attachment #560747 -
Flags: review?(Olli.Pettay) → review+
Comment 8•13 years ago
|
||
Comment on attachment 560748 [details] [diff] [review] Part 2: Improve text handling in XHR >+ // Decoder used for decoding into mResponseText >+ // Only used for DEFAULT and TEXT responseTypes. >+ nsCOMPtr<nsIUnicodeDecoder> mDecoder; Also, JSON, right? Could you add some comments how "we might have only received half a surrogate" case is handled. Since NS_OK_UDEC_MOREINPUT/NS_PARTIAL_MORE_INPUT wasn't in the source code, it took some time to figure out that the case is actually handled. (I hope there are tests for that. I haven't yet looked at them.)
Attachment #560748 -
Flags: review?(Olli.Pettay) → review+
Comment 9•13 years ago
|
||
Comment on attachment 560588 [details] [diff] [review] Part 3: Support chunked data > nsString str; > rv = GetResponseText(str); > if (NS_FAILED(rv)) return rv; >- nsStringBuffer* buf; >- *aResult = XPCStringConvert::ReadableToJSVal(aCx, str, &buf); >- if (buf) { >- str.ForgetSharedBuffer(); >+ if (str.IsVoid()) { >+ *aResult = JSVAL_NULL; >+ } >+ else { } else { Same also elsewhere. This all will make XHR look more like EventSource, though, the use cases are quite different. r=me >+ yield; Tests using yield are hard to review. rs=for the tests.
Attachment #560588 -
Flags: review?(Olli.Pettay) → review+
Comment 10•13 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/b2fb48fdb1e7 https://hg.mozilla.org/mozilla-central/rev/192254be8f97 https://hg.mozilla.org/mozilla-central/rev/dee5413476bb
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla9
Updated•13 years ago
|
Keywords: dev-doc-needed
Comment 11•13 years ago
|
||
Is there a spec for this feature?
Assignee | ||
Comment 12•13 years ago
|
||
I proposed it to the webapps list and got generally good feedback, but no feedback from the editor yet. I'll write a new email detailing the various mozilla extensions to .responseType
Comment 13•13 years ago
|
||
I did give feedback, asking about better interoperability on existing features before implementing new features. Microsoft meanwhile also proposed a Stream API of sorts.
Comment 14•13 years ago
|
||
Documentation updated: https://developer.mozilla.org/en/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress And mentioned on Firefox 9 for developers.
Keywords: dev-doc-needed → dev-doc-complete
Comment 15•12 years ago
|
||
If I understand correctly, the feature introduced here is the 2 new "moz-chunked-text" and "moz-chunked-arraybuffer" values for the responseType property. I don't see how https://developer.mozilla.org/index.php?title=en/DOM/XMLHttpRequest/Using_XMLHttpRequest&action=diff&revision=106&diff=107 (comment 14) documents it. Setting the dev-doc-needed keyword again. My understanding is that when setting responseType to any of these values, the responseText and reponseXML properties become unusable and one should instead use the response property only during progress events, and the response property contains only the data that has been received since the last progress event, instead of the whole response text. This is mostly a guess (I hope it is correct!) based on what I understood of the code, I would have liked to find some confirmation in the documentation (+ it would have saved time!).
Keywords: dev-doc-complete → dev-doc-needed
Assignee | ||
Comment 16•12 years ago
|
||
responseXML is indeed disabled. But for "moz-chunked-text" reponseText has the same value as. response. Note that for moz-chunked-text and moz-chunked-arraybuffer you can only access. response during "progress" events.
Updated•5 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•