72 lines
2.6 KiB
JavaScript

export default {
async fetch(request) {
const url = new URL(request.url);
const tunnelHost = 'instructional-qty-curriculum-protected.trycloudflare.com';
const targetUrl = `https://${tunnelHost}${url.pathname}${url.search}`;
const modifiedHeaders = new Headers(request.headers);
modifiedHeaders.set('Host', tunnelHost);
modifiedHeaders.delete('cf-connecting-ip');
modifiedHeaders.delete('cf-ray');
modifiedHeaders.delete('cf-visitor');
const init = {
method: request.method,
headers: modifiedHeaders,
redirect: 'manual', // Handle redirects ourselves
};
if (request.method !== 'GET' && request.method !== 'HEAD') {
init.body = request.body;
}
const response = await fetch(targetUrl, init);
// Build response headers
const newHeaders = new Headers();
// Copy content-type
const ct = response.headers.get('content-type');
if (ct) newHeaders.set('Content-Type', ct);
// Copy ALL set-cookie headers (critical for Flask sessions)
const cookies = response.headers.getAll ? response.headers.getAll('set-cookie') : [];
if (cookies.length === 0) {
// Fallback for environments without getAll
const sc = response.headers.get('set-cookie');
if (sc) newHeaders.append('Set-Cookie', sc);
} else {
for (const c of cookies) {
newHeaders.append('Set-Cookie', c);
}
}
// Handle redirects — rewrite tunnel URLs to our domain
if (response.status >= 300 && response.status < 400) {
let loc = response.headers.get('location') || '';
loc = loc.replace(`https://${tunnelHost}`, 'https://thenichequiz.com');
// Also handle relative redirects
if (loc.startsWith('/')) loc = `https://thenichequiz.com${loc}`;
newHeaders.set('Location', loc);
return new Response(null, { status: response.status, headers: newHeaders });
}
// Copy content-disposition for CSV downloads
const cd = response.headers.get('content-disposition');
if (cd) newHeaders.set('Content-Disposition', cd);
// Copy content-length
const cl = response.headers.get('content-length');
if (cl) newHeaders.set('Content-Length', cl);
newHeaders.set('Cache-Control', 'no-cache, no-store, must-revalidate');
newHeaders.set('X-Content-Type-Options', 'nosniff');
// Stream the body directly (works for images, HTML, JSON, CSV, everything)
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders,
});
}
};