Socket
Socket
Sign inDemoInstall

http-proxy-middleware

Package Overview
Dependencies
18
Maintainers
1
Versions
81
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.0-beta.0 to 3.0.0-beta.1

2

dist/configuration.d.ts
import { Options } from './types';
export declare function verifyConfig(options: Options): void;
export declare function verifyConfig<TReq, TRes>(options: Options<TReq, TRes>): void;
import type { Options, Plugin } from './types';
export declare function getPlugins(options: Options): Plugin[];
export declare function getPlugins<TReq, TRes>(options: Options<TReq, TRes>): Plugin<TReq, TRes>[];
/// <reference types="node" />
import type * as http from 'http';
import type { Request } from '../types';
export declare type BodyParserLikeRequest = http.IncomingMessage & {
body: any;
};
/**
* Fix proxied body if bodyParser is involved.
*/
export declare function fixRequestBody(proxyReq: http.ClientRequest, req: Request): void;
export declare function fixRequestBody<TReq = http.IncomingMessage>(proxyReq: http.ClientRequest, req: TReq): void;
/// <reference types="node" />
/// <reference types="node" />
import type * as http from 'http';
declare type Interceptor = (buffer: Buffer, proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) => Promise<Buffer | string>;
declare type Interceptor<TReq = http.IncomingMessage, TRes = http.ServerResponse> = (buffer: Buffer, proxyRes: TReq, req: TReq, res: TRes) => Promise<Buffer | string>;
/**

@@ -11,3 +12,3 @@ * Intercept responses from upstream.

*/
export declare function responseInterceptor(interceptor: Interceptor): (proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
export declare function responseInterceptor<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse>(interceptor: Interceptor<TReq, TRes>): (proxyRes: TReq, req: TReq, res: TRes) => Promise<void>;
export {};
import type { RequestHandler, Options } from './types';
export declare class HttpProxyMiddleware {
export declare class HttpProxyMiddleware<TReq, TRes> {
private wsInternalSubscribed;

@@ -8,3 +8,3 @@ private serverOnCloseSubscribed;

private pathRewriter;
constructor(options: Options);
constructor(options: Options<TReq, TRes>);
middleware: RequestHandler;

@@ -11,0 +11,0 @@ private registerPlugins;

@@ -1,3 +0,5 @@

import type { Options, RequestHandler } from './types';
export declare function createProxyMiddleware(options: Options): RequestHandler;
/// <reference types="node" />
import type { Options, RequestHandler, NextFunction } from './types';
import type * as http from 'http';
export declare function createProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse, TNext = NextFunction>(options: Options<TReq, TRes>): RequestHandler<TReq, TRes, TNext>;
export * from './handlers';

@@ -4,0 +6,0 @@ export type { Filter, Options, RequestHandler } from './types';

@@ -0,3 +1,5 @@

/// <reference types="node" />
import { Filter, RequestHandler } from '../types';
import { LegacyOptions } from './types';
import type * as http from 'http';
/**

@@ -9,4 +11,4 @@ * @deprecated

*/
export declare function legacyCreateProxyMiddleware(shortHand: string): RequestHandler;
export declare function legacyCreateProxyMiddleware(legacyOptions: LegacyOptions): RequestHandler;
export declare function legacyCreateProxyMiddleware(legacyContext: Filter, legacyOptions: LegacyOptions): RequestHandler;
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(shortHand: string): RequestHandler<TReq, TRes>;
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(legacyOptions: LegacyOptions<TReq, TRes>): RequestHandler<TReq, TRes>;
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(legacyContext: Filter<TReq>, legacyOptions: LegacyOptions<TReq, TRes>): RequestHandler<TReq, TRes>;

@@ -6,2 +6,2 @@ import { Filter, Options } from '..';

*/
export declare function legacyOptionsAdapter(legacyContext: Filter | LegacyOptions, legacyOptions: LegacyOptions): Options;
export declare function legacyOptionsAdapter<TReq, TRes>(legacyContext: Filter<TReq> | LegacyOptions<TReq, TRes>, legacyOptions: LegacyOptions<TReq, TRes>): Options<TReq, TRes>;

@@ -0,1 +1,3 @@

/// <reference types="node" />
import type * as http from 'http';
import { Options } from '..';

@@ -7,3 +9,3 @@ /**

*/
export interface LegacyOptions extends Options {
export interface LegacyOptions<TReq = http.IncomingMessage, TRes = http.ServerResponse> extends Options<TReq, TRes> {
/**

@@ -10,0 +12,0 @@ * @deprecated

@@ -1,2 +0,4 @@

import type { Filter, Request } from './types';
export declare function matchPathFilter(pathFilter: Filter, uri: string, req: Request): boolean;
/// <reference types="node" />
import type { Filter } from './types';
import type * as http from 'http';
export declare function matchPathFilter<TReq = http.IncomingMessage>(pathFilter: Filter<TReq>, uri: string, req: http.IncomingMessage): boolean;

@@ -26,3 +26,4 @@ "use strict";

// BrowserSync uses req.originalUrl
const originalUrl = (_a = req.originalUrl) !== null && _a !== void 0 ? _a : `${req.baseUrl}${req.path}`;
// Next.js doesn't have req.baseUrl
const originalUrl = (_a = req.originalUrl) !== null && _a !== void 0 ? _a : `${req.baseUrl || ''}${req.url}`;
const exchange = `[HPM] ${req.method} ${originalUrl} -> ${proxyRes.req.protocol}//${proxyRes.req.host}${proxyRes.req.path} [${proxyRes.statusCode}]`;

@@ -29,0 +30,0 @@ logger.info(exchange);

@@ -6,27 +6,29 @@ /**

/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import type * as http from 'http';
import type * as httpProxy from 'http-proxy';
import type * as net from 'net';
export declare type Request<T = http.IncomingMessage> = T;
export declare type Response<T = http.ServerResponse> = T;
export declare type NextFunction<T = (err?: any) => void> = T;
export interface RequestHandler {
(req: Request, res: Response, next?: NextFunction): void | Promise<void>;
upgrade?: (req: Request, socket: net.Socket, head: any) => void;
export interface RequestHandler<TReq = http.IncomingMessage, TRes = http.ServerResponse, TNext = NextFunction> {
(req: TReq, res: TRes, next?: TNext): void | Promise<void>;
upgrade?: (req: http.IncomingMessage, socket: net.Socket, head: any) => void;
}
export declare type Filter = string | string[] | ((pathname: string, req: Request) => boolean);
export declare type Plugin = (proxyServer: httpProxy, options: Options) => void;
export declare type OnProxyEvent = {
error?: httpProxy.ErrorCallback;
proxyReq?: httpProxy.ProxyReqCallback;
proxyReqWs?: httpProxy.ProxyReqWsCallback;
proxyRes?: httpProxy.ProxyResCallback;
export declare type Filter<TReq = http.IncomingMessage> = string | string[] | ((pathname: string, req: TReq) => boolean);
export interface Plugin<TReq = http.IncomingMessage, TRes = http.ServerResponse> {
(proxyServer: httpProxy<TReq, TRes>, options: Options<TReq, TRes>): void;
}
export interface OnProxyEvent<TReq = http.IncomingMessage, TRes = http.ServerResponse> {
error?: httpProxy.ErrorCallback<Error, TReq, TRes>;
proxyReq?: httpProxy.ProxyReqCallback<http.ClientRequest, TReq, TRes>;
proxyReqWs?: httpProxy.ProxyReqWsCallback<http.ClientRequest, TReq>;
proxyRes?: httpProxy.ProxyResCallback<TReq, TRes>;
open?: httpProxy.OpenCallback;
close?: httpProxy.CloseCallback;
start?: httpProxy.StartCallback;
end?: httpProxy.EndCallback;
econnreset?: httpProxy.EconnresetCallback;
};
close?: httpProxy.CloseCallback<TReq>;
start?: httpProxy.StartCallback<TReq, TRes>;
end?: httpProxy.EndCallback<TReq, TRes>;
econnreset?: httpProxy.EconnresetCallback<Error, TReq, TRes>;
}
export declare type Logger = Pick<Console, 'info' | 'warn' | 'error'>;
export interface Options extends httpProxy.ServerOptions {
export interface Options<TReq = http.IncomingMessage, TRes = http.ServerResponse> extends httpProxy.ServerOptions {
/**

@@ -36,7 +38,21 @@ * Narrow down requests to proxy or not.

* Or use the {@link http.IncomingMessage `req`} object for more complex filtering.
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathFilter.md
* @since v3.0.0
*/
pathFilter?: Filter;
pathFilter?: Filter<TReq>;
/**
* Modify request paths before requests are send to the target.
* @example
* ```js
* createProxyMiddleware({
* pathRewrite: {
* '^/api/old-path': '/api/new-path', // rewrite path
* }
* });
* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathRewrite.md
*/
pathRewrite?: {
[regexp: string]: string;
} | ((path: string, req: Request) => string) | ((path: string, req: Request) => Promise<string>);
} | ((path: string, req: TReq) => string) | ((path: string, req: TReq) => Promise<string>);
/**

@@ -55,4 +71,6 @@ * Access the internal http-proxy server instance to customize behavior

* ```
* @link https://github.com/chimurai/http-proxy-middleware#plugins-array
* @since v3.0.0
*/
plugins?: Plugin[];
plugins?: Plugin<TReq, TRes>[];
/**

@@ -62,2 +80,3 @@ * Eject pre-configured plugins.

*
* @link https://github.com/chimurai/http-proxy-middleware#ejectplugins-boolean-default-false
* @since v3.0.0

@@ -79,7 +98,21 @@ */

* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/proxy-events.md
* @since v3.0.0
*/
on?: OnProxyEvent;
on?: OnProxyEvent<TReq, TRes>;
/**
* Dynamically set the {@link Options.target `options.target`}.
* @example
* ```js
* createProxyMiddleware({
* router: async (req) => {
* return 'http://127:0.0.1:3000';
* }
* });
* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/router.md
*/
router?: {
[hostOrPath: string]: httpProxy.ServerOptions['target'];
} | ((req: Request) => httpProxy.ServerOptions['target']) | ((req: Request) => Promise<httpProxy.ServerOptions['target']>);
} | ((req: TReq) => httpProxy.ServerOptions['target']) | ((req: TReq) => Promise<httpProxy.ServerOptions['target']>);
/**

@@ -93,4 +126,6 @@ * Log information from http-proxy-middleware

* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md
* @since v3.0.0
*/
logger?: Logger | any;
}
{
"name": "http-proxy-middleware",
"version": "3.0.0-beta.0",
"version": "3.0.0-beta.1",
"description": "The one-liner node.js proxy middleware for connect, express, next.js and more",

@@ -11,17 +11,14 @@ "main": "dist/index.js",

"scripts": {
"clean": "rm -rf dist && rm -rf coverage",
"clean": "rm -rf dist coverage tsconfig.tsbuildinfo .eslintcache",
"lint": "yarn prettier && yarn eslint",
"lint:fix": "yarn prettier:fix && yarn eslint:fix",
"eslint": "eslint '{src,test}/**/*.ts'",
"eslint": "eslint '{src,test}/**/*.ts' --cache",
"eslint:fix": "yarn eslint --fix",
"prettier": "prettier --list-different \"**/*.{js,ts,md,yml,json,html}\"",
"prettier:fix": "prettier --write \"**/*.{js,ts,md,yml,json,html}\"",
"prebuild": "yarn clean",
"build": "tsc",
"pretest": "yarn build",
"build": "tsc --build",
"test": "jest",
"precoverage": "yarn build",
"coverage": "jest --coverage --coverageReporters=lcov",
"coverage": "jest --coverage",
"prepare": "husky install",
"prepack": "yarn build && rm dist/tsconfig.tsbuildinfo",
"prepack": "yarn clean && yarn test && yarn build",
"spellcheck": "npx --yes cspell --show-context --show-suggestions '**/*.*'"

@@ -58,35 +55,35 @@ },

"devDependencies": {
"@commitlint/cli": "16.2.3",
"@commitlint/config-conventional": "16.2.1",
"@commitlint/cli": "17.4.4",
"@commitlint/config-conventional": "17.4.4",
"@types/debug": "4.1.7",
"@types/express": "4.17.13",
"@types/express": "4.17.17",
"@types/is-glob": "4.0.2",
"@types/jest": "27.4.1",
"@types/jest": "29.4.0",
"@types/micromatch": "4.0.2",
"@types/node": "17.0.25",
"@types/node": "18.14.5",
"@types/supertest": "2.0.12",
"@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.20.0",
"@typescript-eslint/parser": "5.20.0",
"body-parser": "1.20.0",
"browser-sync": "2.27.9",
"@types/ws": "8.5.4",
"@typescript-eslint/eslint-plugin": "5.54.0",
"@typescript-eslint/parser": "5.54.0",
"body-parser": "1.20.2",
"browser-sync": "2.28.1",
"connect": "3.7.0",
"eslint": "8.13.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-prettier": "4.0.0",
"express": "4.17.3",
"eslint": "8.35.0",
"eslint-config-prettier": "8.6.0",
"eslint-plugin-prettier": "4.2.1",
"express": "4.18.2",
"get-port": "5.1.1",
"husky": "7.0.4",
"jest": "27.5.1",
"lint-staged": "12.3.8",
"mockttp": "2.7.0",
"open": "8.4.0",
"prettier": "2.6.2",
"supertest": "6.2.2",
"ts-jest": "27.1.4",
"typescript": "4.6.3",
"ws": "8.5.0"
"husky": "8.0.3",
"jest": "29.4.3",
"lint-staged": "13.1.2",
"mockttp": "3.7.0",
"open": "8.4.2",
"prettier": "2.8.4",
"supertest": "6.3.3",
"ts-jest": "29.0.5",
"typescript": "4.9.5",
"ws": "8.12.1"
},
"dependencies": {
"@types/http-proxy": "^1.17.8",
"@types/http-proxy": "^1.17.10",
"debug": "^4.3.4",

@@ -98,13 +95,2 @@ "http-proxy": "^1.18.1",

},
"peerDependencies": {
"@types/express": "^4.17.13"
},
"peerDependenciesMeta": {
"@types/express": {
"optional": true
}
},
"resolutions": {
"browser-sync/portscanner": "2.2.0"
},
"engines": {

@@ -111,0 +97,0 @@ "node": ">=12.0.0"

# http-proxy-middleware
[![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/chimurai/http-proxy-middleware/CI/master?style=flat-square)](https://github.com/chimurai/http-proxy-middleware/actions?query=branch%3Amaster)
[![Coveralls](https://img.shields.io/coveralls/chimurai/http-proxy-middleware.svg?style=flat-square)](https://coveralls.io/r/chimurai/http-proxy-middleware)
[![dependency Status](https://snyk.io/test/npm/http-proxy-middleware/badge.svg?style=flat-square)](https://snyk.io/test/npm/http-proxy-middleware)
[![npm](https://img.shields.io/npm/v/http-proxy-middleware?color=%23CC3534&style=flat-square)](https://www.npmjs.com/package/http-proxy-middleware)
[![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/chimurai/http-proxy-middleware/ci.yml?branch=master&logo=github-actions&logoColor=white&style=flat-square)](https://github.com/chimurai/http-proxy-middleware/actions/workflows/ci.yml?query=branch%3Amaster)
[![Coveralls](https://img.shields.io/coveralls/chimurai/http-proxy-middleware.svg?style=flat-square&logo=coveralls)](https://coveralls.io/r/chimurai/http-proxy-middleware)
[![Snyk Vulnerabilities for GitHub Repo](https://img.shields.io/snyk/vulnerabilities/github/chimurai/http-proxy-middleware?logo=snyk&style=flat-square)](https://security.snyk.io/package/npm/http-proxy-middleware)
[![npm](https://img.shields.io/npm/v/http-proxy-middleware?color=%23CC3534&style=flat-square&logo=npm)](https://www.npmjs.com/package/http-proxy-middleware)
Node.js proxying made simple. Configure proxy middleware with ease for [connect](https://github.com/senchalabs/connect), [express](https://github.com/expressjs/express), [next.js](https://github.com/vercel/next.js) and [many more](#compatible-servers).
Powered by the popular Nodejitsu [`http-proxy`](https://github.com/nodejitsu/node-http-proxy). [![GitHub stars](https://img.shields.io/github/stars/nodejitsu/node-http-proxy.svg?style=social&label=Star)](https://github.com/nodejitsu/node-http-proxy)
Powered by the popular Nodejitsu [`http-proxy`](https://github.com/http-party/node-http-proxy). [![GitHub stars](https://img.shields.io/github/stars/http-party/node-http-proxy.svg?style=social&label=Star)](https://github.com/http-party/node-http-proxy)

@@ -48,3 +48,3 @@ ## ⚠️ Note <!-- omit in toc -->

// proxy and change the base path from "/api" to "/secret"
// http://localhost:3000/api/foo/bar -> http://www.example.org/secret/foo/bar
// http://127.0.0.1:3000/api/foo/bar -> http://www.example.org/secret/foo/bar
```

@@ -71,3 +71,3 @@

// proxy and keep the same base path "/api"
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
// http://127.0.0.1:3000/api/foo/bar -> http://www.example.org/api/foo/bar
```

@@ -86,3 +86,3 @@

- [Options](#options)
- [`pathFilter` (string, []string, glob, []glob, function)](#pathfilter-string-string-glob-glob-function)
- [`pathFilter` (string, \[\]string, glob, \[\]glob, function)](#pathfilter-string-string-glob-glob-function)
- [`pathRewrite` (object/function)](#pathrewrite-objectfunction)

@@ -99,2 +99,3 @@ - [`router` (object/function)](#router-objectfunction)

- [Intercept and manipulate responses](#intercept-and-manipulate-responses)
- [Node.js 17+: ECONNREFUSED issue with IPv6 and localhost (#705)](#nodejs-17-econnrefused-issue-with-ipv6-and-localhost-705)
- [Debugging](#debugging)

@@ -147,12 +148,9 @@ - [Working examples](#working-examples)

// proxy middleware options
/** @type {import('http-proxy-middleware/dist/types').Options} */
const options = {
// create the proxy
/** @type {import('http-proxy-middleware/dist/types').RequestHandler<express.Request, express.Response>} */
const exampleProxy = createProxyMiddleware({
target: 'http://www.example.org/api', // target host with the same base path
changeOrigin: true, // needed for virtual hosted sites
};
});
// create the proxy
const exampleProxy = createProxyMiddleware(options);
// mount `exampleProxy` in web server

@@ -265,6 +263,6 @@ app.use('/api', exampleProxy);

router: {
'integration.localhost:3000' : 'http://localhost:8001', // host only
'staging.localhost:3000' : 'http://localhost:8002', // host only
'localhost:3000/api' : 'http://localhost:8003', // host + path
'/rest' : 'http://localhost:8004' // path only
'integration.localhost:3000' : 'http://127.0.0.1:8001', // host only
'staging.localhost:3000' : 'http://127.0.0.1:8002', // host only
'localhost:3000/api' : 'http://127.0.0.1:8003', // host + path
'/rest' : 'http://127.0.0.1:8004' // path only
}

@@ -274,3 +272,3 @@

router: function(req) {
return 'http://localhost:8004';
return 'http://127.0.0.1:8004';
}

@@ -282,3 +280,3 @@

protocol: 'https:', // The : is required
host: 'localhost',
host: '127.0.0.1',
port: 8004

@@ -499,3 +497,3 @@ };

{
target: 'http://localhost:4003/',
target: 'http://127.0.0.1:4003/',
buffer: streamify(req.rawBody),

@@ -585,2 +583,17 @@ },

## Node.js 17+: ECONNREFUSED issue with IPv6 and localhost ([#705](https://github.com/chimurai/http-proxy-middleware/issues/705))
Node.js 17+ no longer prefers IPv4 over IPv6 for DNS lookups.
E.g. It's **not** guaranteed that `localhost` will be resolved to `127.0.0.1` – it might just as well be `::1` (or some other IP address).
If your target server only accepts IPv4 connections, trying to proxy to `localhost` will fail if resolved to `::1` (IPv6).
Ways to solve it:
- Change `target: "http://localhost"` to `target: "http://127.0.0.1"` (IPv4).
- Change the target server to (also) accept IPv6 connections.
- Add this flag when running `node`: `node index.js --dns-result-order=ipv4first`. (Not recommended.)
> Note: There’s a thing called [Happy Eyeballs](https://en.wikipedia.org/wiki/Happy_Eyeballs) which means connecting to both IPv4 and IPv6 in parallel, which Node.js doesn’t have, but explains why for example `curl` can connect.
## Debugging

@@ -587,0 +600,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc