kit icon indicating copy to clipboard operation
kit copied to clipboard

Endpoint fallback broken when Accept header includes lower-priority text/html

Open tuyuritio opened this issue 6 months ago • 0 comments

Describe the bug

In is_endpoint_request(), the code checks:

negotiate(accept, ['*', 'text/html']) !== 'text/html'

to determine if a request should be treated as an endpoint request (i.e. not a page/navigation). The intention appears to be to treat any request that does not prefer text/html as an endpoint call.

However, the underlying negotiate() implementation:

  1. Does not treat '*' as a wildcard to return the highest-priority MIME type.
  2. Always returns text/html if text/html appears anywhere in the Accept header, regardless of its relative quality factor (priority).

As a result, any request with an Accept header containing text/html (even if it has a lower quality than another MIME type) will be considered a "page" request, preventing the endpoint fallback from firing as documented.

Reproduction

  1. Create an /feed route containing both:
    • +page.svelte (HTML subscription prompt)
    • +server.ts (actual Atom XML feed)
  2. Send a request with a mixed Accept header, for example(mimicking FreshRSS's: DEFAULT_HTTP_ACCEPT_HEADER):
curl -H "Accept: application/atom+xml, text/html; q=0.1" http://localhost:5173/feed
  1. Because text/html appears (even with a lower quality), the request is negotiated as a page request, and the endpoint’s Atom XML is never returned.

Logs


System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (16) x64 AMD Ryzen 7 7840HS w/ Radeon 780M Graphics     
    Memory: 17.17 GB / 31.28 GB
  Binaries:
    Node: 23.10.0 - C:\Program Files\nodejs\node.EXE
    npm: 11.4.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (134.0.3124.68)
  npmPackages:
    @sveltejs/adapter-node: ^5.2.12 => 5.2.12
    @sveltejs/kit: ^2.21.1 => 2.21.1
    @sveltejs/vite-plugin-svelte: ^5.0.3 => 5.0.3
    svelte: ^5.31.1 => 5.31.1
    vite: ^6.3.5 => 6.3.5

Severity

serious, but I can work around it

Additional Information

I understand that mixing +page.svelte and +server.ts on the same route /feed is somewhat unconventional, but it’s a valid pattern for serving both human-friendly and machine-readable representations of the same resource.

Some feed readers may include text/html with low priority but expect the server to honor the higher-priority XML types.

Thank you for looking into this! Let me know if any further details or tests would help.

tuyuritio avatar May 27 '25 21:05 tuyuritio