Skip to content
/ httpxy Public

πŸ”€ A Full-Featured HTTP and WebSocket Proxy for Node.js

License

Notifications You must be signed in to change notification settings

unjs/httpxy

Repository files navigation

πŸ”€ httpxy

npm version npm downloads bundle Codecov

A Full-Featured HTTP and WebSocket Proxy for Node.js

Proxy Fetch

proxyFetch is a proxy utility with web standard (Request/Response) interfaces. It forwards requests to a specific server address (TCP host/port or Unix socket), bypassing the URL's hostname.

import { proxyFetch } from "httpxy";

// TCP β€” using a URL string
const res = await proxyFetch("http://127.0.0.1:3000", "http://example.com/api/data");
console.log(await res.json());

// Unix socket β€” using a URL string
const res2 = await proxyFetch("unix:/tmp/app.sock", "http://localhost/health");
console.log(await res2.text());

// Or use an object for more control
const res3 = await proxyFetch({ host: "127.0.0.1", port: 3000 }, "http://example.com/api/data");

// Using a Request object
const req = new Request("http://example.com/api/data", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ key: "value" }),
});
const res4 = await proxyFetch("http://127.0.0.1:3000", req);

// Using a URL string with RequestInit
const res5 = await proxyFetch("http://127.0.0.1:3000", "http://example.com/api/data", {
  method: "PUT",
  headers: { Authorization: "Bearer token" },
  body: JSON.stringify({ updated: true }),
});

It accepts the same input and init arguments as the global fetch, including Request objects and streaming bodies, and returns a standard Response. Redirects are handled manually by default.

Proxy Server

Note

Proxy server was originally forked from http-party/node-http-proxy.

Create proxy:

import { createServer } from "node:http";
import { createProxyServer } from "httpxy";

const proxy = createProxyServer({});

const server = createServer(async (req, res) => {
  try {
    await proxy.web(req, res, {
      target: address /* address of your proxy server here */,
    });
  } catch (error) {
    console.error(error);
    res.statusCode = 500;
    res.end("Proxy error: " + error.toString());
  }
});

server.listen(3000, () => {
  console.log("Proxy is listening on http://localhost:3000");
});

Options

Option Type Default Description
target string | URL | ProxyTargetDetailed β€” Target server URL
forward string | URL β€” Forward server URL (pipes request without the target's response)
agent http.Agent β€” Object passed to http(s).request for connection pooling
ssl https.ServerOptions β€” Object passed to https.createServer()
ws boolean false Enable WebSocket proxying
xfwd boolean false Add x-forwarded-* headers
secure boolean β€” Verify SSL certificates
toProxy boolean false Pass absolute URL as path (proxy-to-proxy)
prependPath boolean true Prepend the target's path to the proxy path
ignorePath boolean false Ignore the incoming request path
localAddress string β€” Local interface to bind for outgoing connections
changeOrigin boolean false Change the Host header to match the target URL
preserveHeaderKeyCase boolean false Keep original letter case of response header keys
auth string β€” Basic authentication ('user:password') for Authorization header
hostRewrite string β€” Rewrite the Location hostname on redirects (301/302/307/308)
autoRewrite boolean false Rewrite Location host/port on redirects based on the request
protocolRewrite string β€” Rewrite Location protocol on redirects ('http' or 'https')
cookieDomainRewrite false | string | object false Rewrite domain of Set-Cookie headers
cookiePathRewrite false | string | object false Rewrite path of Set-Cookie headers
headers object β€” Extra headers to add to target requests
proxyTimeout number 120000 Timeout (ms) for the proxy request to the target
timeout number β€” Timeout (ms) for the incoming request
selfHandleResponse boolean false Disable automatic response piping (handle proxyRes yourself)
followRedirects boolean | number false Follow HTTP redirects from target. true = max 5 hops; number = custom max
buffer stream.Stream β€” Stream to use as request body instead of the incoming request

Events

Event Arguments Description
error (err, req, res, target) An error occurred during proxying
proxyReq (proxyReq, req, res, options) Before request is sent to target (modify headers here)
proxyRes (proxyRes, req, res) Response received from target
proxyReqWs (proxyReq, req, socket, options, head) Before WebSocket upgrade request is sent
open (proxySocket) WebSocket connection opened
close (proxyRes, proxySocket, proxyHead) WebSocket connection closed
start (req, res, target) Proxy processing started
end (req, res, proxyRes) Proxy request completed

Examples

HTTP Proxy

import { createServer } from "node:http";
import { createProxyServer } from "httpxy";

const proxy = createProxyServer({});

const server = createServer(async (req, res) => {
  await proxy.web(req, res, { target: "http://localhost:8080" });
});

server.listen(3000);

WebSocket Proxy

import { createServer } from "node:http";
import { createProxyServer } from "httpxy";

const proxy = createProxyServer({ target: "http://localhost:8080", ws: true });

const server = createServer(async (req, res) => {
  await proxy.web(req, res);
});

server.on("upgrade", (req, socket, head) => {
  proxy.ws(req, socket, { target: "http://localhost:8080" }, head);
});

server.listen(3000);

Modify Request Headers

import { createServer } from "node:http";
import { createProxyServer } from "httpxy";

const proxy = createProxyServer({ target: "http://localhost:8080" });

proxy.on("proxyReq", (proxyReq) => {
  proxyReq.setHeader("X-Forwarded-By", "httpxy");
});

const server = createServer(async (req, res) => {
  await proxy.web(req, res);
});

server.listen(3000);

HTTPS Proxy

import { readFileSync } from "node:fs";
import { createProxyServer } from "httpxy";

const proxy = createProxyServer({
  ssl: {
    key: readFileSync("server-key.pem", "utf8"),
    cert: readFileSync("server-cert.pem", "utf8"),
  },
  target: "https://localhost:8443",
  secure: false, // allow self-signed certificates
});

proxy.listen(3000);

Standalone Proxy Server

import { createProxyServer } from "httpxy";

const proxy = createProxyServer({
  target: "http://localhost:8080",
  changeOrigin: true,
});

proxy.listen(3000);

Development

  • Clone this repository
  • Install latest LTS version of Node.js
  • Enable Corepack using corepack enable
  • Install dependencies using pnpm install
  • Run interactive tests using pnpm dev

License

Made with πŸ’›

Published under MIT License.

About

πŸ”€ A Full-Featured HTTP and WebSocket Proxy for Node.js

Resources

License

Stars

Watchers

Forks

Contributors 15