fix: send requests that rank text/html below another type to the endpoint - #17186
SulimanAbdulrazzaq wants to merge 3 commits into
Conversation
…oint is_endpoint_request called negotiate(accept, ['*', 'text/html']). The '*' entry only matches a literal */* range, so any accept header that named text/html at all was treated as a page request, whatever quality it gave it. Feed readers such as FreshRSS send 'application/atom+xml, ..., text/html;q=0.7, ...' and got the page instead of the +server.js feed. Add a prefers_html helper that returns true only when text/html (or text/*) has the highest quality in the header, which is what the docs describe, and use it in is_endpoint_request. Fixes sveltejs#13834
|
Install the latest version of pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/f110b735de19d546486d257032bf27d2b55241e7Open in Note This PR is from a fork. A maintainer must approve approve each commit before it can be built and installed. |
🦋 Changeset detectedLatest commit: f110b73 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
kdelay
left a comment
There was a problem hiding this comment.
parse_accept only reads q right after the subtype, so application/json;charset=utf-8;q=0.5 parses as q=1. Since prefers_html now compares against the top q of all ranges, these go to the endpoint even though text/html ranks highest (page requests before this PR):
text/html;q=0.9, application/signed-exchange;v=b3;q=0.7
text/html;q=0.8, application/json;charset=utf-8;q=0.5
Reading q separately fixed both locally and kept the existing cases passing:
const q = /;[ \t]*q=([0-9.]+)/.exec(str)?.[1] ?? '1';parse_accept only read q directly after the subtype, so a range such as application/json;charset=utf-8;q=0.5 was treated as q=1 and could outrank text/html.
|
@kdelay Thanks, good catch. The parsing predates this PR (it's the regex Fixed in b841ee5 using your approach: |
|
@Rich-Harris @teemingc when you have a moment, could one of you take a look at this one? |
closes #13834
When a route has both
+page.svelteand+server.js, the docs sayGET/POST/HEADrequests are page requests "if theacceptheader prioritisestext/html".is_endpoint_requestchecked this withnegotiate(accept, ['*', 'text/html']) !== 'text/html'. But'*'only matches a literal*/*range. As a result, anyacceptheader that namestext/htmlat all was treated as a page request, whatever quality it gave it.Feed readers hit this. SimplePie, which FreshRSS uses, sends
application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1, and gets the page instead of the feed from+server.js.This PR adds a
prefers_html(accept)helper next tonegotiateinutils/http.js, and uses it inis_endpoint_request. It returnstrueonly whentext/html(ortext/*) has the highest quality in the header, ties included.negotiateitself is unchanged: its parsing and sorting moved into a sharedparse_accept.Behaviour for other headers stays the same:
*/*, a missingacceptheader andapplication/jsonstill go to the endpoint.use:enhancesubmission still gets the page.The new
is_endpoint_requesttests cover these cases and pass both before and after the change.Tests:
src/runtime/server/endpoint.spec.js(new):is_endpoint_requestwith a browser navigation, the SimplePie header,application/json, text/html;q=0.9,*/*, no header, and ause:enhancePOST.src/utils/http.spec.js:prefers_htmlcases.test/apps/basics/test/vitest/server.spec.js: a request to/routing/content-negotiationwith the SimplePie header now reaches the endpoint. Before this change, the page HTML came back.Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm testand lint the project withpnpm lintandpnpm checkChangesets
pnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.Edits