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

Report iframe & frame resource timing #7531

Merged
merged 17 commits into from
Mar 30, 2022

Conversation

@noamr noamr changed the title Report iframe & frame resource timing WIP Report iframe & frame resource timing Jan 25, 2022
@noamr noamr force-pushed the report-iframe-resource-timing branch from 3fc29a3 to d803310 Compare January 30, 2022 10:16
@noamr noamr changed the title WIP Report iframe & frame resource timing Report iframe & frame resource timing Jan 30, 2022
Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

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

We should avoid introducing more instances of "source browsing context", per #1130. At least ones outside of the synchronous initial computation.

Can you instead compute a boolean synchronously, something like "initiator is container", and then consult that at "report frame timing" time? You can stuff it into navigation params, so that you don't need to pass it around manually.

source Outdated Show resolved Hide resolved
source Outdated
@@ -87498,6 +87500,7 @@ interface <dfn interface>Location</dfn> { // but see also <a href="#the-location

<dt><dfn data-x="navigation-params-has-cross-origin-redirects">has cross-origin
redirects</dfn></dt>
<dt><dfn data-x="navigation-params-is-container-initiated">is container initiated</dfn></dt>
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer these not share a dd; they can each have a separate one just saying "a boolean".

source Outdated
<dfn data-x="navigation-navigationid"><var>navigationId</var></dfn> (default null):</p>
"<code data-x="">other</code>"), an optional <span data-x="navigation-id">navigation id</span>
<dfn data-x="navigation-navigationid"><var>navigationId</var></dfn> (default null), and an
optional boolean <dfn data-x="navigation-iscontainerinitiated">isContainerInitiated</dfn>
Copy link
Member

Choose a reason for hiding this comment

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

If we keep this, put <var> inside the <dfn>. But per the below I think we should calculate it early in the algorithm, instead.

source Outdated
"<code data-x="">other</code>"), an optional <span data-x="navigation-id">navigation id</span>
<dfn data-x="navigation-navigationid"><var>navigationId</var></dfn> (default null), and an
optional boolean <dfn data-x="navigation-iscontainerinitiated">isContainerInitiated</dfn>
(default false):</p>
Copy link
Member

Choose a reason for hiding this comment

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

I think it's better to calculate this using the source browsing context vs. the target browsing context, instead of passing it in as a parameter. As long as we calculate it synchronously.

That would also get you embed and object for free, kinda? At least in the cases where they're behaving like nested browsing contexts. (Which embed doesn't in the spec, but does in practice; see #513 .)

Copy link
Member

Choose a reason for hiding this comment

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

I kind of changed my mind here; see #7554 (review) . We don't want embed/object to trigger this since you're doing it separately over in #7554.

However in that case I think we should rename the parameter. Something like "needs to report resource timing" maybe? Because for embed and object, "is container-initiated" could be true; it's just that we don't want to report resource timing for them since we're doing it separately.

source Outdated
false.</p></li>
false, and
<span data-x="navigation-params-is-container-initiated">is container initiated</span> is
<var>isContainerInitiated</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

Also need to set it for the javascript: URL case a few lines below this.

source Outdated
<span data-x="navigation-params-is-container-initiated">is container initiated</span> is false,
then return.</p></li>

<li><p><span>Queue an element task</span> on the <span>DOM manipulation task source</span> given
Copy link
Member

Choose a reason for hiding this comment

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

Should it be the DOM manipulation or the networking task source? I feel like most of the others are done from the networking task source.

Not sure it matters much in practice...

source Outdated
given <var>navigationParams</var>, and <span>queue a global task</span> on the
<span>networking task source</span> given the newly-created <code>Document</code>'s
<span>relevant global object</span> to have the parser process the implied EOF character, which
eventually causes a <code data-x="event-load">load</code> event to be fired.</p>
Copy link
Member

Choose a reason for hiding this comment

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

So, do we not report frame timing when navigating to XHTML/img/video/text/etc. documents? I think all those sections will probably need updating too.

@noamr noamr force-pushed the report-iframe-resource-timing branch from 822607a to 9d2b771 Compare February 21, 2022 11:41
@noamr noamr force-pushed the report-iframe-resource-timing branch from 9d2b771 to 7464cce Compare March 14, 2022 17:20
@noamr
Copy link
Contributor Author

noamr commented Mar 14, 2022

@domenic, apparently this no longer depends on a change in Fetch, the existing finalize algorithm should suffice as Fetch already performs TAO checks for iframes based on the top-level origin at a different stage.

source Outdated
<span>source browsing context</span> set to <var>element</var>'s <span>node document</span>'s
<span data-x="concept-document-bc">browsing context</span>.</p></li>
data-x="navigation-hh">historyHandling</var> set to <var>historyHandling</var>,
<span data-x="navigation-report-rt-to-container">shouldReportResourceTimingToContainer</span> set
Copy link
Member

Choose a reason for hiding this comment

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

span -> i

source Outdated
@@ -87683,6 +87702,7 @@ interface <dfn interface>Location</dfn> { // but see also <a href="#the-location

<dt><dfn data-x="navigation-params-has-cross-origin-redirects">has cross-origin
redirects</dfn></dt>
<dt><dfn data-x="navigation-params-report-rt-to-container">is container initiated</dfn></dt>
<dd>a boolean</dd>
Copy link
Member

Choose a reason for hiding this comment

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

Let's stick with keeping dd/dt pairs 1:1 for navigation params, so insert another <dd>a boolean</dd>. Or even better, <dd>a boolean indicating ...</dd> explaining its purpose.

source Outdated
"<code data-x="">other</code>"), an optional <span data-x="navigation-id">navigation id</span>
<dfn data-x="navigation-navigationid"><var>navigationId</var></dfn> (default null), and an
optional boolean
<dfn data-x="navigation-report-rt-to-container">shouldReportResourceTimingToContainer</dfn>
Copy link
Member

Choose a reason for hiding this comment

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

<var> inside the <dfn>

source Outdated

<p class="note">This ensures that resource timing is reported to the frame before any parsing
and regardless of the type of resource.</p>
</li>
Copy link
Member

Choose a reason for hiding this comment

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

Involving the streams machinery here just to get access to the point in time before the final byte seems bad, since it doesn't match implementations. And, I don't think it will work? Once a chunk passes through the transform, it will probably be parsed, and that happens before the flush algorithm.

I'm not really clear how this is supposed to work, in general. We have three events:

A. The resource timing entry is sent
B. The browser parses the bytes, e.g. to do preload scanning or tree construction (which might run scripts)
C. The last byte is read from the network

You seem to be claiming that A must be sent before B, and also that A must occur after C. But B occurs way before C.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Involving the streams machinery here just to get access to the point in time before the final byte seems bad, since it doesn't match implementations. And, I don't think it will work? Once a chunk passes through the transform, it will probably be parsed, and that happens before the flush algorithm.

I'm not really clear how this is supposed to work, in general. We have three events:

A. The resource timing entry is sent

B. The browser parses the bytes, e.g. to do preload scanning or tree construction (which might run scripts)

C. The last byte is read from the network

You seem to be claiming that A must be sent before B, and also that A must occur after C. But B occurs way before C.

Fair enough, will have another think about this...

Copy link
Contributor Author

@noamr noamr Mar 15, 2022

Choose a reason for hiding this comment

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

I think the stream machinery does the right thing, but the comment is inaccurate - the reporting might be done after parsing, but before handling the EOF.

I can think of 3 alternatives:

  • Keep the current stream foo and update the comment
  • Add a processResponseEndOfBody callback to the navigation fetch and report iframe there. It does the streams foo internally in fetch. (this somewhat matches implementations)
  • Add separate wording for each resource type (HTML, XML, etc.)

Copy link
Member

Choose a reason for hiding this comment

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

processResponseEndOfBody sounds best to me!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, refactored in this spirit and the PR is significantly smaller :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Anything still missing @domenic?

@noamr noamr force-pushed the report-iframe-resource-timing branch from 044e827 to ce68ed2 Compare March 16, 2022 06:07
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated
@@ -88251,7 +88261,8 @@ interface <dfn interface>Location</dfn> { // but see also <a href="#the-location

<ol>
<li><p>If <var>response</var> is null, <!--FETCH--><span
data-x="concept-fetch">fetch</span> <var>request</var>.</p></li>
data-x="concept-fetch">fetch</span> <var>request</var> with <i>processResponseEndOfBody</i>
Copy link
Member

Choose a reason for hiding this comment

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

This <i> needs to be a link, i.e. <i data-x="...">.

source Outdated
@@ -88251,7 +88261,8 @@ interface <dfn interface>Location</dfn> { // but see also <a href="#the-location

<ol>
<li><p>If <var>response</var> is null, <!--FETCH--><span
data-x="concept-fetch">fetch</span> <var>request</var>.</p></li>
data-x="concept-fetch">fetch</span> <var>request</var> with <i>processResponseEndOfBody</i>
set to <var>processResponseEndOfBody</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

This variable is not defined inside "process a navigate fetch". It needs to be threaded through from at least one caller, possibly multiple.

Also, this will only call processResponseEndOfBody for the very first fetch, when response is null. Any redirect fetches afterward will be ignored. Is that the desired timing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm it's not the desired thing. But not sure how else to use processResponseEndOfBody - we will need to make the same "is this a valid redirect" checks inside processEndOfBody.

I'm thinking that perhaps my previous approach of using a transform stream (a previous revision) is the correct way to do this. It's really a replication of a similar stream in https://fetch.spec.whatwg.org/#fetch-finale that we need to do here because we replicate the redirect mechanics.

Copy link
Contributor Author

@noamr noamr left a comment

Choose a reason for hiding this comment

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

Refactored to account for redirects. Not sure if this is simpler/more readable than using a TransformStream, but it would be as correct. WDYT?

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
noamr added a commit to web-platform-tests/wpt that referenced this pull request Mar 23, 2022
noamr added a commit to web-platform-tests/wpt that referenced this pull request Mar 23, 2022
…ue RT entry (#33317)

* Iframes with missing redirect location should fire load event and queue RT entry

See whatwg/html#7531

* Rename and use loader
DanielRyanSmith pushed a commit to DanielRyanSmith/wpt that referenced this pull request Mar 25, 2022
…ue RT entry (web-platform-tests#33317)

* Iframes with missing redirect location should fire load event and queue RT entry

See whatwg/html#7531

* Rename and use loader
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request Mar 26, 2022
…hould fire load event and queue RT entry, a=testonly

Automatic update from web-platform-tests
Iframes with missing redirect location should fire load event and queue RT entry (#33317)

* Iframes with missing redirect location should fire load event and queue RT entry

See whatwg/html#7531

* Rename and use loader
--

wpt-commits: 7eb2cb2120e6cd172ad10edb7f38518e765daf49
wpt-pr: 33317
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request Mar 27, 2022
…hould fire load event and queue RT entry, a=testonly

Automatic update from web-platform-tests
Iframes with missing redirect location should fire load event and queue RT entry (#33317)

* Iframes with missing redirect location should fire load event and queue RT entry

See whatwg/html#7531

* Rename and use loader
--

wpt-commits: 7eb2cb2120e6cd172ad10edb7f38518e765daf49
wpt-pr: 33317
source Outdated
@@ -88250,12 +88266,32 @@ interface <dfn interface>Location</dfn> { // but see also <a href="#the-location
<p>Otherwise:</p>

<ol>
<li><p>Let <var>finalResponseReached</var> be false.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

I find it weird that we're tracking final response-ness both here and in the rest of the loop. For example, that leads to problems where e.g. the censoring done in step 13.5.10 is not reflected; you can use navigation timing to figure out how long responses blocked by CORP take to read their full body. Maybe that is already handled through additional checks in the navigation timing spec? But it seems very duplicative.

Similarly, I'm unsure whether navigation timing will give you results for 204s, 205s, Content-Disposition: attachment downloads, X-Frame-Options failures, or CSP failures. All of those are handled in "process a navigate response", far disconnected from this algorithm.

The cleanest layering I could imagine would be to handle navigation timing around the same time load events are fired, e.g. in https://html.spec.whatwg.org/#navigate-html. But that would preclude firing navigation timing for some error cases, so I don't know if that would be correct. I'd need additional clarity on which error cases you want to include, to give better advice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How is this related to navigation timing? This PR is about resource timing for the iframe. It should represent the timing used to fetch the iframe resource, and nothing else. The rest of these concerns are indeed about navigation and not related to this...

Also the implementations are in that spirit - an EOF handler on the iframe fetch that reports to the container if the navigation was container initiated.

Copy link
Member

Choose a reason for hiding this comment

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

I admit I misunderstood/misspoke. However, it's a resource being used for navigation, so I think some of those concerns might apply, especially the security concerns about not wanting to leak data if it is blocked.

Copy link
Member

Choose a reason for hiding this comment

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

Here is another angle of approach. I am pretty sure that in implementations, if you fail a CSP check or X-Frame-Options check or CORP check while doing the initial load of an iframe, we don't proceed to download the whole request body just so we can give you accurate resource timing. Whereas your current PR implies that would be done. It isn't meshing with other parts of the spec which indicate such errors by, e.g., overwriting the response variable with a network error.

I'm less sure about Content-Disposition: attachment cases (maybe we do report the amount of time it takes to download the file?) or 204s/205s where the server gives a body anyway despite that being disallowed by HTTP (maybe Fetch will queue processResponseEndOfBody immediately, ignoring the body)? But at least in cases where the current HTML spec ignores the body, I am doubtful implementations read the whole thing just for resource timing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see what you mean, indeed X-Frame-Options and CSP navigate failure should terminate the fetch, and report an opaque entry, as if it was a network error, to resource timing. This is indeed covered with WPT: https://wpt.fyi/results/resource-timing/iframe-failed-commit.html

I also added a WPT for 204/205: web-platform-tests/wpt#33402.

I'll amend the spec. I believe we need to be explicit about navigation failure terminating the fetch, which would solve the issue of fetch continuing all the way through, and we can add reporting there.

Copy link
Contributor Author

@noamr noamr Mar 29, 2022

Choose a reason for hiding this comment

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

Actually there is another handled case, an unknown mime-type, which would cause a download. An RT entry should not be reported in that case. Added a test.

This convinces me that the reporting should be done in the different scenarios such as navigate-html navigate-xml etc, like I did in one of the first PRs.

source Outdated Show resolved Hide resolved
aosmond pushed a commit to aosmond/gecko that referenced this pull request Mar 28, 2022
…hould fire load event and queue RT entry, a=testonly

Automatic update from web-platform-tests
Iframes with missing redirect location should fire load event and queue RT entry (#33317)

* Iframes with missing redirect location should fire load event and queue RT entry

See whatwg/html#7531

* Rename and use loader
--

wpt-commits: 7eb2cb2120e6cd172ad10edb7f38518e765daf49
wpt-pr: 33317
aosmond pushed a commit to aosmond/gecko that referenced this pull request Mar 28, 2022
…hould fire load event and queue RT entry, a=testonly

Automatic update from web-platform-tests
Iframes with missing redirect location should fire load event and queue RT entry (#33317)

* Iframes with missing redirect location should fire load event and queue RT entry

See whatwg/html#7531

* Rename and use loader
--

wpt-commits: 7eb2cb2120e6cd172ad10edb7f38518e765daf49
wpt-pr: 33317
@noamr noamr force-pushed the report-iframe-resource-timing branch from c64a9af to f3f3a80 Compare March 29, 2022 12:36
@noamr
Copy link
Contributor Author

noamr commented Mar 29, 2022

OK I refactored again to use report inside the mime-type specific handlers. This makes more sense because for non-supported mime-types there is no reporting, and it also takes care of X-Frame-Options and CSP.

One issue that's not properly handled though is TAO checks.
@domenic do you want to see if where I went with this reporting-wise is OK and then I'll add the TAO checks, which is kind of a separate issue, or should I try to add it to the PR first?

noamr added a commit to noamr/fetch that referenced this pull request Mar 29, 2022
@noamr
Copy link
Contributor Author

noamr commented Mar 29, 2022

OK I refactored again to use report inside the mime-type specific handlers. This makes more sense because for non-supported mime-types there is no reporting, and it also takes care of X-Frame-Options and CSP.

One issue that's not properly handled though is TAO checks. @domenic do you want to see if where I went with this reporting-wise is OK and then I'll add the TAO checks, which is kind of a separate issue, or should I try to add it to the PR first?

OK it's resolved in whatwg/fetch#1422 without need to change anything in the HTML PR.

Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

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

Looks good, just editorial stuff at this point

source Show resolved Hide resolved
source Show resolved Hide resolved
source Show resolved Hide resolved
source Show resolved Hide resolved
source Show resolved Hide resolved
source Show resolved Hide resolved
source Show resolved Hide resolved
Copy link
Contributor Author

@noamr noamr left a comment

Choose a reason for hiding this comment

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

Fixed editorial notes

source Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants