WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
127050
[XHR] Ensure response return null when error flag is set for blob and arraybuffer
https://bugs.webkit.org/show_bug.cgi?id=127050
Summary
[XHR] Ensure response return null when error flag is set for blob and arraybu...
youenn fablet
Reported
2014-01-15 07:45:33 PST
According XHR spec, XHR response getters should return null/empty string when the error flag is set. XHR response getters do not always match that behavior. This happens for instance if response getters are called within ontimeout callbacks and the HTTP response started to be received (error flag is set and xhr state is DONE).
Attachments
First patch
(12.96 KB, patch)
2014-01-15 08:26 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from webkit-ews-07 for mac-mountainlion
(502.67 KB, application/zip)
2014-01-15 09:11 PST
,
Build Bot
no flags
Details
Archive of layout-test-results from webkit-ews-13 for mac-mountainlion-wk2
(466.34 KB, application/zip)
2014-01-15 09:19 PST
,
Build Bot
no flags
Details
Fixing failing test
(14.84 KB, patch)
2014-01-15 09:31 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
factorize doneWithoutError check
(16.19 KB, patch)
2014-01-16 03:23 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
fixed compilation error
(16.55 KB, patch)
2014-01-16 06:54 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Readded precondition in responseXML
(16.49 KB, patch)
2014-01-16 07:58 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Fixed typo
(16.49 KB, patch)
2014-01-16 08:24 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Made tests more robust
(16.95 KB, patch)
2014-01-27 05:19 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Limiting change to arraybuffer and blob
(16.38 KB, patch)
2014-01-29 11:37 PST
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Show Obsolete
(7)
View All
Add attachment
proposed patch, testcase, etc.
youenn fablet
Comment 1
2014-01-15 08:26:15 PST
Created
attachment 221270
[details]
First patch
Build Bot
Comment 2
2014-01-15 09:11:40 PST
Comment on
attachment 221270
[details]
First patch
Attachment 221270
[details]
did not pass mac-ews (mac): Output:
http://webkit-queues.appspot.com/results/5314705006526464
New failing tests: fast/files/xhr-response-blob.html
Build Bot
Comment 3
2014-01-15 09:11:41 PST
Created
attachment 221272
[details]
Archive of layout-test-results from webkit-ews-07 for mac-mountainlion The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: webkit-ews-07 Port: mac-mountainlion Platform: Mac OS X 10.8.5
Build Bot
Comment 4
2014-01-15 09:19:33 PST
Comment on
attachment 221270
[details]
First patch
Attachment 221270
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://webkit-queues.appspot.com/results/6184651169202176
New failing tests: fast/files/xhr-response-blob.html
Build Bot
Comment 5
2014-01-15 09:19:35 PST
Created
attachment 221274
[details]
Archive of layout-test-results from webkit-ews-13 for mac-mountainlion-wk2 The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews. Bot: webkit-ews-13 Port: mac-mountainlion-wk2 Platform: Mac OS X 10.8.5
youenn fablet
Comment 6
2014-01-15 09:31:42 PST
Created
attachment 221277
[details]
Fixing failing test
Alexey Proskuryakov
Comment 7
2014-01-15 15:39:53 PST
Comment on
attachment 221277
[details]
Fixing failing test View in context:
https://bugs.webkit.org/attachment.cgi?id=221277&action=review
> Source/WebCore/xml/XMLHttpRequest.cpp:241 > + if (m_error) > + return "";
Hmm, how are we supposed to handle interrupted connections? We would have responseText attribute have the partial text until the error, at which time it duddenly becomes empty. That's strange.
> Source/WebCore/xml/XMLHttpRequest.cpp:327 > + if (!doneWithoutErrors()) > + return nullptr;
Do we now have two places where we essentially null out the response - one here for the ontimeout/onabort case, and another elsewhere for all the cases that already worked correctly? Can they be merged?
> LayoutTests/http/tests/xmlhttprequest/onabort-response-getters.html:8 > + <script src="../../../resources/testharness.js"></script> > + <script src="../../../resources/testharnessreport.js"></script>
Why the relative paths? I think that this should be just "/resources/testharness.js".
> LayoutTests/http/tests/xmlhttprequest/onabort-response-getters.html:17 > + var url = "/resources/load-then-wait.cgi?name=../../../http/tests/xmlhttprequest/" + fileName + "&waitFor=0.1&mimeType=" + mimeType
Also unsure about this deep relative path.
youenn fablet
Comment 8
2014-01-16 02:31:07 PST
(In reply to
comment #7
)
> (From update of
attachment 221277
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=221277&action=review
> > > Source/WebCore/xml/XMLHttpRequest.cpp:241 > > + if (m_error) > > + return ""; > > Hmm, how are we supposed to handle interrupted connections? We would have responseText attribute have the partial text until the error, at which time it duddenly becomes empty. That's strange.
I am not exactly sure to understand which case you are referring to. Can you give details? For usual cases, I do not think the behavior is changed. The response buffer is cleared when m_error is set to true. One potential case where the patch changes the behavior is if a call to xhr.abort() or xhr.open() triggers a window.onload event (as part of cancelling the loader in internalAbort()). Inside the window.onload event callback, the m_error flag is already set to true but the response buffer is not yet cleared. I can see room for improvement in that area (like ensuring that response information remains accessible for the last progress event before the readystatechange DONE event is sent), but that seems like bigger changes than this patch.
> > > Source/WebCore/xml/XMLHttpRequest.cpp:327 > > + if (!doneWithoutErrors()) > > + return nullptr; > > Do we now have two places where we essentially null out the response - one here for the ontimeout/onabort case, and another elsewhere for all the cases that already worked correctly? > > Can they be merged?
We can factorize the doneWithoutError check in JSXMLHttpRequest::response for all responseType values except ResponseTypeDefault and ResponseTypeText. This would let the behavior unchanged but the code would look more closely aligned with the spec. I will upload a new patch accordingly Note that onabort test works without the patch. That may change when fixing abort() behavior, as proposed in
bug 98404
,
attachment 221163
[details]
. ontimeout cases do not work without the patch right now.
> > > LayoutTests/http/tests/xmlhttprequest/onabort-response-getters.html:8 > > + <script src="../../../resources/testharness.js"></script> > > + <script src="../../../resources/testharnessreport.js"></script> > > Why the relative paths? I think that this should be just "/resources/testharness.js".
Right, they should be removed.
> > > LayoutTests/http/tests/xmlhttprequest/onabort-response-getters.html:17 > > + var url = "/resources/load-then-wait.cgi?name=../../../http/tests/xmlhttprequest/" + fileName + "&waitFor=0.1&mimeType=" + mimeType > > Also unsure about this deep relative path.
This is inspired from xmlhttprequest-timeout.js I will remove it as well.
youenn fablet
Comment 9
2014-01-16 03:23:27 PST
Created
attachment 221356
[details]
factorize doneWithoutError check
EFL EWS Bot
Comment 10
2014-01-16 03:27:56 PST
Comment on
attachment 221356
[details]
factorize doneWithoutError check
Attachment 221356
[details]
did not pass efl-ews (efl): Output:
http://webkit-queues.appspot.com/results/5834558519902208
EFL EWS Bot
Comment 11
2014-01-16 03:30:16 PST
Comment on
attachment 221356
[details]
factorize doneWithoutError check
Attachment 221356
[details]
did not pass efl-wk2-ews (efl-wk2): Output:
http://webkit-queues.appspot.com/results/4692406255484928
Build Bot
Comment 12
2014-01-16 03:58:14 PST
Comment on
attachment 221356
[details]
factorize doneWithoutError check
Attachment 221356
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://webkit-queues.appspot.com/results/5478046505107456
Build Bot
Comment 13
2014-01-16 04:10:59 PST
Comment on
attachment 221356
[details]
factorize doneWithoutError check
Attachment 221356
[details]
did not pass mac-ews (mac): Output:
http://webkit-queues.appspot.com/results/5962754502426624
youenn fablet
Comment 14
2014-01-16 06:54:06 PST
Created
attachment 221374
[details]
fixed compilation error
youenn fablet
Comment 15
2014-01-16 07:58:58 PST
Created
attachment 221377
[details]
Readded precondition in responseXML
EFL EWS Bot
Comment 16
2014-01-16 08:04:25 PST
Comment on
attachment 221377
[details]
Readded precondition in responseXML
Attachment 221377
[details]
did not pass efl-ews (efl): Output:
http://webkit-queues.appspot.com/results/4942846872256512
youenn fablet
Comment 17
2014-01-16 08:24:41 PST
Created
attachment 221380
[details]
Fixed typo
youenn fablet
Comment 18
2014-01-27 05:19:20 PST
Created
attachment 222319
[details]
Made tests more robust
Darin Adler
Comment 19
2014-01-27 10:57:40 PST
Comment on
attachment 222319
[details]
Made tests more robust View in context:
https://bugs.webkit.org/attachment.cgi?id=222319&action=review
> Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp:-236 > + default: > + return jsUndefined(); > } > > - return jsUndefined();
Why this change? The point of leaving out the default is that we get a warning from compilers like clang if any enum value does not have a case. By adding a default, that warning is turned off.
> Source/WebCore/xml/XMLHttpRequest.cpp:291 > + ASSERT(m_responseTypeCode == ResponseTypeBlob && doneWithoutErrors());
This should be two assertions, not one. If the assertion fails we’d like to know which half failed. ASSERT(m_responseTypeCode == ResponseTypeBlob); ASSERT(doneWithoutErrors());
> Source/WebCore/xml/XMLHttpRequest.cpp:321 > + ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer && doneWithoutErrors());
Ditto.
Alexey Proskuryakov
Comment 20
2014-01-27 11:02:09 PST
> > Hmm, how are we supposed to handle interrupted connections? We would have responseText attribute have the partial text until the error, at which time it duddenly becomes empty. That's strange.
> I am not exactly sure to understand which case you are referring to. > Can you give details?
Here is the scenario I'm referring to: 1. A load starts. 2. With every onreadystatechange, JS code looks at xhr.responseText, which contains all the data that has been received so far. 3. The server suddenly decides to drop the connection. 4. The error is detected client side. 5. At this point xhr.responseText suddenly becomes empty. This seems weird.
Alexey Proskuryakov
Comment 21
2014-01-27 11:08:01 PST
Comment on
attachment 222319
[details]
Made tests more robust View in context:
https://bugs.webkit.org/attachment.cgi?id=222319&action=review
> LayoutTests/http/tests/xmlhttprequest/onabort-response-getters.html:72 > + runTest("getting XML response within abort event callback", > + "onabort-response-getters.html","text/html", > + function(test, client) {}, > + function(test, client) {assert_true(client.responseXML == null, "xml response must be empty")} > + )
I don't think that this test actually works. Parsing a malformed XML document results in a null responseXML anyway. We'd probably need a test case that has many space characters after the XML, and only abort once the whole XML part has been received.
youenn fablet
Comment 22
2014-01-28 00:15:19 PST
(In reply to
comment #19
)
> (From update of
attachment 222319
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=222319&action=review
> > > Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp:-236 > > + default: > > + return jsUndefined(); > > } > > > > - return jsUndefined(); > > Why this change? The point of leaving out the default is that we get a warning from compilers like clang if any enum value does not have a case. By adding a default, that warning is turned off.
Some plaforms use -Werror -Wswitch, leading to failing builds. That is what happened in
https://bugs.webkit.org/attachment.cgi?id=221356
> > > Source/WebCore/xml/XMLHttpRequest.cpp:291 > > + ASSERT(m_responseTypeCode == ResponseTypeBlob && doneWithoutErrors()); > > This should be two assertions, not one. If the assertion fails we’d like to know which half failed. > > ASSERT(m_responseTypeCode == ResponseTypeBlob); > ASSERT(doneWithoutErrors()); > > > Source/WebCore/xml/XMLHttpRequest.cpp:321 > > + ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer && doneWithoutErrors()); > > Ditto.
OK, I will fix this
youenn fablet
Comment 23
2014-01-28 01:55:12 PST
(In reply to
comment #21
)
> (From update of
attachment 222319
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=222319&action=review
> > > LayoutTests/http/tests/xmlhttprequest/onabort-response-getters.html:72 > > + runTest("getting XML response within abort event callback", > > + "onabort-response-getters.html","text/html", > > + function(test, client) {}, > > + function(test, client) {assert_true(client.responseXML == null, "xml response must be empty")} > > + ) > > I don't think that this test actually works. Parsing a malformed XML document results in a null responseXML anyway. > > We'd probably need a test case that has many space characters after the XML, and only abort once the whole XML part has been received.
I think that the load-then-wait.cgi should already handle that: it sends the whole document and waits some time before ending the response. It is true though that the test may suffer from changes in the sending of progress events. To ensure that the test is actually working, abort() should be called when onprogress event loaded = total.
youenn fablet
Comment 24
2014-01-28 02:20:15 PST
(In reply to
comment #20
)
> > > Hmm, how are we supposed to handle interrupted connections? We would have responseText attribute have the partial text until the error, at which time it duddenly becomes empty. That's strange. > > > I am not exactly sure to understand which case you are referring to. > > Can you give details? > > Here is the scenario I'm referring to: > > 1. A load starts. > 2. With every onreadystatechange, JS code looks at xhr.responseText, which contains all the data that has been received so far. > 3. The server suddenly decides to drop the connection. > 4. The error is detected client side. > 5. At this point xhr.responseText suddenly becomes empty. > > This seems weird.
This is already happening today. In case of a network error, XMLHttpRequest::genericError will probably be called and the response will be cleared before m_error is even set. In that case, the proposed change in XMLHttpRequest::responseText will not change the behavior (responseText will return "" anyway). It will just change the code path. The proposed change will only change the behavior in some specific cases when m_error is set to true and the response is not yet cleared. To ease the review, I will split that change in a different bug.
youenn fablet
Comment 25
2014-01-29 11:37:32 PST
Created
attachment 222587
[details]
Limiting change to arraybuffer and blob
Alexey Proskuryakov
Comment 26
2014-02-05 15:01:15 PST
Comment on
attachment 222587
[details]
Limiting change to arraybuffer and blob View in context:
https://bugs.webkit.org/attachment.cgi?id=222587&action=review
> Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp:193 > + // FIXME: Use CachedAttribute for other types than JSON as well.
I'm not sure why this is something we'd want to do. Other types are pure DOM ones, so caching in XMLHttpRequest is sufficient - and if the returned object has a wrapper already, we'll pick up that wrapper. I see that you only moved this comment, yet it would be good to clarify it.
youenn fablet
Comment 27
2014-02-05 23:10:31 PST
(In reply to
comment #26
)
> (From update of
attachment 222587
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=222587&action=review
> > > Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp:193 > > + // FIXME: Use CachedAttribute for other types than JSON as well. > > I'm not sure why this is something we'd want to do. > > Other types are pure DOM ones, so caching in XMLHttpRequest is sufficient - and if the returned object has a wrapper already, we'll pick up that wrapper. > > I see that you only moved this comment, yet it would be good to clarify it.
I guess that, When responseType is not "default", all response builders could be cleared once the response object is in cache. Response builders are currently cleared for "json", "blob" and "arrayBuffer", but not for "text" and "document". Since the code for caching is already there, this may also slightly reduce code footprint.
WebKit Commit Bot
Comment 28
2014-02-06 01:37:33 PST
Comment on
attachment 222587
[details]
Limiting change to arraybuffer and blob Clearing flags on attachment: 222587 Committed
r163527
: <
http://trac.webkit.org/changeset/163527
>
WebKit Commit Bot
Comment 29
2014-02-06 01:37:36 PST
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug