import { Handler } from 'http-kernel/Types/mod.ts'; import { Env } from './env.ts'; /** * Forwards the incoming request to the actual LanguageTool server. * Dynamically passes through path and query string. * Removes `username` and `apiKey` from the FormData body if present. */ export const handler: Handler = async (ctx) => { const originalUrl = new URL(ctx.req.url); const proxyUrl = new URL( `${originalUrl.pathname}${originalUrl.search}`, `http://${Env.ltServerHost}:${Env.ltServerPort}`, ); const contentType = ctx.req.headers.get('content-type') ?? ''; let body: BodyInit | null = null; if ( contentType.includes('application/x-www-form-urlencoded') && ctx.state.body ) { const text = new TextDecoder().decode(ctx.state.body as Uint8Array); const params = new URLSearchParams(text); // Remove `apiKey` and `username` from the params // LanguageTool will react with a error if they are present params.delete('apiKey'); params.delete('username'); body = params.toString(); } else { console.debug('Unsupported content type:', contentType); body = ctx.state.body as BodyInit | null; } const headers = new Headers(ctx.req.headers); headers.delete('content-length'); console.debug('Forwarding request to:', proxyUrl.toString()); const forwarded = await fetch(proxyUrl.toString(), { method: ctx.req.method, headers, body, }); console.debug('Received response from LT server:', forwarded.status); const respHeaders = new Headers(forwarded.headers); return new Response(forwarded.body, { status: forwarded.status, headers: respHeaders, }); }; export { handler as ltProxyHandler };