From 804ef224cc3a2570989a60ee233c08347387605a Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 11 Sep 2017 23:52:56 +0200 Subject: [PATCH] fix: dist & gitignore --- .gitignore | 14 --- dist/index.js | 285 ++++++++++++++++++++++++++++++++++++++++++++++ dist/index.js.map | 1 + 3 files changed, 286 insertions(+), 14 deletions(-) create mode 100644 dist/index.js create mode 100644 dist/index.js.map diff --git a/.gitignore b/.gitignore index e03635f..9daa824 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,2 @@ .DS_Store -*.log node_modules -build -bundle-stats.json -*.sublime-workspace -.idea -bower_components -build -coverage -dist -npm-debug.log -public/bundle.js -media -nxt* -db diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..0aaa506 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,285 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _httpErrors = require('http-errors'); + +var _httpErrors2 = _interopRequireDefault(_httpErrors); + +var _http = require('http2'); + +var _http2 = _interopRequireDefault(_http); + +var _http3 = require('http'); + +var _http4 = _interopRequireDefault(_http3); + +var _pump = require('pump'); + +var _pump2 = _interopRequireDefault(_pump); + +var _net = require('net'); + +var _net2 = _interopRequireDefault(_net); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const { + HTTP2_HEADER_CONNECTION, + HTTP2_HEADER_UPGRADE, + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_PATH, + HTTP2_HEADER_HOST, + HTTP2_HEADER_KEEP_ALIVE, + HTTP2_HEADER_PROXY_CONNECTION, + HTTP2_HEADER_TRANSFER_ENCODING, + HTTP2_HEADER_TE, + HTTP2_HEADER_PROXY_AUTHORIZATION, + HTTP2_HEADER_HTTP2_SETTINGS, + HTTP2_HEADER_VIA, + // XXX https://github.com/nodejs/node/issues/15337 + HTTP2_HEADER_FORWARDED = 'forwarded' +} = _http2.default.constants; + +const NODE_VER = process.version.match(/v(\d+).(\d+).(\d+)(?:-(.*))/).slice(1); + +if (NODE_VER[0] < 9 && (NODE_VER[0] !== 8 || NODE_VER[1] > 4)) { + throw new Error(`unsupported node version (${process.version} < 8.5.0)`); +} + +exports.default = { + ws(req, socket, head, options, onProxyError) { + impl(req, socket, head, options, onProxyError); + }, + web(req, res, options, onProxyError) { + impl(req, res, null, options, onProxyError); + } +}; + + +function impl(req, resOrSocket, headOrNil, { + hostname, + port, + timeout, + proxyTimeout, + proxyName, + onReq, + onRes +}, onProxyError) { + function onError(err, statusCode = err && err.statusCode || 500) { + if (resOrSocket.closed === true || resOrSocket.headersSent !== false || !resOrSocket.writeHead) { + resOrSocket.destroy(); + } else { + resOrSocket.writeHead(statusCode); + resOrSocket.end(); + } + + onProxyError(err, req, resOrSocket); + } + + try { + if (resOrSocket instanceof _net2.default.Socket) { + if (req.method !== 'GET') { + throw new _httpErrors2.default.MethodNotAllowed(); + } + + if (!req.headers[HTTP2_HEADER_UPGRADE] || req.headers[HTTP2_HEADER_UPGRADE].toLowerCase() !== 'websocket') { + throw new _httpErrors2.default.BadRequest(); + } + } + + if (!/1\.1|2\.\d/.test(req.httpVersion)) { + throw new _httpErrors2.default.HTTPVersionNotSupported(); + } + + if (proxyName && req.headers[HTTP2_HEADER_VIA] && req.headers[HTTP2_HEADER_VIA].split(',').some(name => name.trim().toLowerCase().endsWith(proxyName.toLowerCase()))) { + throw new _httpErrors2.default.LoopDetected(); + } + + if (timeout) { + req.setTimeout(timeout, () => onError(new _httpErrors2.default.RequestTimeout())); + } + + (req.stream || req).on('error', onError); + + if (resOrSocket instanceof _net2.default.Socket) { + if (headOrNil && headOrNil.length) { + resOrSocket.unshift(headOrNil); + } + + setupSocket(resOrSocket); + } + + const headers = getRequestHeaders(req); + + if (proxyName) { + if (headers[HTTP2_HEADER_VIA]) { + headers[HTTP2_HEADER_VIA] += `,${proxyName}`; + } else { + headers[HTTP2_HEADER_VIA] = proxyName; + } + } + + if (onReq) { + onReq(req, headers); + } + + return proxy(req, resOrSocket, { + method: req.method, + hostname, + port, + path: req.url, + headers, + timeout: proxyTimeout + }, onRes, onError); + } catch (err) { + return onError(err); + } +} + +function proxy(req, resOrSocket, options, onRes, onError) { + const proxyReq = _http4.default.request(options); + + const callback = err => { + if (!proxyReq.aborted) { + proxyReq.abort(); + } + onError(err); + }; + + req.pipe(proxyReq).on('error', err => { + if (err.code === 'ECONNREFUSED' || err.code === 'ENOTFOUND') { + callback(new _httpErrors2.default.ServiceUnavailable(err.message)); + } else if (/HPE_INVALID/.test(err.code)) { + callback(new _httpErrors2.default.BadGateway(err.message)); + } else { + callback(err); + } + }).on('timeout', () => callback(new _httpErrors2.default.GatewayTimeout())).on('response', proxyRes => { + try { + proxyRes.on('aborted', () => callback(new _httpErrors2.default.BadGateway('socket hang up'))); + + if (resOrSocket instanceof _net2.default.Socket) { + if (!proxyRes.upgrade) { + resOrSocket.end(); + } + } else { + const headers = setupHeaders(_extends({}, proxyRes.headers)); + + if (onRes) { + onRes(req, headers); + } + + resOrSocket.writeHead(proxyRes.statusCode, headers); + proxyRes.on('end', () => { + resOrSocket.addTrailers(proxyRes.trailers); + }); + (0, _pump2.default)(proxyRes, resOrSocket, err => err && callback(err)); + } + } catch (err) { + callback(err); + } + }); + + if (resOrSocket instanceof _net2.default.Socket) { + proxyReq.on('upgrade', (proxyRes, proxySocket, proxyHead) => { + try { + setupSocket(proxySocket); + + if (proxyHead && proxyHead.length) { + proxySocket.unshift(proxyHead); + } + + resOrSocket.write(Object.keys(proxyRes.headers).reduce((head, key) => { + const value = proxyRes.headers[key]; + + if (!Array.isArray(value)) { + head.push(key + ': ' + value); + return head; + } + + for (let i = 0; i < value.length; i++) { + head.push(key + ': ' + value[i]); + } + + return head; + }, ['HTTP/1.1 101 Switching Protocols']).join('\r\n') + '\r\n\r\n'); + + (0, _pump2.default)(proxySocket, resOrSocket, proxySocket, err => err && callback(err)); + } catch (err) { + callback(err); + } + }); + } +} + +function getRequestHeaders(req) { + const headers = setupHeaders(_extends({}, req.headers)); + + // Remove pseudo headers + delete headers[HTTP2_HEADER_AUTHORITY]; + delete headers[HTTP2_HEADER_METHOD]; + delete headers[HTTP2_HEADER_PATH]; + delete headers[HTTP2_HEADER_SCHEME]; + + if (req.headers[HTTP2_HEADER_UPGRADE]) { + headers[HTTP2_HEADER_CONNECTION] = 'upgrade'; + headers[HTTP2_HEADER_UPGRADE] = 'websocket'; + } + + const fwd = { + by: req.headers[HTTP2_HEADER_AUTHORITY] || req.headers[HTTP2_HEADER_HOST], + proto: req.socket.encrypted ? 'https' : 'http', + // TODO: Is this correct? + for: [req.socket.remoteAddress] + }; + + if (req.headers[HTTP2_HEADER_FORWARDED]) { + const expr = /for=\s*([^\s]+)/i; + while (true) { + const m = expr.exec(req.headers[HTTP2_HEADER_FORWARDED]); + if (!m) { + break; + } + fwd.for.push(m); + } + } + + headers[HTTP2_HEADER_FORWARDED] = [`by=${fwd.by}`, fwd.for.map(address => `for=${address}`).join('; '), fwd.host && `host=${fwd.host}`, `proto=${fwd.proto}`].filter(x => x).join('; '); + + return headers; +} + +function setupSocket(socket) { + socket.setTimeout(0); + socket.setNoDelay(true); + socket.setKeepAlive(true, 0); +} + +function setupHeaders(headers) { + const connection = headers[HTTP2_HEADER_CONNECTION]; + + if (connection && connection !== 'close') { + for (const key of connection.split(',')) { + delete headers[key.trim().toLowerCase()]; + } + } + + delete headers[HTTP2_HEADER_CONNECTION]; + delete headers[HTTP2_HEADER_KEEP_ALIVE]; + delete headers[HTTP2_HEADER_TRANSFER_ENCODING]; + delete headers[HTTP2_HEADER_TE]; + delete headers[HTTP2_HEADER_UPGRADE]; + delete headers[HTTP2_HEADER_PROXY_AUTHORIZATION]; + delete headers[HTTP2_HEADER_PROXY_CONNECTION]; + delete headers[HTTP2_HEADER_HTTP2_SETTINGS]; + + return headers; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..36c7515 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/index.js"],"names":["HTTP2_HEADER_CONNECTION","HTTP2_HEADER_UPGRADE","HTTP2_HEADER_AUTHORITY","HTTP2_HEADER_METHOD","HTTP2_HEADER_SCHEME","HTTP2_HEADER_PATH","HTTP2_HEADER_HOST","HTTP2_HEADER_KEEP_ALIVE","HTTP2_HEADER_PROXY_CONNECTION","HTTP2_HEADER_TRANSFER_ENCODING","HTTP2_HEADER_TE","HTTP2_HEADER_PROXY_AUTHORIZATION","HTTP2_HEADER_HTTP2_SETTINGS","HTTP2_HEADER_VIA","HTTP2_HEADER_FORWARDED","constants","NODE_VER","process","version","match","slice","Error","ws","req","socket","head","options","onProxyError","impl","web","res","resOrSocket","headOrNil","hostname","port","timeout","proxyTimeout","proxyName","onReq","onRes","onError","err","statusCode","closed","headersSent","writeHead","destroy","end","Socket","method","MethodNotAllowed","headers","toLowerCase","BadRequest","test","httpVersion","HTTPVersionNotSupported","split","some","name","trim","endsWith","LoopDetected","setTimeout","RequestTimeout","stream","on","length","unshift","setupSocket","getRequestHeaders","proxy","path","url","proxyReq","request","callback","aborted","abort","pipe","code","ServiceUnavailable","message","BadGateway","GatewayTimeout","proxyRes","upgrade","setupHeaders","addTrailers","trailers","proxySocket","proxyHead","write","Object","keys","reduce","key","value","Array","isArray","push","i","join","fwd","by","proto","encrypted","for","remoteAddress","expr","m","exec","map","address","host","filter","x","setNoDelay","setKeepAlive","connection"],"mappings":"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","file":"index.js","sourcesContent":["import createError from 'http-errors'\nimport http2 from 'http2'\nimport http from 'http'\nimport pump from 'pump'\nimport net from 'net'\n\nconst {\n HTTP2_HEADER_CONNECTION,\n HTTP2_HEADER_UPGRADE,\n HTTP2_HEADER_AUTHORITY,\n HTTP2_HEADER_METHOD,\n HTTP2_HEADER_SCHEME,\n HTTP2_HEADER_PATH,\n HTTP2_HEADER_HOST,\n HTTP2_HEADER_KEEP_ALIVE,\n HTTP2_HEADER_PROXY_CONNECTION,\n HTTP2_HEADER_TRANSFER_ENCODING,\n HTTP2_HEADER_TE,\n HTTP2_HEADER_PROXY_AUTHORIZATION,\n HTTP2_HEADER_HTTP2_SETTINGS,\n HTTP2_HEADER_VIA,\n // XXX https://github.com/nodejs/node/issues/15337\n HTTP2_HEADER_FORWARDED = 'forwarded'\n} = http2.constants\n\nconst NODE_VER = process.version.match(/v(\\d+).(\\d+).(\\d+)(?:-(.*))/).slice(1)\n\nif (NODE_VER[0] < 9 && (NODE_VER[0] !== 8 || NODE_VER[1] > 4)) {\n throw new Error(`unsupported node version (${process.version} < 8.5.0)`)\n}\n\nexport default {\n ws (req, socket, head, options, onProxyError) {\n impl(req, socket, head, options, onProxyError)\n },\n web (req, res, options, onProxyError) {\n impl(req, res, null, options, onProxyError)\n }\n}\n\nfunction impl (req, resOrSocket, headOrNil, {\n hostname,\n port,\n timeout,\n proxyTimeout,\n proxyName,\n onReq,\n onRes\n}, onProxyError) {\n function onError (err, statusCode = (err && err.statusCode) || 500) {\n if (resOrSocket.closed === true ||\n resOrSocket.headersSent !== false ||\n !resOrSocket.writeHead\n ) {\n resOrSocket.destroy()\n } else {\n resOrSocket.writeHead(statusCode)\n resOrSocket.end()\n }\n\n onProxyError(err, req, resOrSocket)\n }\n\n try {\n if (resOrSocket instanceof net.Socket) {\n if (req.method !== 'GET') {\n throw new createError.MethodNotAllowed()\n }\n\n if (!req.headers[HTTP2_HEADER_UPGRADE] ||\n req.headers[HTTP2_HEADER_UPGRADE].toLowerCase() !== 'websocket') {\n throw new createError.BadRequest()\n }\n }\n\n if (!/1\\.1|2\\.\\d/.test(req.httpVersion)) {\n throw new createError.HTTPVersionNotSupported()\n }\n\n if (proxyName &&\n req.headers[HTTP2_HEADER_VIA] &&\n req.headers[HTTP2_HEADER_VIA]\n .split(',')\n .some(name => name.trim().toLowerCase().endsWith(proxyName.toLowerCase()))\n ) {\n throw new createError.LoopDetected()\n }\n\n if (timeout) {\n req.setTimeout(timeout, () => onError(new createError.RequestTimeout()))\n }\n\n (req.stream || req).on('error', onError)\n\n if (resOrSocket instanceof net.Socket) {\n if (headOrNil && headOrNil.length) {\n resOrSocket.unshift(headOrNil)\n }\n\n setupSocket(resOrSocket)\n }\n\n const headers = getRequestHeaders(req)\n\n if (proxyName) {\n if (headers[HTTP2_HEADER_VIA]) {\n headers[HTTP2_HEADER_VIA] += `,${proxyName}`\n } else {\n headers[HTTP2_HEADER_VIA] = proxyName\n }\n }\n\n if (onReq) {\n onReq(req, headers)\n }\n\n return proxy(req, resOrSocket, {\n method: req.method,\n hostname,\n port,\n path: req.url,\n headers,\n timeout: proxyTimeout\n }, onRes, onError)\n } catch (err) {\n return onError(err)\n }\n}\n\nfunction proxy (req, resOrSocket, options, onRes, onError) {\n const proxyReq = http.request(options)\n\n const callback = err => {\n if (!proxyReq.aborted) {\n proxyReq.abort()\n }\n onError(err)\n }\n\n req\n .pipe(proxyReq)\n .on('error', err => {\n if (err.code === 'ECONNREFUSED' || err.code === 'ENOTFOUND') {\n callback(new createError.ServiceUnavailable(err.message))\n } else if (/HPE_INVALID/.test(err.code)) {\n callback(new createError.BadGateway(err.message))\n } else {\n callback(err)\n }\n })\n .on('timeout', () => callback(new createError.GatewayTimeout()))\n .on('response', proxyRes => {\n try {\n proxyRes.on('aborted', () => callback(new createError.BadGateway('socket hang up')))\n\n if (resOrSocket instanceof net.Socket) {\n if (!proxyRes.upgrade) {\n resOrSocket.end()\n }\n } else {\n const headers = setupHeaders({ ...proxyRes.headers })\n\n if (onRes) {\n onRes(req, headers)\n }\n\n resOrSocket.writeHead(proxyRes.statusCode, headers)\n proxyRes.on('end', () => {\n resOrSocket.addTrailers(proxyRes.trailers)\n })\n pump(proxyRes, resOrSocket, err => err && callback(err))\n }\n } catch (err) {\n callback(err)\n }\n })\n\n if (resOrSocket instanceof net.Socket) {\n proxyReq.on('upgrade', (proxyRes, proxySocket, proxyHead) => {\n try {\n setupSocket(proxySocket)\n\n if (proxyHead && proxyHead.length) {\n proxySocket.unshift(proxyHead)\n }\n\n resOrSocket.write(\n Object\n .keys(proxyRes.headers)\n .reduce((head, key) => {\n const value = proxyRes.headers[key]\n\n if (!Array.isArray(value)) {\n head.push(key + ': ' + value)\n return head\n }\n\n for (let i = 0; i < value.length; i++) {\n head.push(key + ': ' + value[i])\n }\n\n return head\n }, ['HTTP/1.1 101 Switching Protocols'])\n .join('\\r\\n') + '\\r\\n\\r\\n'\n )\n\n pump(proxySocket, resOrSocket, proxySocket, err => err && callback(err))\n } catch (err) {\n callback(err)\n }\n })\n }\n}\n\nfunction getRequestHeaders (req) {\n const headers = setupHeaders({ ...req.headers })\n\n // Remove pseudo headers\n delete headers[HTTP2_HEADER_AUTHORITY]\n delete headers[HTTP2_HEADER_METHOD]\n delete headers[HTTP2_HEADER_PATH]\n delete headers[HTTP2_HEADER_SCHEME]\n\n if (req.headers[HTTP2_HEADER_UPGRADE]) {\n headers[HTTP2_HEADER_CONNECTION] = 'upgrade'\n headers[HTTP2_HEADER_UPGRADE] = 'websocket'\n }\n\n const fwd = {\n by: req.headers[HTTP2_HEADER_AUTHORITY] || req.headers[HTTP2_HEADER_HOST],\n proto: req.socket.encrypted ? 'https' : 'http',\n // TODO: Is this correct?\n for: [ req.socket.remoteAddress ]\n }\n\n if (req.headers[HTTP2_HEADER_FORWARDED]) {\n const expr = /for=\\s*([^\\s]+)/i\n while (true) {\n const m = expr.exec(req.headers[HTTP2_HEADER_FORWARDED])\n if (!m) {\n break\n }\n fwd.for.push(m)\n }\n }\n\n headers[HTTP2_HEADER_FORWARDED] = [\n `by=${fwd.by}`,\n fwd.for.map(address => `for=${address}`).join('; '),\n fwd.host && `host=${fwd.host}`,\n `proto=${fwd.proto}`\n ].filter(x => x).join('; ')\n\n return headers\n}\n\nfunction setupSocket (socket) {\n socket.setTimeout(0)\n socket.setNoDelay(true)\n socket.setKeepAlive(true, 0)\n}\n\nfunction setupHeaders (headers) {\n const connection = headers[HTTP2_HEADER_CONNECTION]\n\n if (connection && connection !== 'close') {\n for (const key of connection.split(',')) {\n delete headers[key.trim().toLowerCase()]\n }\n }\n\n delete headers[HTTP2_HEADER_CONNECTION]\n delete headers[HTTP2_HEADER_KEEP_ALIVE]\n delete headers[HTTP2_HEADER_TRANSFER_ENCODING]\n delete headers[HTTP2_HEADER_TE]\n delete headers[HTTP2_HEADER_UPGRADE]\n delete headers[HTTP2_HEADER_PROXY_AUTHORIZATION]\n delete headers[HTTP2_HEADER_PROXY_CONNECTION]\n delete headers[HTTP2_HEADER_HTTP2_SETTINGS]\n\n return headers\n}\n"]} \ No newline at end of file