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
Allow used body replacement in Request constructor #675
Allow used body replacement in Request constructor #675
Conversation
@terinjokes could you add @harrishancock as a public member of the cloudflare-whatwg organization? |
I wonder if we should move step 7.1 down to the other body checks (and I also wonder if we could simplify those somewhat). |
@annevk This is in progress. |
@annevk Done. Sorry for the delay. |
Agreed about moving the check down with the others. I'll find a nice spot for it and amend the commit. I'm not sure there's a better factorization of the body setup steps (38-44). :/ It seems largely complicated by the fact that nothing after the input Request object body stealing (setting up rs and piping to it) is allowed to throw (to enforce the strong exception safety guarantee, I suppose). Maybe the best thing to do would be to defer the piping action until after all the checks are complete?
I'm not really sure that's "better". :) @yutakahirano? |
Actually, is the check in 7.1 even necessary? The logical place for it is to add it to the beginning of step 43's substeps, but it seems like it's already implicit in step 43.1 -- piping to |
Good question, I guess it depends on if it's observably different. Maybe not, though we'll need to fix #463 to be sure. |
My intention has been they are same. |
Whether we should keep step 7.1 depends on whether we want to separate the read-only part and state-modifying part (currently we don't throw an exception from this part). |
Currently, the following code snippet replaces `request`'s body as one would expect: let request = new Request(url, { method: "POST", body: "foo" }) request = new Request(request, { body: "bar" }) But this snippet throws a TypeError early in Request's constructor: let request = new Request(url, { method: "POST", body: "foo" }) await request.text() // disturb the body request = new Request(request, { body: "bar" }) // throws This commit's changes allows the latter code snippet to work like the first one. Fixes whatwg#674.
e0049c6
to
121a61b
Compare
Amended to move the disturbed or locked check closer to where it's relevant: right before the inputBody piping. To me, it would make most sense to either put the check in the inputBody piping substeps, or make it implicit in the piping itself, as I mentioned. Until that decision is finalized, this seems like the best we can do: the "critical line" between the read-only part of the constructor and the state-modifying part remains in the top-level steps (as opposed to the piping substeps, which are conditional); the piping operation is guaranteed not to throw; and the check and the piping operation are written as close to each other as possible to make future maintenance easier. |
Can you add a web platform test? |
Will do. I had hoped to get to it today, but ran out of time. Soon! |
Ping. :) WPT PR here: web-platform-tests/wpt#9931 |
fetch.bs
Outdated
@@ -5348,10 +5345,14 @@ constructor must run these steps: | |||
<a for=request>use-CORS-preflight flag</a>. | |||
</ol> | |||
|
|||
<li><p>If <var>inputBody</var> is <var>body</var> and <var>input</var> is <a for=Body>disturbed</a> | |||
or <a for=Body>locked</a> then <a>throw</a> a <code>TypeError</code>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a comma before then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can fix these nits if you don't want to, FWIW.
fetch.bs
Outdated
<!-- Any steps after this must not throw. --> | ||
|
||
<li> | ||
<p>If <var>inputBody</var> is non-null, then run these substeps: | ||
<p>If <var>inputBody</var> is non-null and <var>inputBody</var> is <var>body</var>, then run these | ||
substeps: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be just ", then:"
fetch.bs
Outdated
<var>inputBody</var>'s <a for=body>total bytes</a>. | ||
<li><p>Set <var>body</var> to a new <a for=/>body</a> whose <a for=body>stream</a> is | ||
<var>rs</var>, whose <a for=body>source</a> is <var>inputBody</var>'s <a for=body>source</a> and | ||
whose <a for=body>total bytes</a> is <var>inputBody</var>'s <a for=body>total bytes</a>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs an Oxford comma. (Also a problem in the original it seems.)
It seems this feature isn't implemented by browsers yet so no impl bugs to file. |
If someone could confirm the above I think we're good to go. |
@annevk Safari tech preview has it, does that count? It throws TypeError: "Request input is disturbed or locked.". Edit: It's also in stable version 11.0.3. |
That certainly counts, thanks! @harrishancock could you file a bug at https://bugs.webkit.org/enter_bug.cgi?product=WebKit&component=HTML%20DOM? |
@annevk, thank you for fixing the nits, I appreciate it! I've submitted a WebKit bug here: https://bugs.webkit.org/show_bug.cgi?id=183703 |
See Fetch change whatwg/fetch#675. Specifically, that PR allows Requests with disturbed bodies to be used as the first parameter to the Request constructor, as long as the RequestInit dictionary contains a body member with which to replace the used body. As of this writing, no browser implements this change.
Thanks, all merged now! |
…t constructor, a=testonly Automatic update from web-platform-testsFetch: add used body replacement test for Request constructor See Fetch change whatwg/fetch#675. Specifically, that PR allows Requests with disturbed bodies to be used as the first parameter to the Request constructor, as long as the RequestInit dictionary contains a body member with which to replace the used body. As of this writing, no browser implements this change. wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931 wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931
https://bugs.webkit.org/show_bug.cgi?id=183703 <rdar://problem/49425609> Reviewed by Youenn Fablet. LayoutTests/imported/w3c: Rebaseline WPT test now that one more check is passing. * web-platform-tests/fetch/api/request/request-disturbed-expected.txt: Source/WebCore: Allow used body replacement in Request constructor as per: - whatwg/fetch#675 No new tests, rebaseline existing test. * Modules/fetch/FetchRequest.cpp: (WebCore::FetchRequest::initializeWith): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@243757 268f45cc-cd09-0410-ab3c-d52691b4dbfc
…t constructor, a=testonly Automatic update from web-platform-testsFetch: add used body replacement test for Request constructor See Fetch change whatwg/fetch#675. Specifically, that PR allows Requests with disturbed bodies to be used as the first parameter to the Request constructor, as long as the RequestInit dictionary contains a body member with which to replace the used body. As of this writing, no browser implements this change. wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931 wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931 UltraBlame original commit: ad7b8e6c381646d827339d34e4ac9db07654bcc8
…t constructor, a=testonly Automatic update from web-platform-testsFetch: add used body replacement test for Request constructor See Fetch change whatwg/fetch#675. Specifically, that PR allows Requests with disturbed bodies to be used as the first parameter to the Request constructor, as long as the RequestInit dictionary contains a body member with which to replace the used body. As of this writing, no browser implements this change. wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931 wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931 UltraBlame original commit: ad7b8e6c381646d827339d34e4ac9db07654bcc8
…t constructor, a=testonly Automatic update from web-platform-testsFetch: add used body replacement test for Request constructor See Fetch change whatwg/fetch#675. Specifically, that PR allows Requests with disturbed bodies to be used as the first parameter to the Request constructor, as long as the RequestInit dictionary contains a body member with which to replace the used body. As of this writing, no browser implements this change. wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931 wpt-commits: e87f38097902e16348d4e17f4fe3bc2d0112bff1 wpt-pr: 9931 UltraBlame original commit: ad7b8e6c381646d827339d34e4ac9db07654bcc8
Currently, the following code snippet replaces
request
's body as one would expect:But this snippet throws a TypeError early in Request's constructor:
This commit's changes allows the latter code snippet to work like the first one.
Fixes #674.
Preview | Diff