-
Notifications
You must be signed in to change notification settings - Fork 7
/
proxy.js
76 lines (66 loc) · 2.53 KB
/
proxy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Current Version: 1.2.3
// Description: Using Cloudflare Workers to Reverse Proxy everything.
addEventListener( 'fetch', e => e.respondWith( fetchHandler( e ) ) )
async function fetchHandler ( e )
{
try
{
const req = e.request
const urlObj = new URL( req.url )
const targetUrl = urlObj.href.slice( urlObj.origin.length + 1 ).replace( /^https?:\/+/, 'https://' )
const filteredHeaders = new Headers()
req.headers.forEach( ( value, key ) =>
{
if ( !key.toLowerCase().startsWith( 'cf-' ) )
{
filteredHeaders.set( key, value )
}
} )
const res = await fetch( targetUrl, {
body: req.body,
headers: filteredHeaders,
method: req.method,
redirect: 'manual'
} )
const resHdr = new Headers( res.headers )
const deleteHeaders = [
'Content-Security-Policy',
'X-Frame-Options',
]
deleteHeaders.forEach( value => resHdr.delete( value ) )
const setHeaders = {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-store'
}
Object.entries( setHeaders ).forEach( ( [ key, value ] ) => resHdr.set( key, value ) )
if ( resHdr.has( 'Location' ) )
{
resHdr.set( 'Location', `${ urlObj.origin }/${ new URL( resHdr.get( 'Location' ), targetUrl ) }` )
return new Response( null, { status: res.status, headers: resHdr } )
}
const contentReplacements = {
"text/css": /(url\()\/(?!\/)/g,
"text/html": /((action|href|src)=["'])\/(?!\/)/g
}
for ( const [ contentType, regex ] of Object.entries( contentReplacements ) )
{
if ( resHdr.get( "Content-Type" )?.includes( contentType ) )
{
const body = ( await res.text() ).replace(
regex,
`$1${ urlObj.protocol }//${ urlObj.host }/${ new URL( targetUrl ).origin }/`
)
return new Response( body, { headers: resHdr, status: res.status } )
}
}
return new Response( res.body, { headers: resHdr, status: res.status } )
} catch ( error )
{
return new Response( JSON.stringify( { error: error.message } ), {
status: 500,
headers: { 'Content-Type': 'application/json; charset=utf-8' }
} )
}
}