Key Observations:
- The code implements a basic reverse proxy that:
- Routes requests through a specific domain (stratosphericus.workers.dev)
- Rewrites URLs in HTML responses
- Handles CORS
- Manages cookies
- Supports redirects
Potential Issues & Improvements:
- URL Parsing Logic
if (url.pathname.startsWith('/')) {
targetURL = new URL(url.pathname.substring(1))
} else {
targetURL = new URL(url.pathname)
}
- This assumes the path always contains a valid URL after the first character
- Could throw an error if the substring isn't a valid URL Suggested fix:
try {
targetURL = new URL(url.pathname.startsWith('/') ? url.pathname.substring(1) : url.pathname);
} catch (e) {
return new Response('Invalid target URL', { status: 400 });
}
- Protocol Handling
if (!targetURL.toString().startsWith('http')) {
targetURL = new URL(targetURL, `https://${myURL.hostname}/${new URL(request.url).protocol}////${request.url.host.toString()}/`)
}
- Multiple slashes (////) might cause parsing issues
- Complex base URL construction could be simplified Suggested fix:
if (!targetURL.protocol) {
targetURL = new URL(`${targetURL}`, `https://${myURL.hostname}/`);
}
- Header Management
- Setting both 'host' and 'origin' to the same value might not be necessary
- Consider preserving the original Origin header for some use cases Suggestion:
newHeader.set('Host', targetURL.host);
// Only set Origin if needed
if (request.headers.get('Origin')) {
newHeader.set('Origin', targetURL.origin);
}
- CORS Configuration
newRespHeader.set('Access-Control-Allow-Origin', '*');
newRespHeader.set('Access-Control-Allow-Methods', '*');
- Wildcard (*) might be too permissive for some use cases
- Consider mirroring the request's Origin or using specific allowed methods Suggestion:
newRespHeader.set('Access-Control-Allow-Origin', request.headers.get('Origin') || '*');
newRespHeader.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
- HTML Rewriting
- The rewriteSomething class has inconsistent protocol checking:
if (!eleThings.startsWith('http') || !eleThings.startsWith('https'))
- This will always be true due to OR condition (should be AND) Suggested fix:
if (!eleThings.startsWith('http://') && !eleThings.startsWith('https://'))
- Error Handling
- Current try/catch is good but could provide more specific error messages Suggestion:
try {
let response = await fetch(newRequest);
// ... rest of code
} catch (error) {
let message = 'Internal Server Error';
if (error.name === 'TypeError') message = 'Invalid URL or network error';
return new Response(`Proxy Error: ${message}`, {
status: 500,
headers: {
'Content-Type': 'text/plain',
'Access-Control-Allow-Origin': '*'
}
});
}
Additional Recommendations:
- Add input validation for URLs
- Implement rate limiting
- Add caching where appropriate
- Consider adding request timeout handling
- Add logging for debugging/monitoring
Here's a cleaned-up version of the critical section:
async function handleRequest(request) {
const url = new URL(request.url);
// Determine target URL
let targetURL;
if (url.host === myURL.host) {
try {
targetURL = new URL(url.pathname.startsWith('/') ? url.pathname.substring(1) : url.pathname);
} catch (e) {
return new Response('Invalid target URL', { status: 400 });
}
} else {
targetURL = url;
}
// Ensure protocol
if (!targetURL.protocol) {
targetURL = new URL(`${targetURL}`, `https://${myURL.hostname}/`);
}
// Prepare headers
const newHeader = new Headers(request.headers);
newHeader.set('Host', targetURL.host);
const newRequest = new Request(targetURL, {
method: request.method,
headers: newHeader,
body: request.body,
cf: { ssl: { verify: false } }
});
// ... rest of the function
}