A simple http/2 & http/1.1 to http/1.1 spec compliant proxy helper for Node.
- Proxies HTTP 2, HTTP 1 and WebSocket.
- Simple and high performance.
- Hop by hop header handling.
- Connection header handling.
- Via header handling.
- Forward header handling.
$ npm install http2-proxy
http2-proxy
requires at least node v10.0.0.
Request & Response errors are emitted to the server object either as clientError
for http/1 or streamError
for http/2. See the NodeJS documentation for further details.
You need to use an final and/or error handler since errored responses won't be cleaned up automatically.
const finalhandler = require('finalhandler')
const defaultWebHandler = (err, req, res) => {
if (err) {
console.error('proxy error', err)
finalhandler(req, res)(err)
}
}
const defaultWSHandler = (err, req, socket, head) => {
if (err) {
console.error('proxy error', err)
socket.destroy()
}
}
You must pass allowHTTP1: true
to the http2.createServer
or http2.createSecureServer
factory methods.
import http2 from 'http2'
import proxy from 'http2-proxy'
const server = http2.createServer({ allowHTTP1: true })
server.listen(8000)
You can also use http-proxy2
with the old http
&& https
API's.
import http from 'http'
const server = http.createServer()
server.listen(8000)
server.on('request', (req, res) => {
proxy.web(req, res, {
hostname: 'localhost'
port: 9000
}, defaultWebHandler)
})
server.on('upgrade', (req, socket, head) => {
proxy.ws(req, socket, head, {
hostname: 'localhost'
port: 9000
}, defaultWsHandler)
})
const app = connect()
app.use(helmet())
app.use((req, res, next) => proxy
.web(req, res, {
hostname: 'localhost'
port: 9000
}, err => {
if (err) {
next(err)
}
})
)
server.on('request', app)
server.on('request', (req, res) => {
proxy.web(req, res, {
hostname: 'localhost'
port: 9000,
onReq: (req, { headers }) => {
headers['x-forwarded-for'] = req.socket.remoteAddress
headers['x-forwarded-proto'] = req.socket.encrypted ? 'https' : 'http'
headers['x-forwarded-host'] = req.headers['host']
}
}, defaultWebHandler)
})
const http = require('follow-redirects').http
server.on('request', (req, res) => {
proxy.web(req, res, {
hostname: 'localhost'
port: 9000,
onReq: (req, options) => http.request(options)
}, defaultWebHandler)
})
req
:http.IncomingMessage
orhttp2.Http2ServerRequest
.res
:http.ServerResponse
orhttp2.Http2ServerResponse
.options
: See Optionscallback(err, req, res)
: Called on completion or error. Optional.
See request
req
:http.IncomingMessage
.socket
:net.Socket
.head
:Buffer
.options
: See Options.callback(err, req, socket, head)
: Called on completion or error. Optional.
See upgrade
hostname
: Proxyhttp.request(options)
target hostname.port
: Proxyhttp.request(options)
target port.protocol
: 'string' agent protocol ('http' or 'https'). Defaults to 'http'.path
: 'string' target pathname. Defaults toreq.originalUrl || req.url
.proxyTimeout
: Proxyhttp.request(options)
timeout.proxyName
: Proxy name used for Via header.timeout
:http.IncomingMessage
orhttp2.Http2ServerRequest
timeout.onReq(req, options, callback)
: Called before proxy request. If returning a truthy value it will be used as the request.req
:http.IncomingMessage
orhttp2.Http2ServerRequest
options
: Options passed tohttp.request(options)
.callback(err)
: Called on completion or error. Optionally a promise can be returned.
onRes(req, resOrSocket, proxyRes, callback)
: Called before proxy response.req
:http.IncomingMessage
orhttp2.Http2ServerRequest
.resOrSocket
: Forweb
http.ServerResponse
orhttp2.Http2ServerResponse
and forws
net.Socket
.proxyRes
:http.ServerResponse
.callback(err)
: Called on completion or error. Optionally a promise can be returned.