http-proxy-3
Version:
Modern rewrite of http-proxy
240 lines (239 loc) • 11.5 kB
TypeScript
import * as http from "node:http";
import * as net from "node:net";
import { EventEmitter } from "node:events";
import type { Stream } from "node:stream";
export interface ProxyTargetDetailed {
host: string;
port: number;
protocol?: string;
hostname?: string;
socketPath?: string;
key?: string;
passphrase?: string;
pfx?: Buffer | string;
cert?: string;
ca?: string;
ciphers?: string;
secureProtocol?: string;
}
export type ProxyType = "ws" | "web";
export type ProxyTarget = ProxyTargetUrl | ProxyTargetDetailed;
export type ProxyTargetUrl = URL | string | {
port: number;
host: string;
protocol?: string;
};
export type NormalizeProxyTarget<T extends ProxyTargetUrl> = Exclude<T, string> | URL;
export interface ServerOptions {
/** URL string to be parsed with the url module. */
target?: ProxyTarget;
/** URL string to be parsed with the url module or a URL object. */
forward?: ProxyTargetUrl;
/** Object to be passed to http(s).request. */
agent?: any;
/** Object to be passed to https.createServer(). */
ssl?: any;
/** If you want to proxy websockets. */
ws?: boolean;
/** Adds x- forward headers. */
xfwd?: boolean;
/** Verify SSL certificate. */
secure?: boolean;
/** Explicitly specify if we are proxying to another proxy. */
toProxy?: boolean;
/** Specify whether you want to prepend the target's path to the proxy path. */
prependPath?: boolean;
/** Specify whether you want to ignore the proxy path of the incoming request. */
ignorePath?: boolean;
/** Local interface string to bind for outgoing connections. */
localAddress?: string;
/** Changes the origin of the host header to the target URL. */
changeOrigin?: boolean;
/** specify whether you want to keep letter case of response header key */
preserveHeaderKeyCase?: boolean;
/** Basic authentication i.e. 'user:password' to compute an Authorization header. */
auth?: string;
/** Rewrites the location hostname on (301 / 302 / 307 / 308) redirects, Default: null. */
hostRewrite?: string;
/** Rewrites the location host/ port on (301 / 302 / 307 / 308) redirects based on requested host/ port.Default: false. */
autoRewrite?: boolean;
/** Rewrites the location protocol on (301 / 302 / 307 / 308) redirects to 'http' or 'https'.Default: null. */
protocolRewrite?: string;
/** rewrites domain of set-cookie headers. */
cookieDomainRewrite?: false | string | {
[oldDomain: string]: string;
};
/** rewrites path of set-cookie headers. Default: false */
cookiePathRewrite?: false | string | {
[oldPath: string]: string;
};
/** object with extra headers to be added to target requests. */
headers?: {
[header: string]: string | string[] | undefined;
};
/** Timeout (in milliseconds) when proxy receives no response from target. Default: 120000 (2 minutes) */
proxyTimeout?: number;
/** Timeout (in milliseconds) for incoming requests */
timeout?: number;
/** Specify whether you want to follow redirects. Default: false */
followRedirects?: boolean;
/** If set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event */
selfHandleResponse?: boolean;
/** Buffer */
buffer?: Stream;
/** Explicitly set the method type of the ProxyReq */
method?: string;
/**
* Optionally override the trusted CA certificates.
* This is passed to https.request.
*/
ca?: string;
/** Optional fetch implementation to use instead of global fetch, use this to activate fetch-based proxying,
* for example to proxy HTTP/2 requests
*/
fetch?: typeof fetch;
/** Optional configuration object for fetch-based proxy requests.
* Use this to customize fetch request and response handling.
* For custom fetch implementations, use the `fetch` property.*/
fetchOptions?: FetchOptions;
}
export interface FetchOptions {
/** Fetch request options */
requestOptions?: RequestInit;
/** Called before making the fetch request */
onBeforeRequest?: (requestOptions: RequestInit, req: http.IncomingMessage, res: http.ServerResponse, options: NormalizedServerOptions) => void | Promise<void>;
/** Called after receiving the fetch response */
onAfterResponse?: (response: Response, req: http.IncomingMessage, res: http.ServerResponse, options: NormalizedServerOptions) => void | Promise<void>;
}
export interface NormalizedServerOptions extends ServerOptions {
target?: NormalizeProxyTarget<ProxyTarget>;
forward?: NormalizeProxyTarget<ProxyTargetUrl>;
}
export type ErrorCallback<TIncomingMessage extends typeof http.IncomingMessage = typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse = typeof http.ServerResponse, TError = Error> = (err: TError, req: InstanceType<TIncomingMessage>, res: InstanceType<TServerResponse> | net.Socket, target?: ProxyTargetUrl) => void;
type ProxyServerEventMap<TIncomingMessage extends typeof http.IncomingMessage = typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse = typeof http.ServerResponse, TError = Error> = {
error: Parameters<ErrorCallback<TIncomingMessage, TServerResponse, TError>>;
start: [
req: InstanceType<TIncomingMessage>,
res: InstanceType<TServerResponse>,
target: ProxyTargetUrl
];
open: [socket: net.Socket];
proxyReq: [
proxyReq: http.ClientRequest,
req: InstanceType<TIncomingMessage>,
res: InstanceType<TServerResponse>,
options: ServerOptions,
socket: net.Socket
];
proxyRes: [
proxyRes: InstanceType<TIncomingMessage>,
req: InstanceType<TIncomingMessage>,
res: InstanceType<TServerResponse>
];
proxyReqWs: [
proxyReq: http.ClientRequest,
req: InstanceType<TIncomingMessage>,
socket: net.Socket,
options: ServerOptions,
head: any
];
econnreset: [
err: Error,
req: InstanceType<TIncomingMessage>,
res: InstanceType<TServerResponse>,
target: ProxyTargetUrl
];
end: [
req: InstanceType<TIncomingMessage>,
res: InstanceType<TServerResponse>,
proxyRes: InstanceType<TIncomingMessage>
];
close: [
proxyRes: InstanceType<TIncomingMessage>,
proxySocket: net.Socket,
proxyHead: any
];
};
type ProxyMethodArgs<TIncomingMessage extends typeof http.IncomingMessage = typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse = typeof http.ServerResponse, TError = Error> = {
ws: [
req: InstanceType<TIncomingMessage>,
socket: any,
head: any,
...args: [
options?: ServerOptions,
callback?: ErrorCallback<TIncomingMessage, TServerResponse, TError>
] | [callback?: ErrorCallback<TIncomingMessage, TServerResponse, TError>]
];
web: [
req: InstanceType<TIncomingMessage>,
res: InstanceType<TServerResponse>,
...args: [
options: ServerOptions,
callback?: ErrorCallback<TIncomingMessage, TServerResponse, TError>
] | [callback?: ErrorCallback<TIncomingMessage, TServerResponse, TError>]
];
};
type PassFunctions<TIncomingMessage extends typeof http.IncomingMessage = typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse = typeof http.ServerResponse, TError = Error> = {
ws: (req: InstanceType<TIncomingMessage>, socket: net.Socket, options: NormalizedServerOptions, head: Buffer | undefined, server: ProxyServer<TIncomingMessage, TServerResponse, TError>, cb?: ErrorCallback<TIncomingMessage, TServerResponse, TError>) => unknown;
web: (req: InstanceType<TIncomingMessage>, res: InstanceType<TServerResponse>, options: NormalizedServerOptions, head: Buffer | undefined, server: ProxyServer<TIncomingMessage, TServerResponse, TError>, cb?: ErrorCallback<TIncomingMessage, TServerResponse, TError>) => unknown;
};
export declare class ProxyServer<TIncomingMessage extends typeof http.IncomingMessage = typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse = typeof http.ServerResponse, TError = Error> extends EventEmitter<ProxyServerEventMap<TIncomingMessage, TServerResponse, TError>> {
/**
* Used for proxying WS(S) requests
* @param req - Client request.
* @param socket - Client socket.
* @param head - Client head.
* @param options - Additional options.
*/
readonly ws: (...args: ProxyMethodArgs<TIncomingMessage, TServerResponse, TError>["ws"]) => void;
/**
* Used for proxying regular HTTP(S) requests
* @param req - Client request.
* @param res - Client response.
* @param options - Additional options.
*/
readonly web: (...args: ProxyMethodArgs<TIncomingMessage, TServerResponse, TError>["web"]) => void;
private options;
private webPasses;
private wsPasses;
private _server?;
/**
* Creates the proxy server with specified options.
* @param options - Config object passed to the proxy
*/
constructor(options?: ServerOptions);
/**
* Creates the proxy server with specified options.
* @param options Config object passed to the proxy
* @returns Proxy object with handlers for `ws` and `web` requests
*/
static createProxyServer<TIncomingMessage extends typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse, TError = Error>(options?: ServerOptions): ProxyServer<TIncomingMessage, TServerResponse, TError>;
/**
* Creates the proxy server with specified options.
* @param options Config object passed to the proxy
* @returns Proxy object with handlers for `ws` and `web` requests
*/
static createServer<TIncomingMessage extends typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse, TError = Error>(options?: ServerOptions): ProxyServer<TIncomingMessage, TServerResponse, TError>;
/**
* Creates the proxy server with specified options.
* @param options Config object passed to the proxy
* @returns Proxy object with handlers for `ws` and `web` requests
*/
static createProxy<TIncomingMessage extends typeof http.IncomingMessage, TServerResponse extends typeof http.ServerResponse, TError = Error>(options?: ServerOptions): ProxyServer<TIncomingMessage, TServerResponse, TError>;
createRightProxy: <PT extends ProxyType>(type: PT) => Function;
onError: (err: TError) => void;
/**
* A function that wraps the object in a webserver, for your convenience
* @param port - Port to listen on
* @param hostname - The hostname to listen on
*/
listen: (port: number, hostname?: string) => this;
address: () => string | net.AddressInfo | null | undefined;
/**
* A function that closes the inner webserver and stops listening on given port
*/
close: (cb?: Function) => void;
before: <PT extends ProxyType>(type: PT, passName: string, cb: PassFunctions<TIncomingMessage, TServerResponse, TError>[PT]) => void;
after: <PT extends ProxyType>(type: PT, passName: string, cb: PassFunctions<TIncomingMessage, TServerResponse, TError>[PT]) => void;
}
export {};