Last active
February 2, 2024 19:17
-
-
Save pnlybubbles/069c5d7222ea18b7513a01e731fb5647 to your computer and use it in GitHub Desktop.
Reverse Proxy (`pnpm dlx tsx proxy.ts`)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { IncomingMessage } from 'http' | |
import http from 'http' | |
import httpProxy from 'http-proxy' | |
import chalk from 'chalk' | |
type Target = { host: string; port: number } | |
type PathMapping = { '*': Target } & { [key: `/${string}`]: Target } | |
const MAPPING = { | |
// http://localhost:8080/api/hello -> http://localhost:8787/api/hello | |
'/api': { port: 8787, host: 'localhost' }, | |
// http://localhost:8080/otherwise -> http://localhost:5173/otherwise | |
'*': { port: 5173, host: 'localhost' }, | |
} satisfies PathMapping | |
const PROXY = { port: 8080, host: 'localhost' } | |
const { '*': DEFAULT_TARGET, ...PRIORITY_MAPPING } = MAPPING | |
function target(req: IncomingMessage) { | |
const { pathname } = new URL(req.url ?? '', `http://${req.headers.host}`) | |
for (const [path, target] of Object.entries(PRIORITY_MAPPING)) { | |
if (pathname === path || pathname?.startsWith(`${path}/`)) { | |
return target | |
} | |
} | |
return DEFAULT_TARGET | |
} | |
const proxy = httpProxy.createProxyServer({}) | |
const server = http.createServer((req, res) => { | |
proxy.web(req, res, { target: target(req) }) | |
}) | |
server.on('upgrade', function (req, socket, head) { | |
proxy.ws(req, socket, head, { target: target(req) }) | |
}) | |
server.listen(PROXY.port, () => { | |
const PAD = ' ' | |
const TO = chalk.green(' → ') | |
console.log( | |
`${chalk.whiteBright.bold('Proxy:')} ${chalk.cyan(`http://${PROXY.host}:`)}${chalk.cyanBright.bold(PROXY.port)}`, | |
) | |
const maxPath = Math.max(...Object.keys(PRIORITY_MAPPING).map((v) => v.length)) | |
for (const [path, { host, port }] of Object.entries(PRIORITY_MAPPING)) { | |
console.log( | |
`${PAD}${chalk.gray(`${PROXY.host}:${PROXY.port}`)}${chalk.whiteBright.bold(path.padEnd(maxPath))}${TO}${chalk.gray(`${host}:`)}${chalk.whiteBright.bold(port)}${chalk.gray(path)}`, | |
) | |
} | |
console.log( | |
`${PAD}${chalk.gray(`${PROXY.host}:${PROXY.port}`)}${chalk.whiteBright.bold('/*'.padEnd(maxPath))}${TO}${chalk.gray(`${DEFAULT_TARGET.host}:`)}${chalk.whiteBright.bold(DEFAULT_TARGET.port)}${chalk.gray('/*')}`, | |
) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment