|
/** |
|
* Welcome to Cloudflare Workers! This is your first worker. |
|
* Learn more at https://developers.cloudflare.com/workers/ |
|
*/ |
|
|
|
export default { |
|
async fetch(request, env, ctx) { |
|
const url = new URL(request.url); |
|
const method = request.method; |
|
const headers = new Headers(request.headers); |
|
const origin = url.origin; |
|
const host = url.host; |
|
headers.delete('Referrer'); |
|
headers.delete('Host'); |
|
const domainMapper = { |
|
'https://sh.rustup.rs': '/sh', |
|
'https://win.rustup.rs': '/win', |
|
'https://rustup.rs': '/apex', |
|
'https://www.rust-lang.org': '/org', |
|
}; |
|
if (url.pathname == '/' || url.pathname == '/index.html') { |
|
const pageResponse = await fetch('https://rustup.rs'); |
|
const html = await pageResponse.text(); |
|
const newBody = html |
|
.replace(/(<\s*title[^>]*>)([^<]*)(<\/\s*title[^>]*>)/, '$1(A reverse proxied) $2 (Powered by Cloudflare Workers)$3') |
|
.replaceAll(/https:\/\/(?:(?:sh\.|win\.)?rustup.rs|www\.rust-lang\.org)/g, (match) => origin + domainMapper[match]) |
|
.replaceAll(/((?:href|src)=")\/?(?!https:\/\/)([^"#]+)(")/g, '$1/apex/$2"') |
|
; |
|
const injectPos = newBody.indexOf('>', newBody.indexOf('<body')); |
|
const headers = new Headers(pageResponse.headers); |
|
const nonce = btoa(new TextDecoder('utf-16').decode(new Uint16Array(crypto.getRandomValues(new Uint8Array(32))))); |
|
headers.set( |
|
'Content-Security-Policy', |
|
headers.get('Content-Security-Policy').replace('style-src', `style-src 'nonce-${nonce}'`) |
|
); |
|
return new Response(newBody.slice(0, injectPos + 1) + ` |
|
<div id="mirror-notes"> |
|
<style nonce="${nonce}"> |
|
#mirror-notes {font-size: medium; width: 80%; background-color: rgba(83, 153, 207, 0.5); padding: 30px;border-radius: 25px;} |
|
#mirror-notes * {text-align: left;} |
|
#mirror-notes pre {overflow: auto;} |
|
</style> |
|
<p><em>This is a (reverse proxied) mirror (powered by Cloudflare Workers) of the official <a href="https://rustup.rs">rustup.rs</a> while <a href="https://static.rust-lang.org" rel="nofollow">static.rust-lang.org</a> is also proxied.</em></p> |
|
<p><em><strong>Usage</strong>: Visit this website, or configure these environment variables for <code>rustup</code> :</em></p> |
|
<ul> |
|
<li><code>RUSTUP_DIST_SERVER</code>: <code>https://${host}</code></li> |
|
<li><code>RUSTUP_UPDATE_ROOT</code>: <code>https://${host}/rustup</code></li> |
|
</ul> |
|
<div><em>Bash:</em></div> |
|
<div class="highlight highlight-source-shell"> |
|
<pre>CUSTOM_RUSTUP_DOMAIN='${host}' |
|
export RUSTUP_DIST_SERVER="https://$CUSTOM_RUSTUP_DOMAIN" |
|
export RUSTUP_UPDATE_ROOT="https://$CUSTOM_RUSTUP_DOMAIN/rustup"</pre></div> |
|
<div><em>PowerShell:</em></div> |
|
<div class="highlight highlight-source-powershell"> |
|
<pre>$CUSTOM_RUSTUP_DOMAIN='${host}' |
|
$env:RUSTUP_DIST_SERVER="https://$CUSTOM_RUSTUP_DOMAIN" |
|
$env:RUSTUP_UPDATE_ROOT="https://$CUSTOM_RUSTUP_DOMAIN/rustup" |
|
</pre> |
|
</div> |
|
</div>` |
|
+ newBody.slice(injectPos + 1), {headers}); |
|
} |
|
if (url.pathname.startsWith('/sh')) { |
|
const response = await fetch(new URL(url.pathname.slice(3), 'https://sh.rustup.rs'), {method, headers}); |
|
const content = await response.text(); |
|
return new Response(content.replaceAll('static.rust-lang.org', host), {headers: response.headers}); |
|
} |
|
if (url.pathname.startsWith('/win')) { |
|
return fetch(new URL(url.pathname.slice(4), 'https://win.rustup.rs'), {method, headers}); |
|
} |
|
if (url.pathname.startsWith('/apex')) { |
|
const response = await fetch(new URL(url.pathname.slice(5), 'https://rustup.rs'), {method, headers}); |
|
if (response.headers.get('content-type').startsWith('text/')) { |
|
return new Response((await response.text()) |
|
.replaceAll(/https:\/\/(?:(?:sh\.|win\.)?rustup.rs|www\.rust-lang\.org)/g, (match) => origin + domainMapper[match]) |
|
, { |
|
headers: response.headers, |
|
}); |
|
} |
|
return response; |
|
} |
|
if (url.pathname.startsWith('/org')) { |
|
return fetch(new URL(url.pathname.slice(4), 'https://www.rust-lang.org'), {method, headers}); |
|
} |
|
return fetch(new URL(url.pathname, 'https://static.rust-lang.org/'), { |
|
method: request.method, |
|
headers, |
|
}); |
|
}, |
|
}; |