import assert from "node:assert/strict"; import { spawn } from "node:child_process"; import { readFileSync } from "node:fs"; import { createServer } from "node:http"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; const docsRoot = dirname(dirname(fileURLToPath(import.meta.url))); const nextBin = join(docsRoot, "node_modules/next/dist/bin/next"); async function availablePort() { const server = createServer(); await new Promise((resolve, reject) => server.listen(0, "127.0.0.1", resolve).once("error", reject)); const address = server.address(); assert.ok(address && typeof address === "object"); await new Promise(resolve => server.close(resolve)); return address.port; } async function waitForServer(origin, child) { for (let attempt = 0; attempt < 100; attempt += 1) { if (child.exitCode !== null) throw new Error(`Next server exited with code ${child.exitCode}`); try { const response = await fetch(`${origin}/robots.txt`); if (response.ok) return; } catch {} await new Promise(resolve => setTimeout(resolve, 100)); } throw new Error("Timed out waiting for the Next production server."); } async function stop(child) { if (child.exitCode !== null) return; child.kill("SIGTERM"); await new Promise(resolve => { const timer = setTimeout(() => { if (child.exitCode === null) { child.kill("SIGKILL"); } resolve(); }, 5_000); child.once("exit", () => { clearTimeout(timer); resolve(); }); }); } const port = await availablePort(); const origin = `http://localhost:${port}`; let victimHits = 0; const victim = createServer((_request, response) => { victimHits += 1; response.writeHead(200, { "Content-Type": "text/html" }); response.end("

Internal secret

Do not expose this response.

"); }); await new Promise((resolve, reject) => victim.listen(0, "127.0.0.1", resolve).once("error", reject)); const victimAddress = victim.address(); assert.ok(victimAddress && typeof victimAddress === "object"); const child = spawn(process.execPath, [nextBin, "start", "--hostname", "localhost", "--port", String(port)], { cwd: docsRoot, env: { ...process.env, NEXT_TELEMETRY_DISABLED: "1" }, stdio: ["ignore", "pipe", "pipe"], }); let serverOutput = ""; child.stdout.on("data", chunk => (serverOutput += chunk)); child.stderr.on("data", chunk => (serverOutput += chunk)); try { await waitForServer(origin, child); const html = await fetch(`${origin}/`, { headers: { Accept: "text/html" }, redirect: "manual" }); assert.equal(html.status, 200); const htmlVary = html.headers.get("vary") ?? ""; const htmlCacheControl = html.headers.get("cache-control") ?? ""; const htmlBody = await html.text(); assert.ok(htmlBody.length >= 500, "The server-rendered homepage must contain substantial raw HTML."); assert.match(htmlBody, /)/i); assert.match(htmlBody, /)/i); assert.match(htmlBody, /)/i); assert.ok( /(?:^|,)\s*Accept\s*(?:,|$)/i.test(htmlVary) || /(?:private|no-store)/i.test(htmlCacheControl), "The local HTML variant must either vary on Accept or be unavailable to shared caches." ); const vercelConfig = JSON.parse(readFileSync(join(docsRoot, "vercel.json"), "utf8")); const deployedVary = vercelConfig.headers?.[0]?.headers?.find(header => header.key.toLowerCase() === "vary")?.value; for (const token of [ "Accept", "Accept-Encoding", "RSC", "Next-Router-State-Tree", "Next-Router-Prefetch", "Next-Router-Segment-Prefetch", ]) { assert.match(deployedVary ?? "", new RegExp(`(?:^|,)\\s*${token}\\s*(?:,|$)`, "i")); } const markdown = await fetch(`${origin}/`, { headers: { Accept: "text/markdown" } }); assert.equal(markdown.status, 200); assert.match(markdown.headers.get("content-type") ?? "", /^text\/markdown/); assert.match(markdown.headers.get("vary") ?? "", /(?:^|,)\s*Accept\s*(?:,|$)/i); assert.match(await markdown.text(), /^# Rybbit/m); const markdownHead = await fetch(`${origin}/`, { method: "HEAD", headers: { Accept: "text/markdown" } }); assert.equal(markdownHead.status, 200); assert.match(markdownHead.headers.get("content-type") ?? "", /^text\/markdown/); assert.equal(await markdownHead.text(), ""); const docsMarkdown = await fetch(`${origin}/docs/api/getting-started`, { headers: { Accept: "text/markdown" }, }); assert.equal(docsMarkdown.status, 200); assert.match(docsMarkdown.headers.get("content-type") ?? "", /^text\/markdown/); assert.match(await docsMarkdown.text(), /^# /m); const unacceptable = await fetch(`${origin}/`, { headers: { Accept: "application/pdf" } }); assert.equal(unacceptable.status, 406); assert.match(unacceptable.headers.get("vary") ?? "", /(?:^|,)\s*Accept\s*(?:,|$)/i); const hostilePath = `//127.0.0.1:${victimAddress.port}/internal`; const ssrf = await fetch(`${origin}/api/agent/markdown?path=${encodeURIComponent(hostilePath)}`); assert.equal(ssrf.status, 400); assert.match(ssrf.headers.get("content-type") ?? "", /^application\/json/); assert.equal((await ssrf.json()).code, "INVALID_MARKDOWN_PATH"); assert.equal(victimHits, 0); const newline = await fetch(`${origin}/api/agent/markdown?path=${encodeURIComponent("/bad\npath")}`); assert.equal(newline.status, 400); assert.equal((await newline.json()).code, "INVALID_MARKDOWN_PATH"); const recursive = await fetch( `${origin}/api/agent/markdown?path=${encodeURIComponent("/api/agent/markdown")}` ); assert.equal(recursive.status, 400); assert.equal((await recursive.json()).code, "INVALID_MARKDOWN_PATH"); const redirect = await fetch(`${origin}/tools/instagram-logo-generator`, { headers: { Accept: "text/markdown" }, redirect: "manual", }); assert.equal(redirect.status, 308); assert.equal(new URL(redirect.headers.get("location"), origin).pathname, "/tools"); const missing = await fetch(`${origin}/agent-http-test-missing`, { headers: { Accept: "text/markdown" }, }); assert.equal(missing.status, 404); assert.match(await missing.text(), /^# Page not found/m); const htmlMissing = await fetch(`${origin}/agent-http-test-missing`, { headers: { Accept: "text/html" }, redirect: "manual", }); assert.equal(htmlMissing.status, 404); assert.match(await htmlMissing.text(), /Page not found/); const openapi = await fetch(`${origin}/openapi.json`); assert.equal(openapi.status, 200); assert.match(openapi.headers.get("content-type") ?? "", /^application\/json/); const openapiDocument = await openapi.json(); assert.equal(openapiDocument.openapi, "3.1.1"); const openapiAlias = await fetch(`${origin}/api/openapi.json`); assert.equal(openapiAlias.status, 200); assert.deepEqual(await openapiAlias.json(), openapiDocument); const openapiHead = await fetch(`${origin}/openapi.json`, { method: "HEAD" }); assert.equal(openapiHead.status, 200); assert.match(openapiHead.headers.get("content-type") ?? "", /^application\/json/); assert.equal(await openapiHead.text(), ""); const llms = await fetch(`${origin}/llms.txt`); assert.equal(llms.status, 200); assert.match(llms.headers.get("content-type") ?? "", /^text\/plain/); assert.match(await llms.text(), /OpenAPI specification/); const llmsFull = await fetch(`${origin}/llms-full.txt`); assert.equal(llmsFull.status, 200); assert.match(llmsFull.headers.get("content-type") ?? "", /^text\/plain/); const sitemap = await fetch(`${origin}/sitemap.xml`); assert.equal(sitemap.status, 200); assert.match(sitemap.headers.get("content-type") ?? "", /xml/); const robots = await fetch(`${origin}/robots.txt`); assert.equal(robots.status, 200); assert.match(await robots.text(), /Allow: \/api\/openapi\.json/); const apiMissing = await fetch(`${origin}/api/agent-http-test-missing`); assert.equal(apiMissing.status, 404); assert.equal((await apiMissing.json()).code, "API_ROUTE_NOT_FOUND"); console.log("Agent HTTP integration checks passed."); } catch (error) { if (serverOutput) console.error(serverOutput); throw error; } finally { await stop(child); await new Promise(resolve => victim.close(resolve)); }