Socket
Socket
Sign inDemoInstall

http-proxy-middleware

Package Overview
Dependencies
Maintainers
1
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http-proxy-middleware - npm Package Compare versions

Comparing version 0.19.0 to 0.19.1

40

CHANGELOG.md
# Changelog
## [v0.19.1](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.19.1)
- fix(log): handle case when error code is missing ([#303](https://github.com/chimurai/http-proxy-middleware/pull/303))
## [v0.19.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.19.0)
- feat(http-proxy): bump to v1.17.0 ([#261](https://github.com/chimurai/http-proxy-middleware/pull/261))
## [v0.18.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.18.0)
- fix(vulnerability): update micromatch to v3.x ([npm:braces:20180219](https://snyk.io/test/npm/http-proxy-middleware?tab=issues&severity=high&severity=medium&severity=low#npm:braces:20180219
))
- fix(vulnerability): update micromatch to v3.x ([npm:braces:20180219](https://snyk.io/test/npm/http-proxy-middleware?tab=issues&severity=high&severity=medium&severity=low#npm:braces:20180219))
- test(node): drop node 0.x support ([#212](https://github.com/chimurai/http-proxy-middleware/pull/212))
## [v0.17.4](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.4)
## [v0.17.4](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.4)
- fix(ntlm authentication): fixed bug preventing proxying with ntlm authentication. ([#132](https://github.com/chimurai/http-proxy-middleware/pull/149)) (Thanks: [EladBezalel](https://github.com/EladBezalel), [oshri551](https://github.com/oshri551))
## [v0.17.3](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.3)
## [v0.17.3](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.3)
- fix(onError): improve default proxy error handling. http status codes (504, 502 and 500). ([#132](https://github.com/chimurai/http-proxy-middleware/pull/132)) ([graingert](https://github.com/graingert))
## [v0.17.2](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.2)
- feat(logging): improve error message & add link to Node errors page. ([#106](https://github.com/chimurai/http-proxy-middleware/pull/106)) ([cloudmu](https://github.com/cloudmu))

@@ -26,8 +32,11 @@ - feat(pathRewrite): path can be empty string. ([#110](https://github.com/chimurai/http-proxy-middleware/pull/110)) ([sunnylqm](https://github.com/sunnylqm))

## [v0.17.1](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.1)
- fix(Express sub Router): 404 on non-proxy routes ([#94](https://github.com/chimurai/http-proxy-middleware/issues/94))
- fix(Express sub Router): 404 on non-proxy routes ([#94](https://github.com/chimurai/http-proxy-middleware/issues/94))
## [v0.17.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.0)
- fix(context matching): Use [RFC 3986 path](https://tools.ietf.org/html/rfc3986#section-3.3) in context matching. (excludes query parameters)
## [v0.16.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.16.0)
- deprecated(proxyTable): renamed `proxyTable` to `router`.

@@ -37,5 +46,7 @@ - feat(router): support for custom `router` function.

## [v0.15.2](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.15.2)
- fix(websocket): fixes websocket upgrade.
## [v0.15.1](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.15.1)
- feat(pathRewrite): expose `req` object to pathRewrite function.

@@ -45,5 +56,7 @@ - fix(websocket): fixes websocket upgrade when both config.ws and external .upgrade() are used.

## [v0.15.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.15.0)
- feat(pathRewrite): support for custom pathRewrite function.
## [v0.14.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.14.0)
- feat(proxy): support proxy creation without context.

@@ -53,5 +66,7 @@ - fix(connect mounting): use connect's `path` configuration to mount proxy.

## [v0.13.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.13.0)
- feat(context): custom context matcher; when simple `path` matching is not sufficient.
## [v0.12.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.12.0)
- add option `onProxyReqWs` (subscribe to http-proxy `proxyReqWs` event)

@@ -62,5 +77,7 @@ - add option `onOpen` (subscribe to http-proxy `open` event)

## [v0.11.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.11.0)
- improved logging
## [v0.10.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.10.0)
- feat(proxyTable) - added proxyTable support for WebSockets.

@@ -70,5 +87,7 @@ - fixed(proxyTable) - ensure original path (not rewritten path) is being used when `proxyTable` is used in conjunction with `pathRewrite`.

## [v0.9.1](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.9.1)
- fix server crash when socket error not handled correctly.
## [v0.9.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.9.0)
- support subscribing to http-proxy `proxyReq` event ([trbngr](https://github.com/trbngr))

@@ -78,8 +97,11 @@ - add `logLevel` and `logProvider` support

## [v0.8.2](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.8.2)
- fix proxyError handler ([mTazelaar](https://github.com/mTazelaar))
## [v0.8.1](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.8.1)
- fix pathRewrite when `agent` is configured
## [v0.8.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.8.0)
- support external websocket upgrade

@@ -89,2 +111,3 @@ - fix websocket shorthand

## [v0.7.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.7.0)
- support shorthand syntax

@@ -94,5 +117,7 @@ - fix express/connect mounting

## [v0.6.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.6.0)
- support proxyTable
## [v0.5.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.5.0)
- support subscribing to http-proxy `error` event

@@ -102,11 +127,15 @@ - support subscribing to http-proxy `proxyRes` event

## [v0.4.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.4.0)
- support websocket
## [v0.3.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.3.0)
- support wildcard / glob
## [v0.2.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.2.0)
- support multiple paths
## [v0.1.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.1.0)
- support path rewrite

@@ -116,2 +145,3 @@ - deprecate proxyHost option

## [v0.0.5](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.0.5)
- initial release

2

index.js
var HPM = require('./lib')
module.exports = function (context, opts) {
module.exports = function(context, opts) {
return new HPM(context, opts)
}

@@ -10,3 +10,3 @@ var _ = require('lodash')

function createConfig (context, opts) {
function createConfig(context, opts) {
// structure of config object to be returned

@@ -23,4 +23,4 @@ var config = {

// app.use('/api', proxy('http://localhost:9000'));
// app.use(proxy('http://localhost:9000/api'));
// app.use('/api', proxy('http://localhost:9000'));
// app.use(proxy('http://localhost:9000/api'));
} else if (isStringShortHand(context)) {

@@ -36,3 +36,3 @@ var oUrl = url.parse(context)

}
// app.use('/api', proxy({target:'http://localhost:9000'}));
// app.use('/api', proxy({target:'http://localhost:9000'}));
} else {

@@ -69,5 +69,5 @@ config.context = context

*/
function isStringShortHand (context) {
function isStringShortHand(context) {
if (_.isString(context)) {
return !!(url.parse(context).host)
return !!url.parse(context).host
}

@@ -87,7 +87,7 @@ }

*/
function isContextless (context, opts) {
return (_.isPlainObject(context) && _.isEmpty(opts))
function isContextless(context, opts) {
return _.isPlainObject(context) && _.isEmpty(opts)
}
function mapLegacyProxyHostOption (options) {
function mapLegacyProxyHostOption(options) {
// set options.headers.host when option.proxyHost is provided

@@ -97,3 +97,5 @@ if (options.proxyHost) {

logger.warn('[HPM] Deprecated "option.proxyHost"')
logger.warn(' Use "option.changeOrigin" or "option.headers.host" instead')
logger.warn(
' Use "option.changeOrigin" or "option.headers.host" instead'
)
logger.warn(' "option.proxyHost" will be removed in future release.')

@@ -110,3 +112,3 @@ logger.warn('*************************************')

// Warn deprecated proxyTable api usage
function mapLegacyProxyTableOption (options) {
function mapLegacyProxyTableOption(options) {
if (options.proxyTable) {

@@ -126,3 +128,3 @@ logger.warn('*************************************')

function configureLogger (options) {
function configureLogger(options) {
if (options.logLevel) {

@@ -129,0 +131,0 @@ logger.setLevel(options.logLevel)

@@ -11,3 +11,3 @@ var _ = require('lodash')

function matchContext (context, uri, req) {
function matchContext(context, uri, req) {
// single path

@@ -49,3 +49,3 @@ if (isStringPath(context)) {

*/
function matchSingleStringPath (context, uri) {
function matchSingleStringPath(context, uri) {
var pathname = getUrlPathName(uri)

@@ -55,9 +55,9 @@ return pathname.indexOf(context) === 0

function matchSingleGlobPath (pattern, uri) {
function matchSingleGlobPath(pattern, uri) {
var pathname = getUrlPathName(uri)
var matches = micromatch(pathname, pattern)
return matches && (matches.length > 0)
return matches && matches.length > 0
}
function matchMultiGlobPath (patternList, uri) {
function matchMultiGlobPath(patternList, uri) {
return matchSingleGlobPath(patternList, uri)

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

*/
function matchMultiPath (contextList, uri) {
function matchMultiPath(contextList, uri) {
for (var i = 0; i < contextList.length; i++) {

@@ -88,12 +88,12 @@ var context = contextList[i]

*/
function getUrlPathName (uri) {
function getUrlPathName(uri) {
return uri && url.parse(uri).pathname
}
function isStringPath (context) {
function isStringPath(context) {
return _.isString(context) && !isGlob(context)
}
function isGlobPath (context) {
function isGlobPath(context) {
return isGlob(context)
}
/* eslint-disable max-len */
module.exports = {
ERR_CONFIG_FACTORY_TARGET_MISSING: '[HPM] Missing "target" option. Example: {target: "http://www.example.org"}',
ERR_CONTEXT_MATCHER_GENERIC: '[HPM] Invalid context. Expecting something like: "/api" or ["/api", "/ajax"]',
ERR_CONTEXT_MATCHER_INVALID_ARRAY: '[HPM] Invalid context. Expecting something like: ["/api", "/ajax"] or ["/api/**", "!**.html"]',
ERR_PATH_REWRITER_CONFIG: '[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function'
ERR_CONFIG_FACTORY_TARGET_MISSING:
'[HPM] Missing "target" option. Example: {target: "http://www.example.org"}',
ERR_CONTEXT_MATCHER_GENERIC:
'[HPM] Invalid context. Expecting something like: "/api" or ["/api", "/ajax"]',
ERR_CONTEXT_MATCHER_INVALID_ARRAY:
'[HPM] Invalid context. Expecting something like: ["/api", "/ajax"] or ["/api/**", "!**.html"]',
ERR_PATH_REWRITER_CONFIG:
'[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function'
}

@@ -9,6 +9,6 @@ var _ = require('lodash')

function init (proxy, opts) {
function init(proxy, opts) {
var handlers = getProxyEventHandlers(opts)
_.forIn(handlers, function (handler, eventName) {
_.forIn(handlers, function(handler, eventName) {
proxy.on(eventName, handlers[eventName])

@@ -20,8 +20,15 @@ })

function getProxyEventHandlers (opts) {
function getProxyEventHandlers(opts) {
// https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events
var proxyEvents = ['error', 'proxyReq', 'proxyReqWs', 'proxyRes', 'open', 'close']
var proxyEvents = [
'error',
'proxyReq',
'proxyReqWs',
'proxyRes',
'open',
'close'
]
var handlers = {}
_.forEach(proxyEvents, function (event) {
_.forEach(proxyEvents, function(event) {
// all handlers for the http-proxy events are prefixed with 'on'.

@@ -51,4 +58,4 @@ // loop through options and try to find these handlers

function defaultErrorHandler (err, req, res) {
var host = (req.headers && req.headers.host)
function defaultErrorHandler(err, req, res) {
var host = req.headers && req.headers.host
var code = err.code

@@ -66,3 +73,4 @@

break
default: res.writeHead(500)
default:
res.writeHead(500)
}

@@ -75,5 +83,5 @@ }

function logClose (req, socket, head) {
function logClose(req, socket, head) {
// view disconnected websocket connections
logger.info('[HPM] Client disconnected')
}

@@ -13,3 +13,3 @@ var _ = require('lodash')

function HttpProxyMiddleware (context, opts) {
function HttpProxyMiddleware(context, opts) {
// https://github.com/chimurai/http-proxy-middleware/issues/57

@@ -23,3 +23,8 @@ var wsUpgradeDebounced = _.debounce(handleUpgrade)

var proxy = httpProxy.createProxyServer({})
logger.info('[HPM] Proxy created:', config.context, ' -> ', proxyOptions.target)
logger.info(
'[HPM] Proxy created:',
config.context,
' -> ',
proxyOptions.target
)

@@ -40,3 +45,3 @@ var pathRewriter = PathRewriter.create(proxyOptions.pathRewrite) // returns undefined when "pathRewrite" is not provided

function middleware (req, res, next) {
function middleware(req, res, next) {
if (shouldProxy(config.context, req)) {

@@ -55,3 +60,3 @@ var activeProxyOptions = prepareProxyRequest(req)

function catchUpgradeRequest (server) {
function catchUpgradeRequest(server) {
// subscribe once; don't subscribe on every request...

@@ -65,3 +70,3 @@ // https://github.com/chimurai/http-proxy-middleware/issues/113

function handleUpgrade (req, socket, head) {
function handleUpgrade(req, socket, head) {
// set to initialized when used externally

@@ -85,4 +90,4 @@ wsInitialized = true

*/
function shouldProxy (context, req) {
var path = (req.originalUrl || req.url)
function shouldProxy(context, req) {
var path = req.originalUrl || req.url
return contextMatcher.match(context, path, req)

@@ -99,6 +104,6 @@ }

*/
function prepareProxyRequest (req) {
function prepareProxyRequest(req) {
// https://github.com/chimurai/http-proxy-middleware/issues/17
// https://github.com/chimurai/http-proxy-middleware/issues/94
req.url = (req.originalUrl || req.url)
req.url = req.originalUrl || req.url

@@ -117,4 +122,15 @@ // store uri before it gets rewritten for logging

if (proxyOptions.logLevel === 'debug') {
var arrow = getArrow(originalPath, req.url, proxyOptions.target, newProxyOptions.target)
logger.debug('[HPM] %s %s %s %s', req.method, originalPath, arrow, newProxyOptions.target)
var arrow = getArrow(
originalPath,
req.url,
proxyOptions.target,
newProxyOptions.target
)
logger.debug(
'[HPM] %s %s %s %s',
req.method,
originalPath,
arrow,
newProxyOptions.target
)
}

@@ -126,3 +142,3 @@

// Modify option.target when router present.
function __applyRouter (req, options) {
function __applyRouter(req, options) {
var newTarget

@@ -134,3 +150,7 @@

if (newTarget) {
logger.debug('[HPM] Router new target: %s -> "%s"', options.target, newTarget)
logger.debug(
'[HPM] Router new target: %s -> "%s"',
options.target,
newTarget
)
options.target = newTarget

@@ -142,3 +162,3 @@ }

// rewrite path
function __applyPathRewrite (req, pathRewriter) {
function __applyPathRewrite(req, pathRewriter) {
if (pathRewriter) {

@@ -155,10 +175,20 @@ var path = pathRewriter(req.url, req)

function logError (err, req, res) {
var hostname = (req.headers && req.headers.host) || (req.hostname || req.host) // (websocket) || (node0.10 || node 4/5)
function logError(err, req, res) {
var hostname =
(req.headers && req.headers.host) || (req.hostname || req.host) // (websocket) || (node0.10 || node 4/5)
var target = proxyOptions.target.host || proxyOptions.target
var errorMessage = '[HPM] Error occurred while trying to proxy request %s from %s to %s (%s) (%s)'
var errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors' // link to Node Common Systems Errors page
var errorMessage =
'[HPM] Error occurred while trying to proxy request %s from %s to %s (%s) (%s)'
var errReference =
'https://nodejs.org/api/errors.html#errors_common_system_errors' // link to Node Common Systems Errors page
logger.error(errorMessage, req.url, hostname, target, err.code, errReference)
logger.error(
errorMessage,
req.url,
hostname,
target,
err.code || err,
errReference
)
}
}

@@ -25,3 +25,3 @@ var util = require('util')

// singleton
getInstance: function () {
getInstance: function() {
if (!loggerInstance) {

@@ -36,3 +36,3 @@ loggerInstance = new Logger()

function Logger () {
function Logger() {
var logLevel

@@ -47,3 +47,3 @@ var provider

error: error,
setLevel: function (v) {
setLevel: function(v) {
if (isValidLevel(v)) {

@@ -53,3 +53,3 @@ logLevel = v

},
setProvider: function (fn) {
setProvider: function(fn) {
if (fn && isValidProvider(fn)) {

@@ -65,5 +65,5 @@ provider = fn(defaultProvider)

function init () {
function init() {
api.setLevel('info')
api.setProvider(function () {
api.setProvider(function() {
return defaultProvider

@@ -74,7 +74,7 @@ })

// log will log messages, regardless of logLevels
function log () {
function log() {
provider.log(_interpolate.apply(null, arguments))
}
function debug () {
function debug() {
if (_showLevel('debug')) {

@@ -85,3 +85,3 @@ provider.debug(_interpolate.apply(null, arguments))

function info () {
function info() {
if (_showLevel('info')) {

@@ -92,3 +92,3 @@ provider.info(_interpolate.apply(null, arguments))

function warn () {
function warn() {
if (_showLevel('warn')) {

@@ -99,3 +99,3 @@ provider.warn(_interpolate.apply(null, arguments))

function error () {
function error() {
if (_showLevel('error')) {

@@ -111,7 +111,7 @@ provider.error(_interpolate.apply(null, arguments))

*/
function _showLevel (showLevel) {
function _showLevel(showLevel) {
var result = false
var currentLogLevel = LEVELS[logLevel]
if (currentLogLevel && (currentLogLevel <= LEVELS[showLevel])) {
if (currentLogLevel && currentLogLevel <= LEVELS[showLevel]) {
result = true

@@ -125,3 +125,3 @@ }

// make it possible for additional log data, such date/time or custom prefix.
function _interpolate () {
function _interpolate() {
var fn = _.spread(util.format)

@@ -133,3 +133,3 @@ var result = fn(_.slice(arguments))

function isValidProvider (fnProvider) {
function isValidProvider(fnProvider) {
var result = true

@@ -144,3 +144,3 @@

function isValidLevel (levelName) {
function isValidLevel(levelName) {
var validLevels = _.keys(LEVELS)

@@ -169,6 +169,6 @@ var isValid = _.includes(validLevels, levelName)

*/
function getArrow (originalPath, newPath, originalTarget, newTarget) {
function getArrow(originalPath, newPath, originalTarget, newTarget) {
var arrow = ['>']
var isNewTarget = (originalTarget !== newTarget) // router
var isNewPath = (originalPath !== newPath) // pathRewrite
var isNewTarget = originalTarget !== newTarget // router
var isNewPath = originalPath !== newPath // pathRewrite

@@ -175,0 +175,0 @@ if (isNewPath && !isNewTarget) {

@@ -15,3 +15,3 @@ var _ = require('lodash')

*/
function createPathRewriter (rewriteConfig) {
function createPathRewriter(rewriteConfig) {
var rulesCache

@@ -31,6 +31,6 @@

function rewritePath (path) {
function rewritePath(path) {
var result = path
_.forEach(rulesCache, function (rule) {
_.forEach(rulesCache, function(rule) {
if (rule.regex.test(path)) {

@@ -47,3 +47,3 @@ result = result.replace(rule.regex, rule.value)

function isValidRewriteConfig (rewriteConfig) {
function isValidRewriteConfig(rewriteConfig) {
if (_.isFunction(rewriteConfig)) {

@@ -53,5 +53,7 @@ return true

return true
} else if (_.isUndefined(rewriteConfig) ||
_.isNull(rewriteConfig) ||
_.isEqual(rewriteConfig, {})) {
} else if (
_.isUndefined(rewriteConfig) ||
_.isNull(rewriteConfig) ||
_.isEqual(rewriteConfig, {})
) {
return false

@@ -63,7 +65,7 @@ } else {

function parsePathRewriteRules (rewriteConfig) {
function parsePathRewriteRules(rewriteConfig) {
var rules = []
if (_.isPlainObject(rewriteConfig)) {
_.forIn(rewriteConfig, function (value, key) {
_.forIn(rewriteConfig, function(value, key) {
rules.push({

@@ -73,3 +75,7 @@ regex: new RegExp(key),

})
logger.info('[HPM] Proxy rewrite rule created: "%s" ~> "%s"', key, rewriteConfig[key])
logger.info(
'[HPM] Proxy rewrite rule created: "%s" ~> "%s"',
key,
rewriteConfig[key]
)
})

@@ -76,0 +82,0 @@ }

@@ -8,3 +8,3 @@ var _ = require('lodash')

function getTarget (req, config) {
function getTarget(req, config) {
var newTarget

@@ -22,3 +22,3 @@ var router = config.router

function getTargetFromProxyTable (req, table) {
function getTargetFromProxyTable(req, table) {
var result

@@ -30,5 +30,6 @@ var host = req.headers.host

_.forIn(table, function (value, key) {
_.forIn(table, function(value, key) {
if (containsPath(key)) {
if (hostAndPath.indexOf(key) > -1) { // match 'localhost:3000/api'
if (hostAndPath.indexOf(key) > -1) {
// match 'localhost:3000/api'
result = table[key]

@@ -39,3 +40,4 @@ logger.debug('[HPM] Router table match: "%s"', key)

} else {
if (key === host) { // match 'localhost:3000'
if (key === host) {
// match 'localhost:3000'
result = table[key]

@@ -51,4 +53,4 @@ logger.debug('[HPM] Router table match: "%s"', host)

function containsPath (v) {
function containsPath(v) {
return v.indexOf('/') > -1
}
{
"name": "http-proxy-middleware",
"version": "0.19.0",
"version": "0.19.1",
"description": "The one-liner node.js proxy middleware for connect, express and browser-sync",

@@ -12,8 +12,7 @@ "main": "index.js",

"clean": "rm -rf coverage",
"lint": "standard --verbose | snazzy --colors",
"lint:fix": "standard --fix",
"lint": "prettier \"**/*.{js,md}\" --list-different",
"lint:fix": "prettier \"**/*.{js,md}\" --write",
"test": "npm run lint && mocha --recursive --colors --reporter spec",
"cover": "npm run clean && istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive",
"coveralls": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --recursive --reporter spec && istanbul-coveralls && npm run clean",
"commitmsg": "commitlint -e $GIT_PARAMS"
"coveralls": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --recursive --reporter spec && istanbul-coveralls && npm run clean"
},

@@ -46,10 +45,10 @@ "repository": {

"devDependencies": {
"@commitlint/cli": "^7.1.1",
"@commitlint/config-conventional": "^7.1.1",
"browser-sync": "^2.24.7",
"chai": "^4.1.2",
"@commitlint/cli": "^7.2.1",
"@commitlint/config-conventional": "^7.1.2",
"browser-sync": "^2.26.3",
"chai": "^4.2.0",
"connect": "^3.6.6",
"coveralls": "^3.0.2",
"express": "^4.16.3",
"husky": "^0.14.3",
"express": "^4.16.4",
"husky": "^1.2.0",
"istanbul": "^0.4.5",

@@ -59,6 +58,6 @@ "istanbul-coveralls": "^1.0.3",

"mocha-lcov-reporter": "1.3.0",
"opn": "^5.3.0",
"snazzy": "^8.0.0",
"standard": "^12.0.0",
"ws": "^6.0.0"
"opn": "^5.4.0",
"precise-commits": "^1.0.2",
"prettier": "^1.15.2",
"ws": "^6.1.2"
},

@@ -68,3 +67,3 @@ "dependencies": {

"is-glob": "^4.0.0",
"lodash": "^4.17.10",
"lodash": "^4.17.11",
"micromatch": "^3.1.10"

@@ -75,6 +74,7 @@ },

},
"standard": {
"env": [
"mocha"
]
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "precise-commits"
}
},

@@ -81,0 +81,0 @@ "commitlint": {

@@ -7,3 +7,3 @@ # http-proxy-middleware

[![dependency Status](https://snyk.io/test/npm/http-proxy-middleware/badge.svg)](https://snyk.io/test/npm/http-proxy-middleware)
[![JavaScript Style Guide](https://img.shields.io/badge/codestyle-standard-brightgreen.svg)](https://standardjs.com)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)

@@ -19,9 +19,9 @@ Node.js proxying made simple. Configure proxy middleware with ease for [connect](https://github.com/senchalabs/connect), [express](https://github.com/strongloop/express), [browser-sync](https://github.com/BrowserSync/browser-sync) and [many more](#compatible-servers).

```javascript
var express = require('express');
var proxy = require('http-proxy-middleware');
var express = require('express')
var proxy = require('http-proxy-middleware')
var app = express();
var app = express()
app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
app.listen(3000);
app.use('/api', proxy({ target: 'http://www.example.org', changeOrigin: true }))
app.listen(3000)

@@ -44,9 +44,9 @@ // http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar

- [Options](#options)
- [http-proxy-middleware options](#http-proxy-middleware-options)
- [http-proxy events](#http-proxy-events)
- [http-proxy options](#http-proxy-options)
- [http-proxy-middleware options](#http-proxy-middleware-options)
- [http-proxy events](#http-proxy-events)
- [http-proxy options](#http-proxy-options)
- [Shorthand](#shorthand)
- [app.use\(path, proxy\)](#appusepath-proxy)
- [app.use\(path, proxy\)](#appusepath-proxy)
- [WebSocket](#websocket)
- [External WebSocket upgrade](#external-websocket-upgrade)
- [External WebSocket upgrade](#external-websocket-upgrade)
- [Working examples](#working-examples)

@@ -61,3 +61,2 @@ - [Recipes](#recipes)

## Install

@@ -76,5 +75,5 @@

```javascript
var proxy = require('http-proxy-middleware');
var proxy = require('http-proxy-middleware')
var apiProxy = proxy('/api', {target: 'http://www.example.org'});
var apiProxy = proxy('/api', { target: 'http://www.example.org' })
// \____/ \_____________________________/

@@ -86,6 +85,7 @@ // | |

```
* **context**: Determine which requests should be proxied to the target host.
(more on [context matching](#context-matching))
* **options.target**: target host to proxy to. _(protocol + host)_
- **context**: Determine which requests should be proxied to the target host.
(more on [context matching](#context-matching))
- **options.target**: target host to proxy to. _(protocol + host)_
(full list of [`http-proxy-middleware` configuration options](#options))

@@ -95,7 +95,7 @@

``` javascript
```javascript
// shorthand syntax for the example above:
var apiProxy = proxy('http://www.example.org/api');
var apiProxy = proxy('http://www.example.org/api')
```
```
More about the [shorthand configuration](#shorthand).

@@ -109,28 +109,28 @@

// include dependencies
var express = require('express');
var proxy = require('http-proxy-middleware');
var express = require('express')
var proxy = require('http-proxy-middleware')
// proxy middleware options
var options = {
target: 'http://www.example.org', // target host
changeOrigin: true, // needed for virtual hosted sites
ws: true, // proxy websockets
pathRewrite: {
'^/api/old-path' : '/api/new-path', // rewrite path
'^/api/remove/path' : '/path' // remove base path
},
router: {
// when request.headers.host == 'dev.localhost:3000',
// override target 'http://www.example.org' to 'http://localhost:8000'
'dev.localhost:3000' : 'http://localhost:8000'
}
};
target: 'http://www.example.org', // target host
changeOrigin: true, // needed for virtual hosted sites
ws: true, // proxy websockets
pathRewrite: {
'^/api/old-path': '/api/new-path', // rewrite path
'^/api/remove/path': '/path' // remove base path
},
router: {
// when request.headers.host == 'dev.localhost:3000',
// override target 'http://www.example.org' to 'http://localhost:8000'
'dev.localhost:3000': 'http://localhost:8000'
}
}
// create the proxy (without context)
var exampleProxy = proxy(options);
var exampleProxy = proxy(options)
// mount `exampleProxy` in web server
var app = express();
app.use('/api', exampleProxy);
app.listen(3000);
var app = express()
app.use('/api', exampleProxy)
app.listen(3000)
```

@@ -151,34 +151,40 @@

* **path matching**
- `proxy({...})` - matches any path, all requests will be proxied.
- `proxy('/', {...})` - matches any path, all requests will be proxied.
- `proxy('/api', {...})` - matches paths starting with `/api`
- **path matching**
* **multiple path matching**
- `proxy(['/api', '/ajax', '/someotherpath'], {...})`
- `proxy({...})` - matches any path, all requests will be proxied.
- `proxy('/', {...})` - matches any path, all requests will be proxied.
- `proxy('/api', {...})` - matches paths starting with `/api`
* **wildcard path matching**
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
- `proxy('**', {...})` matches any path, all requests will be proxied.
- `proxy('**/*.html', {...})` matches any path which ends with `.html`
- `proxy('/*.html', {...})` matches paths directly under path-absolute
- `proxy('/api/**/*.html', {...})` matches requests ending with `.html` in the path of `/api`
- `proxy(['/api/**', '/ajax/**'], {...})` combine multiple patterns
- `proxy(['/api/**', '!**/bad.json'], {...})` exclusion
- **multiple path matching**
* **custom matching**
For full control you can provide a custom function to determine which requests should be proxied or not.
```javascript
/**
* @return {Boolean}
*/
var filter = function (pathname, req) {
return (pathname.match('^/api') && req.method === 'GET');
};
- `proxy(['/api', '/ajax', '/someotherpath'], {...})`
var apiProxy = proxy(filter, {target: 'http://www.example.org'})
```
- **wildcard path matching**
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
- `proxy('**', {...})` matches any path, all requests will be proxied.
- `proxy('**/*.html', {...})` matches any path which ends with `.html`
- `proxy('/*.html', {...})` matches paths directly under path-absolute
- `proxy('/api/**/*.html', {...})` matches requests ending with `.html` in the path of `/api`
- `proxy(['/api/**', '/ajax/**'], {...})` combine multiple patterns
- `proxy(['/api/**', '!**/bad.json'], {...})` exclusion
**Note**: In multiple path matching, you cannot use string paths and wildcard paths together.
- **custom matching**
For full control you can provide a custom function to determine which requests should be proxied or not.
```javascript
/**
* @return {Boolean}
*/
var filter = function(pathname, req) {
return pathname.match('^/api') && req.method === 'GET'
}
var apiProxy = proxy(filter, { target: 'http://www.example.org' })
```
## Options

@@ -188,63 +194,66 @@

* **option.pathRewrite**: object/function, rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
```javascript
// rewrite path
pathRewrite: {'^/old/api' : '/new/api'}
// remove path
pathRewrite: {'^/remove/api' : ''}
// add base path
pathRewrite: {'^/' : '/basepath/'}
- **option.pathRewrite**: object/function, rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
// custom rewriting
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
```
```javascript
// rewrite path
pathRewrite: {'^/old/api' : '/new/api'}
* **option.router**: object/function, re-target `option.target` for specific requests.
```javascript
// Use `host` and/or `path` to match requests. First match will be used.
// The order of the configuration matters.
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
}
// remove path
pathRewrite: {'^/remove/api' : ''}
// Custom router function
router: function(req) {
return 'http://localhost:8004';
}
```
// add base path
pathRewrite: {'^/' : '/basepath/'}
* **option.logLevel**: string, ['debug', 'info', 'warn', 'error', 'silent']. Default: `'info'`
// custom rewriting
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
```
* **option.logProvider**: function, modify or replace log provider. Default: `console`.
```javascript
// simple replace
function logProvider(provider) {
// replace the default console log provider.
return require('winston');
}
```
- **option.router**: object/function, re-target `option.target` for specific requests.
```javascript
// verbose replacement
function logProvider(provider) {
var logger = new (require('winston').Logger)();
```javascript
// Use `host` and/or `path` to match requests. First match will be used.
// The order of the configuration matters.
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
}
var myCustomProvider = {
log: logger.log,
debug: logger.debug,
info: logger.info,
warn: logger.warn,
error: logger.error
}
return myCustomProvider;
// Custom router function
router: function(req) {
return 'http://localhost:8004';
}
```
- **option.logLevel**: string, ['debug', 'info', 'warn', 'error', 'silent']. Default: `'info'`
- **option.logProvider**: function, modify or replace log provider. Default: `console`.
```javascript
// simple replace
function logProvider(provider) {
// replace the default console log provider.
return require('winston')
}
```
```javascript
// verbose replacement
function logProvider(provider) {
var logger = new (require('winston')).Logger()
var myCustomProvider = {
log: logger.log,
debug: logger.debug,
info: logger.info,
warn: logger.warn,
error: logger.error
}
```
* (DEPRECATED) **option.proxyHost**: Use `option.changeOrigin = true` instead.
* (DEPRECATED) **option.proxyTable**: Use `option.router` instead.
return myCustomProvider
}
```
- (DEPRECATED) **option.proxyHost**: Use `option.changeOrigin = true` instead.
- (DEPRECATED) **option.proxyTable**: Use `option.router` instead.

@@ -255,53 +264,60 @@ ### http-proxy events

* **option.onError**: function, subscribe to http-proxy's `error` event for custom error handling.
```javascript
function onError(err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.');
}
```
- **option.onError**: function, subscribe to http-proxy's `error` event for custom error handling.
* **option.onProxyRes**: function, subscribe to http-proxy's `proxyRes` event.
```javascript
function onProxyRes(proxyRes, req, res) {
proxyRes.headers['x-added'] = 'foobar'; // add new header to response
delete proxyRes.headers['x-removed']; // remove header from response
}
```
```javascript
function onError(err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
})
res.end(
'Something went wrong. And we are reporting a custom error message.'
)
}
```
* **option.onProxyReq**: function, subscribe to http-proxy's `proxyReq` event.
```javascript
function onProxyReq(proxyReq, req, res) {
// add custom header to request
proxyReq.setHeader('x-added', 'foobar');
// or log the req
}
```
- **option.onProxyRes**: function, subscribe to http-proxy's `proxyRes` event.
* **option.onProxyReqWs**: function, subscribe to http-proxy's `proxyReqWs` event.
```javascript
function onProxyReqWs(proxyReq, req, socket, options, head) {
// add custom header
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
}
```
```javascript
function onProxyRes(proxyRes, req, res) {
proxyRes.headers['x-added'] = 'foobar' // add new header to response
delete proxyRes.headers['x-removed'] // remove header from response
}
```
* **option.onOpen**: function, subscribe to http-proxy's `open` event.
```javascript
function onOpen(proxySocket) {
// listen for messages coming FROM the target here
proxySocket.on('data', hybiParseAndLogMessage);
}
```
- **option.onProxyReq**: function, subscribe to http-proxy's `proxyReq` event.
* **option.onClose**: function, subscribe to http-proxy's `close` event.
```javascript
function onClose(res, socket, head) {
// view disconnected websocket connections
console.log('Client disconnected');
}
```
```javascript
function onProxyReq(proxyReq, req, res) {
// add custom header to request
proxyReq.setHeader('x-added', 'foobar')
// or log the req
}
```
- **option.onProxyReqWs**: function, subscribe to http-proxy's `proxyReqWs` event.
```javascript
function onProxyReqWs(proxyReq, req, socket, options, head) {
// add custom header
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar')
}
```
- **option.onOpen**: function, subscribe to http-proxy's `open` event.
```javascript
function onOpen(proxySocket) {
// listen for messages coming FROM the target here
proxySocket.on('data', hybiParseAndLogMessage)
}
```
- **option.onClose**: function, subscribe to http-proxy's `close` event.
```javascript
function onClose(res, socket, head) {
// view disconnected websocket connections
console.log('Client disconnected')
}
```
### http-proxy options

@@ -311,69 +327,67 @@

* **option.target**: url string to be parsed with the url module
* **option.forward**: url string to be parsed with the url module
* **option.agent**: object to be passed to http(s).request (see Node's [https agent](http://nodejs.org/api/https.html#https_class_https_agent) and [http agent](http://nodejs.org/api/http.html#http_class_http_agent) objects)
* **option.ssl**: object to be passed to https.createServer()
* **option.ws**: true/false: if you want to proxy websockets
* **option.xfwd**: true/false, adds x-forward headers
* **option.secure**: true/false, if you want to verify the SSL Certs
* **option.toProxy**: true/false, passes the absolute URL as the `path` (useful for proxying to proxies)
* **option.prependPath**: true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
* **option.ignorePath**: true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
* **option.localAddress** : Local interface string to bind for outgoing connections
* **option.changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
* **option.preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
* **option.auth** : Basic authentication i.e. 'user:password' to compute an Authorization header.
* **option.hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
* **option.autoRewrite**: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
* **option.protocolRewrite**: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
* **option.cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
* `false` (default): disable cookie rewriting
* String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
* Object: mapping of domains to new domains, use `"*"` to match all domains.
For example keep one domain unchanged, rewrite one domain and remove other domains:
```
cookieDomainRewrite: {
"unchanged.domain": "unchanged.domain",
"old.domain": "new.domain",
"*": ""
}
```
* **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
* `false` (default): disable cookie rewriting
* String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
* Object: mapping of paths to new paths, use `"*"` to match all paths.
For example, to keep one path unchanged, rewrite one path and remove other paths:
```
cookiePathRewrite: {
"/unchanged.path/": "/unchanged.path/",
"/old.path/": "/new.path/",
"*": ""
}
```
* **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
* **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
* **option.timeout**: timeout (in millis) for incoming requests
* **option.followRedirects**: true/false, Default: false - specify whether you want to follow redirects
* **option.selfHandleResponse** true/false, 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
* **option.buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:
- **option.target**: url string to be parsed with the url module
- **option.forward**: url string to be parsed with the url module
- **option.agent**: object to be passed to http(s).request (see Node's [https agent](http://nodejs.org/api/https.html#https_class_https_agent) and [http agent](http://nodejs.org/api/http.html#http_class_http_agent) objects)
- **option.ssl**: object to be passed to https.createServer()
- **option.ws**: true/false: if you want to proxy websockets
- **option.xfwd**: true/false, adds x-forward headers
- **option.secure**: true/false, if you want to verify the SSL Certs
- **option.toProxy**: true/false, passes the absolute URL as the `path` (useful for proxying to proxies)
- **option.prependPath**: true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
- **option.ignorePath**: true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
- **option.localAddress** : Local interface string to bind for outgoing connections
- **option.changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
- **option.preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
- **option.auth** : Basic authentication i.e. 'user:password' to compute an Authorization header.
- **option.hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
- **option.autoRewrite**: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
- **option.protocolRewrite**: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
- **option.cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
- `false` (default): disable cookie rewriting
- String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
- Object: mapping of domains to new domains, use `"*"` to match all domains.
For example keep one domain unchanged, rewrite one domain and remove other domains:
```
'use strict';
cookieDomainRewrite: {
"unchanged.domain": "unchanged.domain",
"old.domain": "new.domain",
"*": ""
}
```
- **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
- `false` (default): disable cookie rewriting
- String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
- Object: mapping of paths to new paths, use `"*"` to match all paths.
For example, to keep one path unchanged, rewrite one path and remove other paths:
```
cookiePathRewrite: {
"/unchanged.path/": "/unchanged.path/",
"/old.path/": "/new.path/",
"*": ""
}
```
- **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
- **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
- **option.timeout**: timeout (in millis) for incoming requests
- **option.followRedirects**: true/false, Default: false - specify whether you want to follow redirects
- **option.selfHandleResponse** true/false, 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
- **option.buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:
const streamify = require('stream-array');
const HttpProxy = require('http-proxy');
const proxy = new HttpProxy();
```
'use strict';
module.exports = (req, res, next) => {
const streamify = require('stream-array');
const HttpProxy = require('http-proxy');
const proxy = new HttpProxy();
proxy.web(req, res, {
target: 'http://localhost:4003/',
buffer: streamify(req.rawBody)
}, next);
module.exports = (req, res, next) => {
};
```
proxy.web(req, res, {
target: 'http://localhost:4003/',
buffer: streamify(req.rawBody)
}, next);
};
```
## Shorthand

@@ -384,11 +398,9 @@

```javascript
proxy('http://www.example.org:8000/api');
proxy('http://www.example.org:8000/api')
// proxy('/api', {target: 'http://www.example.org:8000'});
proxy('http://www.example.org:8000/api/books/*/**.json');
proxy('http://www.example.org:8000/api/books/*/**.json')
// proxy('/api/books/*/**.json', {target: 'http://www.example.org:8000'});
proxy('http://www.example.org:8000/api', {changeOrigin:true});
proxy('http://www.example.org:8000/api', { changeOrigin: true })
// proxy('/api', {target: 'http://www.example.org:8000', changeOrigin: true});

@@ -399,12 +411,14 @@ ```

If you want to use the server's `app.use` `path` parameter to match requests;
If you want to use the server's `app.use` `path` parameter to match requests;
Create and mount the proxy without the http-proxy-middleware `context` parameter:
```javascript
app.use('/api', proxy({target:'http://www.example.org', changeOrigin:true}));
app.use('/api', proxy({ target: 'http://www.example.org', changeOrigin: true }))
```
`app.use` documentation:
* express: http://expressjs.com/en/4x/api.html#app.use
* connect: https://github.com/senchalabs/connect#mount-middleware
- express: http://expressjs.com/en/4x/api.html#app.use
- connect: https://github.com/senchalabs/connect#mount-middleware
## WebSocket

@@ -414,9 +428,9 @@

// verbose api
proxy('/', {target:'http://echo.websocket.org', ws:true});
proxy('/', { target: 'http://echo.websocket.org', ws: true })
// shorthand
proxy('http://echo.websocket.org', {ws:true});
proxy('http://echo.websocket.org', { ws: true })
// shorter shorthand
proxy('ws://echo.websocket.org');
proxy('ws://echo.websocket.org')
```

@@ -427,13 +441,13 @@

In the previous WebSocket examples, http-proxy-middleware relies on a initial http request in order to listen to the http `upgrade` event. If you need to proxy WebSockets without the initial http request, you can subscribe to the server's http `upgrade` event manually.
```javascript
var wsProxy = proxy('ws://echo.websocket.org', {changeOrigin:true});
var wsProxy = proxy('ws://echo.websocket.org', { changeOrigin: true })
var app = express();
app.use(wsProxy);
var app = express()
app.use(wsProxy)
var server = app.listen(3000);
server.on('upgrade', wsProxy.upgrade); // <-- subscribe to http 'upgrade'
var server = app.listen(3000)
server.on('upgrade', wsProxy.upgrade) // <-- subscribe to http 'upgrade'
```
## Working examples

@@ -443,6 +457,6 @@

* Browser-Sync ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync/index.js))
* express ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express/index.js))
* connect ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect/index.js))
* WebSocket ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket/index.js))
- Browser-Sync ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync/index.js))
- express ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express/index.js))
- connect ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect/index.js))
- WebSocket ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket/index.js))

@@ -456,11 +470,12 @@ ## Recipes

`http-proxy-middleware` is compatible with the following servers:
* [connect](https://www.npmjs.com/package/connect)
* [express](https://www.npmjs.com/package/express)
* [browser-sync](https://www.npmjs.com/package/browser-sync)
* [lite-server](https://www.npmjs.com/package/lite-server)
* [grunt-contrib-connect](https://www.npmjs.com/package/grunt-contrib-connect)
* [grunt-browser-sync](https://www.npmjs.com/package/grunt-browser-sync)
* [gulp-connect](https://www.npmjs.com/package/gulp-connect)
* [gulp-webserver](https://www.npmjs.com/package/gulp-webserver)
- [connect](https://www.npmjs.com/package/connect)
- [express](https://www.npmjs.com/package/express)
- [browser-sync](https://www.npmjs.com/package/browser-sync)
- [lite-server](https://www.npmjs.com/package/lite-server)
- [grunt-contrib-connect](https://www.npmjs.com/package/grunt-contrib-connect)
- [grunt-browser-sync](https://www.npmjs.com/package/grunt-browser-sync)
- [gulp-connect](https://www.npmjs.com/package/gulp-connect)
- [gulp-webserver](https://www.npmjs.com/package/gulp-webserver)
Sample implementations can be found in the [server recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes/servers.md).

@@ -490,3 +505,2 @@

## License

@@ -493,0 +507,0 @@

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc