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

Define the Sec-Purpose header #85

Closed
wants to merge 1 commit into from
Closed

Define the Sec-Purpose header #85

wants to merge 1 commit into from

Conversation

noamr
Copy link

@noamr noamr commented Dec 19, 2022

This hopefully replaces x-moz: Prefetch
and Purpose: Prefetch with something
agreed.

It applies both to link prefetch and to speculation rules prefetch, though the latter may require additional parameters.

See whatwg/html#8111
Closes #84

This hopefully replaces `x-moz: Prefetch`
and `Purpose: Prefetch` with something
agreed.

It applies both to [link prefetch](https://html.spec.whatwg.org/multipage/links.html#link-type-prefetch)
and to [speculation rules prefetch](https://wicg.github.io/nav-speculation/prefetch.html#prefetch),
though the latter may require additional parameters.

See whatwg/html#8111
Closes w3c#84
@mikewest
Copy link
Member

Did you consider a distinct destination or mode rather than a new header?

@noamr
Copy link
Author

noamr commented Dec 19, 2022

Did you consider a distinct destination or mode rather than a new header?

It can't be mode because a prefetch can still be cors/no-cors.
In WICG/nav-speculation#133, the idea is that for speculationrules the bespoke "purpose" would be expanded to express both prefetches and prerenders.

However, I don't mind using Sec-Fetch-Dest for <link rel=prefetch> and deferring Sec-Purpose to speculationrules. @domenic, @jeremyroman, wdyt?

@mikewest
Copy link
Member

Hrm. Given that we're (apparently?) already shipping Sec-Purpose: prefetch;prerender, I'm not sure how useful it is for me to debate the spelling. That said, I don't understand why we need a new header for this. I thought we were aiming to align the two concepts. What does the distinction represent to developers that a destination of prefetch or prerender wouldn't?

@domenic
Copy link

domenic commented Dec 19, 2022

I think destination and whether the resource is being prefetched or not is orthogonal? E.g. you could have a prefetched image, a prefetched audio, a prefetched document, ...

@mikewest
Copy link
Member

Does it make a material difference to the developer? If we think there's reason to make server-side distinctions between a prefetched image and a prefetched video, then I agree that we need more detail (though if we're spelling it "initiator" in Fetch, I'm not sure why we'd send "purpose" in a header). I'm not sure that distinction is meaningful for the kinds of concerns I've heard raised around prefetching (bandwidth and server load both seem resource-specific, not kind-specific), though it certainly would be meaningful to distingush a document from a subresource of some other type. Is prefetch vs prerender not that distinction?

@noamr
Copy link
Author

noamr commented Dec 19, 2022

Is prefetch vs prerender not that distinction?

prefetch could be for documents or subresources. Prerender is only for documents. btw in speculationrules, everything is a document. perhaps there we could have a document destination and a prefetch purpose, and leave the destination empty in <link rel=prerender>. This would make a difference to developers...

@domenic
Copy link

domenic commented Dec 19, 2022

No; prefetch vs. prerender is not that distinction. Prefetch is just a fetch; prerender creates a full browsing context, downloads all subresources, runs JS, etc. We're currently using Sec-Purpose: prefetch;prerender for subresources that are being fetched during a prerender, BTW. (And then Sec-Fetch-Dest is used to distinguish the type of subresource.)

As to whether the distinction is meaningful to the developer, I don't know, because I don't know what developers today do with the difference between Sec-Fetch-Dest: audio and Sec-Fetch-Dest: image.

<ol class="algorithm">
2. Let |header| be a [=Structured Header=] whose value is a [=structured header/token=].

3. If [=request/initiator=] is `prefetch`, set |header|'s value to "`prefetch`".
Copy link
Member

Choose a reason for hiding this comment

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

Should prerender be defined here as well?

3. If [=request/initiator=] is `prefetch`, set |header|'s value to "`prefetch`".

4. [=header list/Set a structured field value=]
&#96;<a http-header>`Sec-Fetch-Mode`</a>&#96;/|header| in |r|'s [=request/header list=].
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
&#96;<a http-header>`Sec-Fetch-Mode`</a>&#96;/|header| in |r|'s [=request/header list=].
&#96;<a http-header>`Sec-Purpose`</a>&#96;/|header| in |r|'s [=request/header list=].

@@ -278,6 +278,35 @@ To <dfn abstract-op lt="set-user">set the `Sec-Fetch-User` header</dfn> for a [=
</ol>
</div>

The `Sec-Purpose` HTTP Request Header {#sec-purpose-header}
Copy link
Member

Choose a reason for hiding this comment

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

Given the existing implementation, I'll simply bemoan the fact that we're neither consistent with the rest of fetch metadata (Sec-Fetch-*) nor with Fetch's terminology (initiator). That's unfortunate, and perhaps not too late to change?

Copy link
Author

Choose a reason for hiding this comment

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

I think it's not too bad because purpose is not exactly a fetch concept. But I really don't mind. @domenic?

Copy link

Choose a reason for hiding this comment

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

Yeah, I don't think this is either fetch nor fetch-metadata... I think it's bad enough fetch-metadata is a separate spec from fetch, so I'm confused why this PR exists. We currently defined the header in https://wicg.github.io/nav-speculation/prefetch.html#sec-purpose-header and I'd expect it to move to HTML if it's going to be used by link rel prefetch.

Copy link
Author

Choose a reason for hiding this comment

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

I originally defined it in HTML, but then it needs special handling so that it doesn't create a preflight etc. This seemed like the place where we define these Sec- headers so it felt natural. Alternatives?

Copy link

Choose a reason for hiding this comment

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

Oh, is this the spec that defines special handling for preflights?

Copy link
Member

Choose a reason for hiding this comment

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

It's not really. This only defined the Sec-Fetch-* headers to date. And those could be merged into Fetch if we wanted to.

The main thing most Sec-* headers need to adhere to is that they are bound to the request rather late, post-SW.

Copy link

@domenic domenic Dec 19, 2022

Choose a reason for hiding this comment

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

It looks like it is not; Fetch defines that. So it seems to me defining the header in Fetch would make the most sense, if it's tied to initiator. @annevk's thoughts are welcome.

As for exposing a general initiator header vs. what's specified here: I think what's specified here is better. Initiator is a spec-internal term which we could easily change, and/or might be going away in the future: whatwg/fetch#1563 . And we should expose the minimum amount of information, not all possible initiators, so that we don't end up in the same situation as Sec-Fetch-Dest where apparently we're not sure what people are doing with the values we expose.

As for whether we should prefix with Sec-Fetch- vs. Sec-: I don't really understand the purpose of the Fetch- prefix, since all headers on the web platform are sent by fetch, so it feels like a legacy mistake to me that we wouldn't want to repeat to include that redundant prefix. (Based on reading this repo's readme, it seems maybe this stemmed from them all being originally bundled into a single header named Sec-Fetch or something?)

Copy link
Author

Choose a reason for hiding this comment

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

Porting this PR to fetch SGTM. Will wait for @annevk's thoughts on the matter.

Copy link
Member

Choose a reason for hiding this comment

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

Is my comment above not visible? Anyway, I concur.

Copy link
Author

Choose a reason for hiding this comment

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

It's visible but I didn't read it as opinionated.
Anyway, all clarified now.

[[!I-D.ietf-httpbis-header-structure]] Its ABNF is:

```
Sec-Purpose = sh-token
Copy link
Member

Choose a reason for hiding this comment

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

The sh-token grammar does not support prefetch; prerender. I think you'd need to define this as an sf-item (https://www.rfc-editor.org/rfc/rfc8941.html#section-3.3) along with some processing instructions that note that prerender is the only valid parameter (https://www.rfc-editor.org/rfc/rfc8941.html#param).

@mikewest
Copy link
Member

Ok. It seems that I've misunderstood the distinctions here. Thanks for the clarification. I added some notes to the PR.

@mikewest
Copy link
Member

I don't know what developers today do with the difference between Sec-Fetch-Dest: audio and Sec-Fetch-Dest: image.

I missed this above: I don't either. :) Google distinguishes between navigational requests and non-navigational requests in what the security team calls a "resource isolation policy", and between top-level and nested navigational requests in a "framing isolation policy". https://web.dev/fetch-metadata/ has some detail, and you can find internal pages with more.

As far as I know, Google doesn't distinguish between kinds of subresource requests. I've seen people talk about protecting API endpoints by ensuring that Sec-Fetch-Dest is empty, and blocking unexpected request types for endpoints serving known data types, but I don't know if those are deployed anywhere.

@noamr
Copy link
Author

noamr commented Dec 19, 2022

Closing in favor of whatwg/fetch#1576

@noamr noamr closed this Dec 19, 2022
@noamr noamr deleted the sec-purpose branch December 19, 2022 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Define Sec-Purpose: Prefetch
4 participants