Socket
Socket
Sign inDemoInstall

http2-proxy

Package Overview
Dependencies
0
Maintainers
1
Versions
193
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.12 to 0.2.13

220

index.js

@@ -25,2 +25,3 @@ const http2 = require('http2')

const NODE_VER = process.version.match(/v(\d+).(\d+).(\d+)(?:-(.*))/).slice(1)
const REQ_OPTIONS = {}

@@ -56,69 +57,64 @@ if (NODE_VER[0] < 9 && (NODE_VER[0] !== 8 || NODE_VER[1] > 4)) {

try {
if (resOrSocket instanceof net.Socket) {
if (req.method !== 'GET') {
throw createError('method not allowed', null, 405)
}
if (!req.headers[HTTP2_HEADER_UPGRADE] ||
req.headers[HTTP2_HEADER_UPGRADE].toLowerCase() !== 'websocket') {
throw createError('bad request', null, 400)
}
if (resOrSocket instanceof net.Socket) {
if (req.method !== 'GET') {
return errorHandler(createError('method not allowed', null, 405))
}
if (!/1\.1|2\.\d/.test(req.httpVersion)) {
throw createError('http version not supported', null, 505)
if (!req.headers[HTTP2_HEADER_UPGRADE] ||
req.headers[HTTP2_HEADER_UPGRADE].toLowerCase() !== 'websocket') {
return errorHandler(createError('bad request', null, 400))
}
}
if (proxyName && req.headers[HTTP2_HEADER_VIA]) {
for (const name of req.headers[HTTP2_HEADER_VIA].split(',')) {
if (sanitize(name).endsWith(proxyName.toLowerCase())) {
throw createError('loop detected', null, 508)
}
if (req.httpVersion !== '1.1' && req.httpVersion !== '2.0') {
return errorHandler(createError('http version not supported', null, 505))
}
if (proxyName && req.headers[HTTP2_HEADER_VIA]) {
for (const name of req.headers[HTTP2_HEADER_VIA].split(',')) {
if (sanitize(name).endsWith(proxyName.toLowerCase())) {
return errorHandler(createError('loop detected', null, 508))
}
}
}
if (timeout) {
req.setTimeout(timeout, errorHandler.requestTimeout)
}
if (timeout) {
req.setTimeout(timeout, errorHandler.requestTimeout)
}
if (resOrSocket instanceof net.Socket) {
if (headOrNil && headOrNil.length) {
resOrSocket.unshift(headOrNil)
}
setupSocket(resOrSocket)
if (resOrSocket instanceof net.Socket) {
if (headOrNil && headOrNil.length) {
resOrSocket.unshift(headOrNil)
}
const headers = getRequestHeaders(req)
setupSocket(resOrSocket)
}
if (proxyName) {
if (headers[HTTP2_HEADER_VIA]) {
headers[HTTP2_HEADER_VIA] += `,${proxyName}`
} else {
headers[HTTP2_HEADER_VIA] = proxyName
}
}
const headers = getRequestHeaders(req)
const options = {
method: req.method,
hostname,
port,
path: req.url,
headers,
timeout: proxyTimeout
if (proxyName) {
if (headers[HTTP2_HEADER_VIA]) {
headers[HTTP2_HEADER_VIA] += `,${proxyName}`
} else {
headers[HTTP2_HEADER_VIA] = proxyName
}
}
if (onReq) {
onReq(req, options)
}
REQ_OPTIONS.method = req.method
REQ_OPTIONS.hostname = hostname
REQ_OPTIONS.port = port
REQ_OPTIONS.path = req.url
REQ_OPTIONS.headers = headers
REQ_OPTIONS.timeout = proxyTimeout
return proxy(req, resOrSocket, options, onRes, errorHandler)
} catch (err) {
return errorHandler(err)
if (onReq) {
onReq(req, REQ_OPTIONS)
}
const proxyReq = http.request(REQ_OPTIONS)
proxy(req, resOrSocket, proxyReq, onRes, errorHandler)
}
function proxy (req, resOrSocket, options, onRes, errorHandler) {
const proxyReq = http.request(options)
function proxy (req, resOrSocket, proxyReq, onRes, errorHandler) {
const proxyErrorHandler = ProxyErrorHandler.create(req, proxyReq, errorHandler)

@@ -141,2 +137,6 @@

function getRequestHeaders (req) {
const host = req.headers[HTTP2_HEADER_AUTHORITY] || req.headers[HTTP2_HEADER_HOST]
const upgrade = req.headers[HTTP2_HEADER_UPGRADE]
const forwarded = req.headers[HTTP2_HEADER_FORWARDED]
const headers = setupHeaders(Object.assign({}, req.headers))

@@ -150,3 +150,3 @@

if (req.headers[HTTP2_HEADER_UPGRADE]) {
if (upgrade) {
headers[HTTP2_HEADER_CONNECTION] = 'upgrade'

@@ -159,6 +159,6 @@ headers[HTTP2_HEADER_UPGRADE] = 'websocket'

if (req.headers[HTTP2_HEADER_FORWARDED]) {
if (forwarded) {
const expr = /for=\s*([^\s]+)/ig
while (true) {
const m = expr.exec(req.headers[HTTP2_HEADER_FORWARDED])
const m = expr.exec(forwarded)
if (!m) {

@@ -171,3 +171,2 @@ break

const host = req.headers[HTTP2_HEADER_AUTHORITY] || req.headers[HTTP2_HEADER_HOST]
if (host) {

@@ -265,2 +264,3 @@ headers[HTTP2_HEADER_FORWARDED] += `; host=${host}`

this.callback = null
ErrorHandler.pool.push(this)

@@ -283,6 +283,7 @@ }

constructor () {
this.hasError = null
this.hasError = false
this.req = null
this.proxyReq = null
this.errorHandler = null
this.hpeExpr = /HPE_INVALID/

@@ -304,3 +305,3 @@ this._release = this._release.bind(this)

err.statusCode = 503
} else if (/HPE_INVALID/.test(err.code)) {
} else if (this.hpeExpr.test(err.code)) {
err.statusCode = 502

@@ -336,6 +337,7 @@ } else if (err.code === 'ECONNRESET') {

this.hasError = null
this.hasError = false
this.req = null
this.proxyReq = null
this.errorHandler = null
ProxyErrorHandler.pool.push(this)

@@ -375,33 +377,29 @@ }

try {
proxyRes.on('aborted', this.proxyErrorHandler.socketHangup)
proxyRes.on('aborted', this.proxyErrorHandler.socketHangup)
if (this.resOrSocket instanceof net.Socket) {
if (this.onRes) {
this.onRes(this.req, this.resOrSocket)
}
if (this.resOrSocket instanceof net.Socket) {
if (this.onRes) {
this.onRes(this.req, this.resOrSocket)
}
if (!proxyRes.upgrade) {
this.resOrSocket.end()
}
} else {
setupHeaders(proxyRes.headers)
if (!proxyRes.upgrade) {
this.resOrSocket.end()
}
} else {
setupHeaders(proxyRes.headers)
this.resOrSocket.statusCode = proxyRes.statusCode
for (const key of Object.keys(proxyRes.headers)) {
this.resOrSocket.setHeader(key, proxyRes.headers[key])
}
this.resOrSocket.statusCode = proxyRes.statusCode
for (const key of Object.keys(proxyRes.headers)) {
this.resOrSocket.setHeader(key, proxyRes.headers[key])
}
if (this.onRes) {
this.onRes(this.req, this.resOrSocket)
}
if (this.onRes) {
this.onRes(this.req, this.resOrSocket)
}
this.resOrSocket.writeHead(this.resOrSocket.statusCode)
proxyRes.on('end', this._addTrailers)
proxyRes
.on('error', this.proxyErrorHandler)
.pipe(this.resOrSocket)
}
} catch (err) {
this.proxyErrorHandler(err)
this.resOrSocket.writeHead(this.resOrSocket.statusCode)
proxyRes.on('end', this._addTrailers)
proxyRes
.on('error', this.proxyErrorHandler)
.pipe(this.resOrSocket)
}

@@ -411,2 +409,6 @@ }

_release () {
if (this.proxyRes) {
this.proxyRes.destroy()
}
this.req = null

@@ -417,2 +419,3 @@ this.resOrSocket = null

this.proxyRes = null
ProxyResponseHandler.pool.push(this)

@@ -450,41 +453,41 @@ }

try {
setupSocket(proxySocket)
setupSocket(proxySocket)
if (proxyHead && proxyHead.length) {
proxySocket.unshift(proxyHead)
}
if (proxyHead && proxyHead.length) {
proxySocket.unshift(proxyHead)
}
let head = 'HTTP/1.1 101 Switching Protocols'
let head = 'HTTP/1.1 101 Switching Protocols'
for (const key of Object.keys(proxyRes.headers)) {
const value = proxyRes.headers[key]
for (const key of Object.keys(proxyRes.headers)) {
const value = proxyRes.headers[key]
if (!Array.isArray(value)) {
head += '\r\n' + key + ': ' + value
} else {
for (let i = 0; i < value.length; i++) {
head += '\r\n' + key + ': ' + value[i]
}
if (!Array.isArray(value)) {
head += '\r\n' + key + ': ' + value
} else {
for (let i = 0; i < value.length; i++) {
head += '\r\n' + key + ': ' + value[i]
}
}
}
head += '\r\n\r\n'
head += '\r\n\r\n'
this.resOrSocket.write(head)
this.resOrSocket.write(head)
proxyRes.on('error', this.proxyErrorHandler)
proxyRes.on('error', this.proxyErrorHandler)
proxySocket
.on('error', this.proxyErrorHandler)
.pipe(this.resOrSocket)
.pipe(proxySocket)
} catch (err) {
this.proxyErrorHandler(err)
}
proxySocket
.on('error', this.proxyErrorHandler)
.pipe(this.resOrSocket)
.pipe(proxySocket)
}
_release () {
this.proxyRes.destroy()
this.proxySocket.destroy()
if (this.proxyRes) {
this.proxyRes.destroy()
}
if (this.proxySocket) {
this.proxySocket.destroy()
}

@@ -496,2 +499,3 @@ this.req = null

this.proxySocket = null
ProxyUpgradeHandler.pool.push(this)

@@ -498,0 +502,0 @@ }

{
"name": "http2-proxy",
"version": "0.2.12",
"version": "0.2.13",
"scripts": {

@@ -5,0 +5,0 @@ "dev": "nodemon --inspect=9308 --expose-http2 src",

@@ -23,3 +23,3 @@ # node-http2-proxy

`http2-proxy` requires node **v8.5.0** or newer with `http2` enabled. See [nightly node builds](https://nodejs.org/download/nightly/) or [building node from source](https://github.com/nodejs/node/blob/master/BUILDING.md#building-nodejs-on-supported-platforms). Pass the `--expose-http2` option when starting node **v8.x.x**.
`http2-proxy` requires node **v8.5.0** or newer with `http2` enabled. Pass the `--expose-http2` option when starting node **v8.x.x**.

@@ -87,6 +87,6 @@ ### Usage

- `req`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or [`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverrequest)
- `res`: [`http.ServerResponse`](https://nodejs.org/api/http.html#http_http_request_options_callback) or [`http2.Http2ServerResponse`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverresponse)
- `options`: see [Options](#options)
- `onProxyError(err)`: called on error
- `req`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or [`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverrequest).
- `res`: [`http.ServerResponse`](https://nodejs.org/api/http.html#http_http_request_options_callback) or [`http2.Http2ServerResponse`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverresponse).
- `options`: See [Options](#options).
- `onProxyError(err)`: Called on error.

@@ -97,7 +97,7 @@ See [`request`](https://nodejs.org/api/http.html#http_event_request)

- `req`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
- `socket`: [`net.Socket`](https://nodejs.org/api/net.html#net_class_net_socket)
- `head`: [`Buffer`](https://nodejs.org/api/buffer.html#buffer_class_buffer)
- `options`: see [Options](#options)
- `onProxyError(err)`: called on error
- `req`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage).
- `socket`: [`net.Socket`](https://nodejs.org/api/net.html#net_class_net_socket).
- `head`: [`Buffer`](https://nodejs.org/api/buffer.html#buffer_class_buffer).
- `options`: See [Options](#options).
- `onProxyError(err)`: Called on error.

@@ -108,13 +108,13 @@ See [`upgrade`](https://nodejs.org/api/http.html#http_event_upgrade)

- `hostname`: proxy [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback) target hostname
- `port`: proxy [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback) target port
- `proxyTimeout`: proxy [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback) timeout
- `proxyName`: proxy name used for **Via** header
- `hostname`: Proxy [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback) target hostname.
- `port`: Proxy [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback) target port.
- `proxyTimeout`: Proxy [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback) timeout.
- `proxyName`: Proxy name used for **Via** header.
- `timeout`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or [`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverrequest) timeout
- `onReq(req, options)`: called before proxy request
- `onReq(req, options)`: Called before proxy request. Note you cannot keep a reference to the options object as it will be re-used by `http2-proxy`.
- `req`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or [`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverrequest)
- `options`: options passed to [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback)
- `onRes(req, resOrSocket)`: called before proxy response
- `req`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or [`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverrequest)
- `resOrSocket`: For `web` [`http.ServerResponse`](https://nodejs.org/api/http.html#http_http_request_options_callback) or [`http2.Http2ServerResponse`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverresponse) and for `ws` [`net.Socket`](https://nodejs.org/api/net.html#net_class_net_socket)
- `options`: Options passed to [`http.request(options)`](https://nodejs.org/api/http.html#http_http_request_options_callback).
- `onRes(req, resOrSocket)`: Called before proxy response.
- `req`: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or [`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverrequest).
- `resOrSocket`: For `web` [`http.ServerResponse`](https://nodejs.org/api/http.html#http_http_request_options_callback) or [`http2.Http2ServerResponse`](https://nodejs.org/api/http2.html#http2_class_http2_http2serverresponse) and for `ws` [`net.Socket`](https://nodejs.org/api/net.html#net_class_net_socket).

@@ -121,0 +121,0 @@ ### License

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc