HTTP Proxy на чистой ноде
Forward-прокси без библиотек: HTTP — через
http.request, HTTPS — через CONNECT-туннель из двух pipe.
Что это
HTTP-прокси принимает запрос от клиента и перепосылает его на нужный хост. Два режима:
- HTTP — прокси видит полный запрос (URL, headers, body); может модифицировать.
- HTTPS — клиент шлёт
CONNECT host:443 HTTP/1.1; прокси открывает TCP к таргету и просто перекидывает байты в обе стороны. Заголовки внутри TLS прокси не видит.
API / Пример
const http = require('http');
const net = require('net');
const proxy = http.createServer((req, res) => {
// Обычный HTTP — пайпим в targeted-сервер
const { hostname, port, path } = new URL(req.url);
const upstream = http.request({ hostname, port, path, method: req.method, headers: req.headers });
req.pipe(upstream);
upstream.on('response', (upRes) => {
res.writeHead(upRes.statusCode, upRes.headers);
upRes.pipe(res);
});
});
// HTTPS: туннель через CONNECT
proxy.on('connect', (req, clientSocket, head) => {
const { hostname, port } = new URL('https://' + req.url);
const upstream = net.connect(port || 443, hostname, () => {
clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
if (head.length) upstream.write(head);
upstream.pipe(clientSocket);
clientSocket.pipe(upstream);
});
});
proxy.listen(8080);
Производительность / Подводные камни
- HTTP всегда CRLF (
\r\n) — даже на Linux, где OS EOL =\n. Не использоватьos.EOL. - Двойной CRLF разделяет заголовки и тело.
- HTTPS-прокси не видит контент — это просто TCP-туннель; для MITM нужна своя CA и подмена сертификатов.
pipeне обрабатывает все события — error/close нужно ловить вручную, иначе утечки сокетов.new URLиспользует Ada-парсер — быстро и корректно по RFC.socketв connect-обработчике — writable — пишем туда HTTP-ответ как байты.
🎓 Источники
- 🎓 Node.js HTTP Proxy — ревью примеров кода · 2023-11-29
- Тезисы: HTTP-прокси через
http.requestи пайпы; HTTPS — через событиеconnectи двусторонний TCP-pipe;\r\n(CRLF) — стандарт HTTP независимо от OS;new URLиспользует Ada; имена из RFC должны быть в библиотеке (предложение константы EOL для http-модуля). - Цитата: «HTTP всегда
\r\n— независимо от того, какой EOL у операционки.»
- Тезисы: HTTP-прокси через