-
Notifications
You must be signed in to change notification settings - Fork 323
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 Request to outlive environment settings object #388
Conversation
I'm not entirely sure actually. @yutakahirano can hopefully help. |
concept-request relies on ReadableStream which relies on the realm. So we cannot read data from the request body when the environment settings object is invalid, I guess. cc: @domenic |
Yeah, that's true, if someone sends a ReadableStream body but the window has been collected, you're in trouble. |
Ah, well.. In that case I guess we should throw an error if body object's type is Before I update the pull.. Does that make sense? Any other gotchas? |
TPAC notes:
Adding |
The problem is that the concept layer also depends on ReadableStream. Even when you create a Request object from a DOMString body, the body is held as a ReadableStream (see https://fetch.spec.whatwg.org/#concept-body and https://fetch.spec.whatwg.org/#concept-bodyinit-extract). If we need to have a fetch operation work beyond the realm destruction, we need to define a stream that works in such a circumstance. |
I thought one of the goals was to let the browser optimize such that if it never has to execute js to read the stream, then it could perform off thread copying, etc. A DOMString body should fall into this category, no? |
Updated / simplified the proposed change in 3b71edd -- getting warmer? This doesn't address @yutakahirano's comment about Streams support for outliving real destruction.. but that smells like a Streams API feature? @domenic any thoughts or recommendations on this one? |
Yeah, I'm not sure what to do about that issue :-/. I think it might be worth noting in the spec somehow, and I'll try to think of a nicer solution next week... |
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.
Many nits, but the main problem I see here is that you haven't defined what size of an object means. As I understand it from a discussion with @esprehn and others, calculating the size of FormData
requires a roundtrip through networking land. Whereas this would require that to be a synchronous lookup.
@@ -4224,7 +4224,7 @@ <h4 id="should-response-to-request-be-blocked-due-to-nosniff?"><dfn title="shoul | |||
|
|||
<p>To <dfn title=concept-BodyInit-extract>extract</dfn> a <span title=concept-body>body</span> and a | |||
`<code title>Content-Type</code>` <span title=concept-header-value>value</span> from | |||
<var>object</var>, run these steps: | |||
<var>object</var> with optional <var>keepalive-body-size</var>, run these steps: |
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.
keepaliveBodySize
(Content-Type
is an exception that should maybe be modified at some point).
@@ -4487,6 +4493,7 @@ <h4 id="should-response-to-request-be-blocked-due-to-nosniff?"><dfn title="shoul | |||
readonly attribute <span>RequestCache</span> <span title=dom-Request-cache>cache</span>; | |||
readonly attribute <span>RequestRedirect</span> <span title=dom-Request-redirect>redirect</span>; | |||
readonly attribute DOMString <span title=dom-Request-integrity>integrity</span>; | |||
readonly attribute boolean <span title=dom-Request-keepAlive>keepAlive</span>; |
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.
keepAlive or keepalive? We should stay consistent. https://en.wikipedia.org/wiki/Keepalive suggests the time has come where it is one word, but HTTP sets precedent in the other direction unfortunately.
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'll rename to lowercase "keepalive" throughout.
<span title=concept-request-integrity-metadata>integrity metadata</span> is | ||
<var>request</var>'s | ||
<span title=concept-request-integrity-metadata>integrity metadata</span>. | ||
<span title=concept-request-integrity-metadata>integrity metadata</span>, and | ||
<span title=concept-request-keep-alive-flag>keep-alive flag</span> is |
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 flag hasn't been defined it seems?
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.
A request has an associated keep-alive flag. Unless stated otherwise it is unset.
I think that should do the trick?
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.
Yeah, though "keepalive" per earlier comment and maybe a note following it that describes it would be good. Ideally all request fields have a note describing them, but I haven't gotten around to do that just yet.
@@ -4734,6 +4746,10 @@ <h4 id="should-response-to-request-be-blocked-due-to-nosniff?"><dfn title="shoul | |||
<var>request</var>'s | |||
<span title=concept-request-integrity-metadata>integrity metadata</span> to it. | |||
|
|||
<li><p>If <var>init</var>'s <code title>keepAlive</code> member is present, set |
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.
then set*
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 change that, but (fyi) it's inconsistent with surrounding language.. e.g.
If init's
integrity
member is present, set request's integrity metadata to it.
I'll keep as is for now, let me know if you want me to change it.
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.
Please change it. Existing language should also be updated at some point. But it's better if new language does it from the start for git blame and such.
@@ -4291,6 +4291,12 @@ <h4 id="should-response-to-request-be-blocked-due-to-nosniff?"><dfn title="shoul | |||
</dl> | |||
|
|||
<li> | |||
<p>If <var>keepalive-body-size</var> is provided and <var>object</var>'s type is | |||
<code title=concept-ReadableStream>ReadableStream</code>, or <var>object</var>'s size is greater | |||
than <var>keepalive-body-size</var>, throw a <code title>TypeError</code> and abort the |
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.
then throw* and no need to say the remaining steps are aborted. That follows from throwing (new convention we're trying to use).
<li><p>If <var>init</var>'s <code title>keepAlive</code> member is present and is set to | ||
<code>true</code>, then set <var>inputBody</var> and <var>Content-Type</var> to the | ||
result of <span title=concept-BodyInit-extract>extracting</span> <var>init</var>'s | ||
<code title>body</code> member with <var>keepalive-body-size</var> set by user agent policy. |
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 suggest we introduce keepalive-body-size in an earlier step so it's more clear it's user-agent defined.
@@ -4802,7 +4818,17 @@ <h4 id="should-response-to-request-be-blocked-due-to-nosniff?"><dfn title="shoul | |||
<ol> | |||
<li><p>Let <var>Content-Type</var> be null. | |||
|
|||
<li><p>Set <var>inputBody</var> and <var>Content-Type</var> to the result of | |||
<li><p>If <var>init</var>'s <code title>keepAlive</code> member is present and is set to |
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.
You need a newline after the <li>
since it contains two <p>
s.
result of <span title=concept-BodyInit-extract>extracting</span> <var>init</var>'s | ||
<code title>body</code> member with <var>keepalive-body-size</var> set by user agent policy. | ||
Rethrow any exceptions. | ||
<p class="note no-backref">This step ensures that requests that are allowed to outlive the |
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.
Newline before the <p>
and probably also should be indented one space more.
@@ -4291,6 +4291,12 @@ <h4 id="should-response-to-request-be-blocked-due-to-nosniff?"><dfn title="shoul | |||
</dl> | |||
|
|||
<li> | |||
<p>If <var>keepalive-body-size</var> is provided and <var>object</var>'s type is | |||
<code title=concept-ReadableStream>ReadableStream</code>, or <var>object</var>'s size is greater |
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.
a ReadableStream
object*
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.
Also, how do we determine object's size? As I understand it that can be quite hard for FormData
.
@annevk thanks for the review, I think I addressed most of it in 759a8fa, modulo...
That's a great question.. I was hoping you could point me towards a handy hook somewhere. :) How does 5.5 step 5 derive it?
Presumably this step has the same issue as you outlined above? |
Yeah, I think it does. The main difference is that currently we don't need to know the size synchronously as it's not exposed anywhere. This would expose it synchronously and I don't think user agents would be happy with that. |
That's true. Well, I guess the other approach we have here is:
~section 5.5, step 7:
WDYT? |
"user-agent-defined maximum body size", but yes, that could work. I'd love @esprehn or someone else from Blink to sign off on that though. |
<span title=concept-request-integrity-metadata>integrity metadata</span> is | ||
<var>request</var>'s | ||
<span title=concept-request-integrity-metadata>integrity metadata</span>. | ||
<span title=concept-request-integrity-metadata>integrity metadata</span>, and | ||
<span title=concept-request-keepalive-flag>keepalive flag</span> is |
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.
Note that keepalive flag doesn't need a title since the <dfn>
doesn't have one either. I should probably have given all flags a title from the start, but too late now and when it's all converted to bikeshed at some point it'll no longer matter much.
<span title=concept-request-integrity-metadata>integrity metadata</span>, and | ||
<span title=concept-request-keepalive-flag>keepalive flag</span> is | ||
<var>request</var>'s | ||
<span title=concept-request-keepalive-flag>keepalive flag</span> |
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.
title can be removed here too.
@@ -4734,6 +4746,10 @@ <h4 id="should-response-to-request-be-blocked-due-to-nosniff?"><dfn title="shoul | |||
<var>request</var>'s | |||
<span title=concept-request-integrity-metadata>integrity metadata</span> to it. | |||
|
|||
<li><p>If <var>init</var>'s <code title>keepalive</code> member is present, then set | |||
<var>request</var>'s | |||
<span title=concept-request-keepAlive>keepalive flag</span> to it. |
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.
And here.
@annevk updated, PTAL. In the meantime, I'll ping some Blink folks for a review -- stay tuned. |
Yeah I think that works. Btw what makes it clear that the fetch result promise will never resolve on a keepalive request if the page is destroyed? |
I don't think anything at the moment. We don't have a clear "page is destroyed" hook yet. What does that mean, by the way? Browsing context going away ( |
the spec change lgtm. we still have issues with our implementation for the sendBeacon and this, but I agree this is what we should pursue. I guess Chromium could start implementing this in Q117. |
@youennf any feedback from WebKit? Apart from some minor nits I can take care of when merging this looks okay to me now. (The lifetime issues will need to be sorted, but they are larger than this issue in my estimation.) |
Makes sense to me. I guess the keep-alive attribute might be useful for service workers although for some of the keep-alive use-cases, there might be no need to resolve/create any response. |
Related discussion in [1]. This exposes keepAlive flag within Request constructor and adds guards for limiting the size of such requests. [1] w3c/beacon#27
@igrigorik the only thing that remains doing is writing tests. I assume that will happen as part of implementation work, but if you all could make sure they end up in https://github.com/w3c/web-platform-tests that'd be great. |
Also, thank you for your work on this! |
@annevk yep, thanks! I'll a tests TODO on my list.. |
I'm sorry I didn't provide more feedback sooner, but can someone explain why we need to expose a It feels really weird to me to ask devs to specify a flag for something the browser can probably do automatically in implementation. |
How would this work with sendBeacon()? E.g., what this enables is a keepalive HEAD. Not possible today. |
The same way we effectively keep Request objects in Cache API beyond the end of an environment settings object. The browser has to maintain an internal representation in some way. It doesn't need to keep the JS object alive. But maybe I don't understand what you mean by "keepalive HEAD". |
E.g., how would you write |
Anne explained further in IRC that this is about not canceling the fetch operation if the environment settings object is destroyed. I got confused because the PR and spec text talk more about the lifecycle of (R|r)equest objects. Anyway, carry on. |
From w3c/beacon#27 (comment):
@tyoshino @annevk @youennf any thoughts or opinions on the above? |
I think @wanderview misunderstood what was going on due to some unclear wording in this PR's title. See comments above. |
OK, never mind.. Onwards! :-) |
Related discussion in w3c/beacon#27.
@annevk ptal, is this on the right track? I have a few ???'s and TODO's that I could use help with :)