// /rss.xml: the Journal API's RSS 2.0 feed, served from the site origin. // The visitor's x-forwarded-for is forwarded (plus the peer address) so the // API's rate limiter keeps one bucket per visitor. 404 when journal.rss is // false, 502 when the API does not answer. export default defineEventHandler(async (event) => { const config = useRuntimeConfig(event) if ((config.public.journal as { rss?: boolean }).rss === false) { throw createError({ statusCode: 404, statusMessage: 'Not found' }) } const base = (config.journal as { apiBase: string }).apiBase // Recorded by server/plugins/journal-client-address.ts before any route // cache hides the request headers. const forwarded = (event.context.journalForwardedFor as string | undefined) || [getRequestHeader(event, 'x-forwarded-for'), getRequestIP(event)] .filter((v): v is string => typeof v === 'string' && v !== '') .join(', ') let body: string try { body = await $fetch('/rss', { baseURL: base, responseType: 'text', headers: forwarded ? { 'x-forwarded-for': forwarded } : {}, }) } catch { setResponseStatus(event, 502) setResponseHeader(event, 'content-type', 'text/plain; charset=utf-8') return 'The feed is unavailable.' } setResponseHeader(event, 'content-type', 'application/rss+xml; charset=utf-8') return body })