mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Use Accept header for skills HTML/markdown negotiation (#1454)
## Summary Follow-up to #1452. `Sec-Fetch-Mode` / `Sec-Fetch-Dest` didn't reliably split HTML vs. markdown at the CDN edge, so curl could still get the HTML landing page. Switch to the `Accept` header: - Browsers send `Accept: text/html,...` on top-level navigations. - `curl`, `fetch()`, and agent fetchers send `*/*` or omit `Accept`. - Serve HTML only when `text/html` is explicitly listed; everything else gets `SKILL.md`. - `Vary` updated to `Accept` to match. ## Test plan - [ ] Deploy preview - [ ] `curl -sSL https://skill.stack-auth.com/ | head -3` returns markdown frontmatter - [ ] Browser load of `https://skill.stack-auth.com/` still shows the HTML landing page - [ ] Purge Vercel cache if stale variants persist <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved content format negotiation for skill resources to correctly serve HTML or markdown based on client requests. * **Chores** * Optimized caching behavior for edge and CDN services to enhance global content distribution efficiency. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1454?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
055304d3fd
commit
a84c7814de
@ -211,7 +211,7 @@ For the full, current flag list and any commands added after this skill was gene
|
||||
const COMMON_HEADERS = {
|
||||
"Cache-Control": "public, max-age=3600, s-maxage=3600",
|
||||
// CDN must cache markdown (curl/agents) and HTML (browser navigate) separately.
|
||||
"Vary": "Sec-Fetch-Mode, Sec-Fetch-Dest",
|
||||
"Vary": "Accept",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, HEAD, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
@ -431,12 +431,18 @@ function renderHtml(): string {
|
||||
</html>`;
|
||||
}
|
||||
|
||||
const MARKDOWN_PREFERRING_TYPES = new Set(["*/*", "text/plain", "text/markdown", "text/x-markdown"]);
|
||||
|
||||
function wantsHtml(req: Request): boolean {
|
||||
// Browsers navigating to a top-level URL send Sec-Fetch-Mode: navigate.
|
||||
// curl, fetch(), and agent fetchers do not, so they keep getting markdown.
|
||||
if (req.headers.get("sec-fetch-mode") === "navigate") return true;
|
||||
if (req.headers.get("sec-fetch-dest") === "document") return true;
|
||||
return false;
|
||||
// Browsers send `Accept: text/html,...` before `*/*`; curl/fetch/agents send
|
||||
// `*/*` (or omit Accept). Serve HTML only when text/html appears AND is
|
||||
// listed before any markdown-preferring type that would otherwise win.
|
||||
const accept = req.headers.get("accept") ?? "";
|
||||
const types = accept.split(",").map((part) => part.trim().split(";")[0].trim().toLowerCase());
|
||||
const htmlIndex = types.indexOf("text/html");
|
||||
if (htmlIndex === -1) return false;
|
||||
const competitorIndex = types.findIndex((t) => MARKDOWN_PREFERRING_TYPES.has(t));
|
||||
return competitorIndex === -1 || htmlIndex < competitorIndex;
|
||||
}
|
||||
|
||||
export function GET(req: Request) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user