Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

window.stop() should fire abort events on XMLHttpRequest asynchronously #14406

Merged
merged 1 commit into from
May 31, 2023

Conversation

cdumez
Copy link
Contributor

@cdumez cdumez commented May 26, 2023

02e1d3e

window.stop() should fire abort events on XMLHttpRequest asynchronously
https://bugs.webkit.org/show_bug.cgi?id=257397

Reviewed by Darin Adler and Youenn Fablet.

window.stop() should fire an abort event on XMLHttpRequest asynchronously, to match
the behavior of Blink and Gecko.

It should schedule a asynchronous task, which should get cancelled if the
JavaScript calls `open()` on the XMLHttpRequest again. This is covered by WPT
tests.

* LayoutTests/imported/w3c/web-platform-tests/xhr/abort-after-stop.window-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/open-after-stop.window-expected.txt:
Rebaseline tests now that more checks are passing.

* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-basic-cors-not-enabled-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-basic-cors-not-enabled.htm:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-basic-setrequestheader-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-basic-setrequestheader.htm:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-setrequestheader-no-cred-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-setrequestheader-no-cred.htm:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-network-error-sync-events.sub-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-network-error-sync-events.sub.htm:
Fix tests to use get_host_info() instead of hardcoding custom domains which don't work with the
WebKit layout tests infrastructure. This improves test coverage. I'll upstream those changes.

* Source/WebCore/xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::XMLHttpRequest):
(WebCore::XMLHttpRequest::open):
(WebCore::XMLHttpRequest::abort):
(WebCore::XMLHttpRequest::internalAbort):
(WebCore::XMLHttpRequest::abortError):
(WebCore::XMLHttpRequest::handleCancellation):
(WebCore::XMLHttpRequest::didFail):
* Source/WebCore/xml/XMLHttpRequest.h:
Align our behavior with Blink and Gecko.

Canonical link: https://commits.webkit.org/264765@main

c67bf03

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl ❌ πŸ§ͺ ios-wk2   πŸ§ͺ api-mac βœ… πŸ›  gtk
βœ… πŸ§ͺ ios-wk2-wpt   πŸ§ͺ mac-wk1 ❌ πŸ§ͺ gtk-wk2
βœ… πŸ§ͺ api-ios   πŸ§ͺ mac-wk2 βœ… πŸ§ͺ api-gtk
βœ… πŸ›  tv   πŸ§ͺ mac-AS-debug-wk2
βœ… πŸ›  tv-sim
❌ πŸ›  πŸ§ͺ merge βœ… πŸ›  watch
βœ… πŸ›  watch-sim

@cdumez cdumez self-assigned this May 26, 2023
@cdumez cdumez added the WebCore Misc. For miscellaneous bugs in the WebCore framework (and not JavaScriptCore or WebKit). label May 26, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 27, 2023
@cdumez cdumez removed the merging-blocked Applied to prevent a change from being merged label May 27, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 27, 2023
@cdumez cdumez removed the merging-blocked Applied to prevent a change from being merged label May 30, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 30, 2023
@cdumez cdumez marked this pull request as ready for review May 30, 2023 19:06
@cdumez cdumez removed the merging-blocked Applied to prevent a change from being merged label May 30, 2023
Copy link
Contributor

@youennf youennf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me.
Please land the WPT PR first though.

@@ -1149,6 +1149,7 @@ void LocalDOMWindow::stop()
if (!frame)
return;

SetForScope isStopped { m_isStopping, true };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isStopping?
Also, shouldn't we need to write it as m_isStopping, true, false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isStopping indeed, will fix.

With regards to your other comment, I don't think so. My version is a little safer in case of re-entrancy because it will restore whatever value m_isStopping had before (which is likely false but not necessarily in case we re-enter this function).

@@ -682,7 +681,7 @@ void XMLHttpRequest::abort()
{
Ref<XMLHttpRequest> protectedThis(*this);

m_wasAbortedByClient = true;
m_wasAbortedByClient = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The web page is calling abort() so it seems m_wasAbortedByClient should be true.
If we change the meaning of m_wasAbortedByClient, we should change its name.
In this case, maybe we can remove it altogether.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, not sure what happened here. I'll restore.

if (auto* window = document->domWindow())
m_wasAbortedByClient |= window->isStopping();
}

// The XHR specification says we should only fire an abort event if the cancelation was requested by the client.
if (m_wasAbortedByClient && error.isCancellation()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this patch, m_wasAbortedByClient is always false, except in this method, and it is the only place we check it. Can we use a local variable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it’s non-obvious, I studied the code and verified that @youennf is right about this. No other code is looking at m_wasAbortedByClient, and it will always be false entering this function, so we don’t need m_wasAbortedByClient any more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is set to true in abort().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But abort then unconditionally calls immediateAbort. That sets m_error unconditionally. So we will return early in that case and after the early return we are guaranteed that m_wasAbortedByClient is false. So I am sure we can get the same behavior without a data member.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see. Thanks for clarifying. I'll look into it now.

@@ -889,18 +889,28 @@ String XMLHttpRequest::statusText() const
return m_response.httpStatusText();
}

void XMLHttpRequest::didFail(const ResourceError& error)
void XMLHttpRequest::handleCancellation(const ResourceError&)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why having a const ResourceError&?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will drop.

@cdumez
Copy link
Contributor Author

cdumez commented May 31, 2023

Upstream PR: web-platform-tests/wpt#40325

Source/WebCore/xml/XMLHttpRequest.cpp Show resolved Hide resolved
if (auto* window = document->domWindow())
m_wasAbortedByClient |= window->isStopping();
}

// The XHR specification says we should only fire an abort event if the cancelation was requested by the client.
if (m_wasAbortedByClient && error.isCancellation()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it’s non-obvious, I studied the code and verified that @youennf is right about this. No other code is looking at m_wasAbortedByClient, and it will always be false entering this function, so we don’t need m_wasAbortedByClient any more.

@@ -17,7 +17,7 @@
{
var xhr = new XMLHttpRequest();

xhr.open("POST", "http://nonexistent.{{host}}:{{ports[http][0]}}", false);
xhr.open("POST", "http://{{host}}:3", false); // Bad port.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 is not a bad port as far as I can tell from https://fetch.spec.whatwg.org/#bad-port.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed!

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 31, 2023
@cdumez cdumez removed the merging-blocked Applied to prevent a change from being merged label May 31, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 31, 2023
@cdumez cdumez added merge-queue Applied to send a pull request to merge-queue and removed merging-blocked Applied to prevent a change from being merged labels May 31, 2023
https://bugs.webkit.org/show_bug.cgi?id=257397

Reviewed by Darin Adler and Youenn Fablet.

window.stop() should fire an abort event on XMLHttpRequest asynchronously, to match
the behavior of Blink and Gecko.

It should schedule a asynchronous task, which should get cancelled if the
JavaScript calls `open()` on the XMLHttpRequest again. This is covered by WPT
tests.

* LayoutTests/imported/w3c/web-platform-tests/xhr/abort-after-stop.window-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/open-after-stop.window-expected.txt:
Rebaseline tests now that more checks are passing.

* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-basic-cors-not-enabled-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-basic-cors-not-enabled.htm:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-basic-setrequestheader-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-basic-setrequestheader.htm:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-setrequestheader-no-cred-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-authentication-cors-setrequestheader-no-cred.htm:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-network-error-sync-events.sub-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/xhr/send-network-error-sync-events.sub.htm:
Fix tests to use get_host_info() instead of hardcoding custom domains which don't work with the
WebKit layout tests infrastructure. This improves test coverage. I'll upstream those changes.

* Source/WebCore/xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::XMLHttpRequest):
(WebCore::XMLHttpRequest::open):
(WebCore::XMLHttpRequest::abort):
(WebCore::XMLHttpRequest::internalAbort):
(WebCore::XMLHttpRequest::abortError):
(WebCore::XMLHttpRequest::handleCancellation):
(WebCore::XMLHttpRequest::didFail):
* Source/WebCore/xml/XMLHttpRequest.h:
Align our behavior with Blink and Gecko.

Canonical link: https://commits.webkit.org/264765@main
@webkit-commit-queue
Copy link
Collaborator

Committed 264765@main (02e1d3e): https://commits.webkit.org/264765@main

Reviewed commits have been landed. Closing PR #14406 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 02e1d3e into WebKit:main May 31, 2023
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label May 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WebCore Misc. For miscellaneous bugs in the WebCore framework (and not JavaScriptCore or WebKit).
Projects
None yet
7 participants