reverse-proxy-middleware 0.0.144 → 0.0.145

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/helper.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { BufferedHTTPServerRequest, EvaluationParameters, EvaluationScopeStateAPIs, Forwarders, HTTPServerResponse, ResolvedHeaderTransformation, ResolvedForwarder, ResolvedForwarders } from './type';
1
+ import type { BufferedHTTPServerRequest, Configuration, EvaluationParameters, EvaluationScopeStateAPIs, Forwarders, HTTPServerResponse, ResolvedHeaderTransformation, ResolvedForwarder, ResolvedForwarders, Server } from './type';
2
2
  import { Logger } from 'clientnode';
3
3
  export declare const EVALUATION_SCOPE_NAMES: readonly ["array", "datetime", "filesystem", "functions", "indicators", "logger", "module", "number", "object", "string", "utility", "data", "error", "request", "response", "stateAPI", "stateAPIs"];
4
4
  export declare const log: Logger;
@@ -11,4 +11,30 @@ export declare const resolveForwarders: (forwarders: Forwarders) => ResolvedForw
11
11
  export declare const addParsedContentToRequest: (bufferedRequest: BufferedHTTPServerRequest) => void;
12
12
  export declare const transformHeaders: (content: string, headerTransformations: Array<ResolvedHeaderTransformation>, parameters: EvaluationParameters) => string;
13
13
  export declare const reverseProxyBufferedRequest: (request: BufferedHTTPServerRequest, response: HTTPServerResponse, forwarder: ResolvedForwarder, stateAPIScope: EvaluationScopeStateAPIs) => Promise<void>;
14
+ /**
15
+ * Loads the package configuration extended by "configuration.json" and
16
+ * "secure-configuration.json" files found in given directory and evaluates
17
+ * all dynamic values.
18
+ * @param directoryPath - Directory to search configuration files in.
19
+ * @param baseConfiguration - Configuration to extend.
20
+ * @returns A promise resolving to the evaluated configuration.
21
+ */
22
+ export declare const loadConfiguration: (directoryPath?: string, baseConfiguration?: Configuration) => Promise<Configuration>;
23
+ /**
24
+ * Waits until given request is fully buffered, determines its forwarder,
25
+ * applies the forwarder's state apis and forwards the request.
26
+ * @param request - Buffered client request.
27
+ * @param response - Response to the client.
28
+ * @param forwarders - Forwarders to choose from.
29
+ * @param parseBody - Indicates whether to parse a json request body.
30
+ * @returns A promise resolving when the request has been processed.
31
+ */
32
+ export declare const handleRequest: (request: BufferedHTTPServerRequest, response: HTTPServerResponse, forwarders: ResolvedForwarders, parseBody?: boolean) => Promise<void>;
33
+ /**
34
+ * Creates a (not yet listening) server forwarding incoming requests.
35
+ * @param configuration - Server configuration.
36
+ * @param forwarders - Forwarders to use for incoming requests.
37
+ * @returns The created server.
38
+ */
39
+ export declare const createServer: (configuration: Configuration, forwarders?: ResolvedForwarders) => Server;
14
40
  export default reverseProxyBufferedRequest;
package/dist/helper.js CHANGED
@@ -1,5 +1,9 @@
1
1
  import * as __WEBPACK_EXTERNAL_MODULE_clientnode__ from "clientnode";
2
+ import { readFile as __WEBPACK_EXTERNAL_MODULE_fs_promises_cc1b69f3_readFile__ } from "fs/promises";
3
+ import { createServer as __WEBPACK_EXTERNAL_MODULE_http_createServer__ } from "http";
4
+ import { createSecureServer as __WEBPACK_EXTERNAL_MODULE_http2_createSecureServer__ } from "http2";
2
5
  import { createConnection as __WEBPACK_EXTERNAL_MODULE_net_createConnection__ } from "net";
6
+ import { resolve as __WEBPACK_EXTERNAL_MODULE_path_resolve__ } from "path";
3
7
  import { connect as __WEBPACK_EXTERNAL_MODULE_tls_connect__ } from "tls";
4
8
  /******/ var __webpack_modules__ = ([
5
9
  /* 0 */,
@@ -10,7 +14,7 @@ const x = (y) => {
10
14
  const x = {}; __webpack_require__.d(x, y); return x
11
15
  }
12
16
  const y = (x) => (() => (x))
13
- module.exports = x({ ["Logger"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.Logger), ["UTILITY_SCOPE_NAMES"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.UTILITY_SCOPE_NAMES), ["UTILITY_SCOPE_VALUES"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.UTILITY_SCOPE_VALUES), ["compile"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.compile), ["copy"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.copy), ["extend"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.extend), ["modifyObject"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.modifyObject), ["represent"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.represent) });
17
+ module.exports = x({ ["Logger"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.Logger), ["MAXIMAL_NUMBER_OF_ITERATIONS"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.MAXIMAL_NUMBER_OF_ITERATIONS), ["UTILITY_SCOPE"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.UTILITY_SCOPE), ["UTILITY_SCOPE_NAMES"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.UTILITY_SCOPE_NAMES), ["UTILITY_SCOPE_VALUES"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.UTILITY_SCOPE_VALUES), ["compile"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.compile), ["copy"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.copy), ["evaluateAsyncDynamicData"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.evaluateAsyncDynamicData), ["evaluateDynamicData"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.evaluateDynamicData), ["extend"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.extend), ["isFile"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.isFile), ["modifyObject"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.modifyObject), ["represent"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.represent), ["timeout"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.timeout) });
14
18
 
15
19
  /***/ })
16
20
  /******/ ]);
@@ -57,10 +61,20 @@ module.exports = x({ ["Logger"]: () => (__WEBPACK_EXTERNAL_MODULE_clientnode__.L
57
61
 
58
62
  // EXTERNAL MODULE: external "clientnode"
59
63
  var external_clientnode_ = __webpack_require__(1);
64
+ ;// external "fs/promises"
65
+
66
+ ;// external "http"
67
+
68
+ ;// external "http2"
69
+
60
70
  ;// external "net"
61
71
 
72
+ ;// external "path"
73
+
62
74
  ;// external "tls"
63
75
 
76
+ ;// ./package.json
77
+ const package_namespaceObject = /*#__PURE__*/JSON.parse('{"HF":{"forwarders":{"base":{"headerTransformations":{"retrieve":[],"send":[]},"host":"localhost","port":443,"stateAPIs":[{"data":{},"expressions":{"post":"true","pre":"false"},"name":"base","options":{},"url":""}],"tls":true,"useExpression":"true"}},"host":"localhost","nodeServerOptions":{"allowHTTP1":true},"parseBody":false,"port":8080,"privateKeyPath":"","publicKeyPath":""}}');
64
78
  ;// ./src/helper.ts
65
79
  // #!/usr/bin/env babel-node
66
80
  // -*- coding: utf-8 -*-
@@ -96,7 +110,39 @@ var addParsedContentToRequest=function addParsedContentToRequest(bufferedRequest
96
110
  // Add new header.
97
111
  content=content.replace(/(\s*\n)\s*\n\s*/,function(substring,delimiter){for(var _len=arguments.length,parameters=new Array(_len>2?_len-2:0),_key=2;_key<_len;_key++){parameters[_key-2]=arguments[_key]}var result=typeof target==="string"?target:target?target.apply(void 0,[substring,delimiter].concat(parameters)):"";return"".concat(delimiter).concat(result).concat(substring)})}else{if(!newLinePrinted){void log.debug();newLinePrinted=true}// Search and replace (or remove) header.
98
112
  void log.debug("Search for \"".concat(source,"\" and replace with"),"".concat((0,external_clientnode_.represent)(target),"."));if(source)content=content.replace(source,target)}}catch(error){void log.warn("\nCould not apply header transformation with source "+(transformation.source?(0,external_clientnode_.represent)(transformation.source):"\"add\"")+" and replacement "+(transformation.target?(0,external_clientnode_.represent)(transformation.target):"\"remove\"")+":",error)}};for(_iterator0.s();!(_step0=_iterator0.n()).done;){if(_loop2())continue}}catch(err){_iterator0.e(err)}finally{_iterator0.f()}return content};var reverseProxyBufferedRequest=/*#__PURE__*/function(){var _reverseProxyBufferedRequest=_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(request,response,forwarder,stateAPIScope){return _regenerator().w(function(_context2){while(1)switch(_context2.n){case 0:return _context2.a(2,new Promise(function(resolve,reject){var clientSocket=response.socket;var createConnection=forwarder.tls?__WEBPACK_EXTERNAL_MODULE_tls_connect__:__WEBPACK_EXTERNAL_MODULE_net_createConnection__;var portSuffix=forwarder.tls&&forwarder.port!==443||!forwarder.tls&&forwarder.port!==80?":".concat(String(forwarder.port)):"";var serverSocket=createConnection(_objectSpread({host:forwarder.host,port:forwarder.port},forwarder.tls?{servername:forwarder.host,rejectUnauthorized:false}:{}),function(){void log.info("\nConnection to: http".concat(forwarder.tls?"s":"","://")+"".concat(forwarder.host).concat(portSuffix," established."))});serverSocket.on("error",function(error){void log.error("Proxy to server error",error);reject(error)});var parameters=[].concat(_toConsumableArray(external_clientnode_.UTILITY_SCOPE_VALUES),[{clientSocket:clientSocket,serverSocket:serverSocket},null,request,response,null,stateAPIScope]);// Send data from server back to client.
99
- if(forwarder.headerTransformations.retrieve.length){var headerProcessed=false;serverSocket.on("data",function(buffer){if(headerProcessed){clientSocket.write(buffer);return}var content=buffer.toString();void log.info("\n <=== Got response header from backend:\n\n".concat(content));content=transformHeaders(content,forwarder.headerTransformations.retrieve,parameters);void log.info("\n <<<< Send response header to client:\n\n".concat(content));clientSocket.write(content);headerProcessed=true;resolve()})}else serverSocket.pipe(clientSocket);serverSocket.on("connect",function(){var headerProcessed=false;var _iterator1=_createForOfIteratorHelper(request.socket.buffer.data),_step1;try{for(_iterator1.s();!(_step1=_iterator1.n()).done;){var buffer=_step1.value;if(!headerProcessed){var content=buffer.toString();void log.debug("\n ===> Got request header from client:\n\n".concat(content));if(forwarder.tls)// NOTE: TLS support was introduced in version 1.1.
113
+ if(forwarder.headerTransformations.retrieve.length){var headerProcessed=false;serverSocket.on("data",function(buffer){if(headerProcessed){clientSocket.write(buffer);return}var content=buffer.toString();void log.info("\n <=== Got response header from backend:\n\n".concat(content));content=transformHeaders(content,forwarder.headerTransformations.retrieve,parameters);void log.info("\n <<<< Send response header to client:\n\n".concat(content));clientSocket.write(content);headerProcessed=true;resolve()})}else serverSocket.pipe(clientSocket);/*
114
+ NOTE: A closed client connection makes the backend connection
115
+ obsolete. Without header transformations the request is finished
116
+ when the backend connection has been closed.
117
+ */var onClientClose=function onClientClose(){serverSocket.destroy()};clientSocket.once("close",onClientClose);serverSocket.on("close",function(){clientSocket.off("close",onClientClose);resolve()});serverSocket.on("connect",function(){var headerProcessed=false;var _iterator1=_createForOfIteratorHelper(request.socket.buffer.data),_step1;try{for(_iterator1.s();!(_step1=_iterator1.n()).done;){var buffer=_step1.value;if(!headerProcessed){var content=buffer.toString();void log.debug("\n ===> Got request header from client:\n\n".concat(content));if(forwarder.tls)// NOTE: TLS support was introduced in version 1.1.
100
118
  content=content.replace(/HTTP\/1\.0/i,"HTTP/1.1");// Overwrite proxy host with destination one.
101
- content=content.replace(/(($|\n)host: )[^\n]+/i,"$1".concat(forwarder.host).concat(portSuffix));content=transformHeaders(content,forwarder.headerTransformations.send,parameters);void log.debug("\n >>>> Send request header to backend:\n\n".concat(content));serverSocket.write(content);headerProcessed=true;continue}serverSocket.write(buffer)}}catch(err){_iterator1.e(err)}finally{_iterator1.f()}})}))}},_callee2)}));function reverseProxyBufferedRequest(_x4,_x5,_x6,_x7){return _reverseProxyBufferedRequest.apply(this,arguments)}return reverseProxyBufferedRequest}();/* harmony default export */ const helper = (reverseProxyBufferedRequest);
102
- export { EVALUATION_SCOPE_NAMES, addParsedContentToRequest, applyStateAPIs, helper as default, determineForwarder, log, resolveForwarders, reverseProxyBufferedRequest, transformHeaders };
119
+ content=content.replace(/(($|\n)host: )[^\r\n]+/i,"$1".concat(forwarder.host).concat(portSuffix));content=transformHeaders(content,forwarder.headerTransformations.send,parameters);void log.debug("\n >>>> Send request header to backend:\n\n".concat(content));serverSocket.write(content);headerProcessed=true;continue}serverSocket.write(buffer)}}catch(err){_iterator1.e(err)}finally{_iterator1.f()}})}))}},_callee2)}));function reverseProxyBufferedRequest(_x4,_x5,_x6,_x7){return _reverseProxyBufferedRequest.apply(this,arguments)}return reverseProxyBufferedRequest}();// region server
120
+ /**
121
+ * Loads the package configuration extended by "configuration.json" and
122
+ * "secure-configuration.json" files found in given directory and evaluates
123
+ * all dynamic values.
124
+ * @param directoryPath - Directory to search configuration files in.
125
+ * @param baseConfiguration - Configuration to extend.
126
+ * @returns A promise resolving to the evaluated configuration.
127
+ */var loadConfiguration=/*#__PURE__*/function(){var _loadConfiguration=_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(directoryPath,baseConfiguration){var configuration,_iterator10,_step10,path,configurationPath,givenConfiguration,evaluationOptions,_t6,_t7;return _regenerator().w(function(_context3){while(1)switch(_context3.p=_context3.n){case 0:if(directoryPath===void 0){directoryPath=process.cwd()}if(baseConfiguration===void 0){baseConfiguration=package_namespaceObject.HF}configuration=(0,external_clientnode_.copy)(baseConfiguration);_iterator10=_createForOfIteratorHelper(["configuration.json","secure-configuration.json"]);_context3.p=1;_iterator10.s();case 2:if((_step10=_iterator10.n()).done){_context3.n=6;break}path=_step10.value;configurationPath=__WEBPACK_EXTERNAL_MODULE_path_resolve__(directoryPath,path);_context3.n=3;return (0,external_clientnode_.isFile)(configurationPath);case 3:if(!_context3.v){_context3.n=5;break}_t6=JSON;_context3.n=4;return __WEBPACK_EXTERNAL_MODULE_fs_promises_cc1b69f3_readFile__(configurationPath,{encoding:"utf-8"});case 4:givenConfiguration=_t6.parse.call(_t6,_context3.v);(0,external_clientnode_.extend)(true,(0,external_clientnode_.modifyObject)(configuration,givenConfiguration),givenConfiguration);case 5:_context3.n=2;break;case 6:_context3.n=8;break;case 7:_context3.p=7;_t7=_context3.v;_iterator10.e(_t7);case 8:_context3.p=8;_iterator10.f();return _context3.f(8);case 9:evaluationOptions={scope:_objectSpread(_objectSpread({},external_clientnode_.UTILITY_SCOPE),{},{configuration:configuration,environment:process.env})};return _context3.a(2,(0,external_clientnode_.evaluateAsyncDynamicData)((0,external_clientnode_.evaluateDynamicData)(configuration,evaluationOptions),evaluationOptions))}},_callee3,null,[[1,7,8,9]])}));function loadConfiguration(_x8,_x9){return _loadConfiguration.apply(this,arguments)}return loadConfiguration}();/**
128
+ * Waits until given request is fully buffered, determines its forwarder,
129
+ * applies the forwarder's state apis and forwards the request.
130
+ * @param request - Buffered client request.
131
+ * @param response - Response to the client.
132
+ * @param forwarders - Forwarders to choose from.
133
+ * @param parseBody - Indicates whether to parse a json request body.
134
+ * @returns A promise resolving when the request has been processed.
135
+ */var handleRequest=/*#__PURE__*/function(){var _handleRequest=_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(request,response,forwarders,parseBody){var iteration,forwarder,_yield$applyStateAPIs,result,scope,_t8;return _regenerator().w(function(_context4){while(1)switch(_context4.p=_context4.n){case 0:if(parseBody===void 0){parseBody=false}void log.info("|".concat("-".repeat(80-2),"|\nStart processing"),"".concat(request.method," request: ").concat(request.url,"\n")+request);// NOTE: We have to wait until client request is fully buffered.
136
+ iteration=0;case 1:if(!(iteration<external_clientnode_.MAXIMAL_NUMBER_OF_ITERATIONS.value*1000)){_context4.n=4;break}_context4.n=2;return (0,external_clientnode_.timeout)();case 2:if(!request.socket.buffer.finished){_context4.n=3;break}return _context4.a(3,4);case 3:iteration++;_context4.n=1;break;case 4:if(parseBody)addParsedContentToRequest(request);forwarder=determineForwarder(request,response,forwarders);if(!(forwarder===null)){_context4.n=5;break}void log.error("No forwarder found for given request:",request);response.statusCode=502;response.end();return _context4.a(2);case 5:_context4.p=5;_context4.n=6;return applyStateAPIs(request,response,forwarder);case 6:_yield$applyStateAPIs=_context4.v;result=_yield$applyStateAPIs.result;scope=_yield$applyStateAPIs.scope;if(!result){_context4.n=7;break}_context4.n=7;return reverseProxyBufferedRequest(request,response,forwarder,scope);case 7:_context4.n=9;break;case 8:_context4.p=8;_t8=_context4.v;void log.error(_t8);case 9:void log.info("\nEnd processing","".concat(request.method," request: ").concat(request.url,"\n")+"".concat(request,"|").concat("-".repeat(80-2),"|"));case 10:return _context4.a(2)}},_callee4,null,[[5,8]])}));function handleRequest(_x0,_x1,_x10,_x11){return _handleRequest.apply(this,arguments)}return handleRequest}();/**
137
+ * Creates a (not yet listening) server forwarding incoming requests.
138
+ * @param configuration - Server configuration.
139
+ * @param forwarders - Forwarders to use for incoming requests.
140
+ * @returns The created server.
141
+ */var createServer=function createServer(configuration,forwarders){if(forwarders===void 0){forwarders=resolveForwarders(configuration.forwarders)}var onIncomingMessage=function onIncomingMessage(request,response){void handleRequest(request,response,forwarders,configuration.parseBody)};var server={instance:configuration.publicKeyPath&&configuration.privateKeyPath?__WEBPACK_EXTERNAL_MODULE_http2_createSecureServer__(configuration.nodeServerOptions,onIncomingMessage):// NOTE: http2 compatibility mode does not work for
142
+ // unencrypted connections yet.
143
+ __WEBPACK_EXTERNAL_MODULE_http_createServer__(onIncomingMessage),streams:[],sockets:[],start:function start(){return new Promise(function(resolve,reject){server.instance.once("error",reject);server.instance.listen(configuration.port,function(){server.instance.off("error",reject);void log.info("Listen on port ".concat(String(configuration.port)," for ")+"incoming requests.");resolve()})})},stop:function stop(){return new Promise(function(resolve){server.instance.close(function(){void log.info("Shut server down.");resolve()});for(var _i3=0,_arr=[server.sockets,server.streams];_i3<_arr.length;_i3++){var connections=_arr[_i3];for(var _i4=0,_arr2=_toConsumableArray(connections);_i4<_arr2.length;_i4++){var connection=_arr2[_i4];connection.destroy()}}})}};server.instance.on("connection",function(socket){server.sockets.push(socket);socket.buffer={data:[],finished:false};socket.on("data",function(data){socket.buffer.data.push(data)});for(var _i5=0,_arr3=["done","finish","writableEnded","writableFinished"];_i5<_arr3.length;_i5++){var name=_arr3[_i5];socket.on(name,function(){socket.buffer.finished=true})}/*
144
+ NOTE: Workaround since none of the events above trigger before
145
+ responding to client occurred.
146
+ */void (0,external_clientnode_.timeout)(function(){socket.buffer.finished=true});socket.on("close",function(){socket.buffer.finished=true;server.sockets.splice(server.sockets.indexOf(socket),1)})});server.instance.on("stream",function(stream,headers){server.streams.push(stream);void log.info("Got stream",stream,headers);stream.on("close",function(){server.streams.splice(server.streams.indexOf(stream),1)})});return server};// endregion
147
+ /* harmony default export */ const helper = (reverseProxyBufferedRequest);
148
+ export { EVALUATION_SCOPE_NAMES, addParsedContentToRequest, applyStateAPIs, createServer, helper as default, determineForwarder, handleRequest, loadConfiguration, log, resolveForwarders, reverseProxyBufferedRequest, transformHeaders };
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  // -*- coding: utf-8 -*-
3
3
 
4
+ import { readFile as __WEBPACK_EXTERNAL_MODULE_fs_promises_cc1b69f3_readFile__ } from "fs/promises";
5
+ import { createServer as __WEBPACK_EXTERNAL_MODULE_http_createServer__ } from "http";
6
+ import { createSecureServer as __WEBPACK_EXTERNAL_MODULE_http2_createSecureServer__ } from "http2";
4
7
  import { createConnection as __WEBPACK_EXTERNAL_MODULE_net_createConnection__ } from "net";
8
+ import { resolve as __WEBPACK_EXTERNAL_MODULE_path_resolve__ } from "path";
5
9
  import { connect as __WEBPACK_EXTERNAL_MODULE_tls_connect__ } from "tls";
6
10
  import * as __WEBPACK_EXTERNAL_MODULE_clientnode__ from "clientnode";
7
- import * as __WEBPACK_EXTERNAL_MODULE_fs_promises_cc1b69f3__ from "fs/promises";
8
- import * as __WEBPACK_EXTERNAL_MODULE_http__ from "http";
9
- import * as __WEBPACK_EXTERNAL_MODULE_http2__ from "http2";
10
- import * as __WEBPACK_EXTERNAL_MODULE_path__ from "path";
11
11
  /******/ var __webpack_modules__ = ([
12
12
  /* 0 */
13
13
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
@@ -15,22 +15,30 @@ import * as __WEBPACK_EXTERNAL_MODULE_path__ from "path";
15
15
 
16
16
  // EXPORTS
17
17
  __webpack_require__.d(__webpack_exports__, {
18
- Ko: () => (/* binding */ addParsedContentToRequest),
19
- BE: () => (/* binding */ applyStateAPIs),
20
- Ay: () => (/* binding */ helper),
21
- cP: () => (/* binding */ determineForwarder),
18
+ sA: () => (/* binding */ createServer),
19
+ vF: () => (/* binding */ loadConfiguration),
22
20
  Rm: () => (/* binding */ log),
23
21
  cx: () => (/* binding */ resolveForwarders)
24
22
  });
25
23
 
26
- // UNUSED EXPORTS: EVALUATION_SCOPE_NAMES, reverseProxyBufferedRequest, transformHeaders
24
+ // UNUSED EXPORTS: EVALUATION_SCOPE_NAMES, addParsedContentToRequest, applyStateAPIs, default, determineForwarder, handleRequest, reverseProxyBufferedRequest, transformHeaders
27
25
 
28
26
  // EXTERNAL MODULE: external "clientnode"
29
27
  var external_clientnode_ = __webpack_require__(1);
28
+ ;// external "fs/promises"
29
+
30
+ ;// external "http"
31
+
32
+ ;// external "http2"
33
+
30
34
  ;// external "net"
31
35
 
36
+ ;// external "path"
37
+
32
38
  ;// external "tls"
33
39
 
40
+ ;// ./package.json
41
+ const package_namespaceObject = /*#__PURE__*/JSON.parse('{"HF":{"forwarders":{"base":{"headerTransformations":{"retrieve":[],"send":[]},"host":"localhost","port":443,"stateAPIs":[{"data":{},"expressions":{"post":"true","pre":"false"},"name":"base","options":{},"url":""}],"tls":true,"useExpression":"true"}},"host":"localhost","nodeServerOptions":{"allowHTTP1":true},"parseBody":false,"port":8080,"privateKeyPath":"","publicKeyPath":""}}');
34
42
  ;// ./src/helper.ts
35
43
  // #!/usr/bin/env babel-node
36
44
  // -*- coding: utf-8 -*-
@@ -66,9 +74,41 @@ var addParsedContentToRequest=function addParsedContentToRequest(bufferedRequest
66
74
  // Add new header.
67
75
  content=content.replace(/(\s*\n)\s*\n\s*/,function(substring,delimiter){for(var _len=arguments.length,parameters=new Array(_len>2?_len-2:0),_key=2;_key<_len;_key++){parameters[_key-2]=arguments[_key]}var result=typeof target==="string"?target:target?target.apply(void 0,[substring,delimiter].concat(parameters)):"";return"".concat(delimiter).concat(result).concat(substring)})}else{if(!newLinePrinted){void log.debug();newLinePrinted=true}// Search and replace (or remove) header.
68
76
  void log.debug("Search for \"".concat(source,"\" and replace with"),"".concat((0,external_clientnode_.represent)(target),"."));if(source)content=content.replace(source,target)}}catch(error){void log.warn("\nCould not apply header transformation with source "+(transformation.source?(0,external_clientnode_.represent)(transformation.source):"\"add\"")+" and replacement "+(transformation.target?(0,external_clientnode_.represent)(transformation.target):"\"remove\"")+":",error)}};for(_iterator0.s();!(_step0=_iterator0.n()).done;){if(_loop2())continue}}catch(err){_iterator0.e(err)}finally{_iterator0.f()}return content};var reverseProxyBufferedRequest=/*#__PURE__*/function(){var _reverseProxyBufferedRequest=_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(request,response,forwarder,stateAPIScope){return _regenerator().w(function(_context2){while(1)switch(_context2.n){case 0:return _context2.a(2,new Promise(function(resolve,reject){var clientSocket=response.socket;var createConnection=forwarder.tls?__WEBPACK_EXTERNAL_MODULE_tls_connect__:__WEBPACK_EXTERNAL_MODULE_net_createConnection__;var portSuffix=forwarder.tls&&forwarder.port!==443||!forwarder.tls&&forwarder.port!==80?":".concat(String(forwarder.port)):"";var serverSocket=createConnection(_objectSpread({host:forwarder.host,port:forwarder.port},forwarder.tls?{servername:forwarder.host,rejectUnauthorized:false}:{}),function(){void log.info("\nConnection to: http".concat(forwarder.tls?"s":"","://")+"".concat(forwarder.host).concat(portSuffix," established."))});serverSocket.on("error",function(error){void log.error("Proxy to server error",error);reject(error)});var parameters=[].concat(_toConsumableArray(external_clientnode_.UTILITY_SCOPE_VALUES),[{clientSocket:clientSocket,serverSocket:serverSocket},null,request,response,null,stateAPIScope]);// Send data from server back to client.
69
- if(forwarder.headerTransformations.retrieve.length){var headerProcessed=false;serverSocket.on("data",function(buffer){if(headerProcessed){clientSocket.write(buffer);return}var content=buffer.toString();void log.info("\n <=== Got response header from backend:\n\n".concat(content));content=transformHeaders(content,forwarder.headerTransformations.retrieve,parameters);void log.info("\n <<<< Send response header to client:\n\n".concat(content));clientSocket.write(content);headerProcessed=true;resolve()})}else serverSocket.pipe(clientSocket);serverSocket.on("connect",function(){var headerProcessed=false;var _iterator1=_createForOfIteratorHelper(request.socket.buffer.data),_step1;try{for(_iterator1.s();!(_step1=_iterator1.n()).done;){var buffer=_step1.value;if(!headerProcessed){var content=buffer.toString();void log.debug("\n ===> Got request header from client:\n\n".concat(content));if(forwarder.tls)// NOTE: TLS support was introduced in version 1.1.
77
+ if(forwarder.headerTransformations.retrieve.length){var headerProcessed=false;serverSocket.on("data",function(buffer){if(headerProcessed){clientSocket.write(buffer);return}var content=buffer.toString();void log.info("\n <=== Got response header from backend:\n\n".concat(content));content=transformHeaders(content,forwarder.headerTransformations.retrieve,parameters);void log.info("\n <<<< Send response header to client:\n\n".concat(content));clientSocket.write(content);headerProcessed=true;resolve()})}else serverSocket.pipe(clientSocket);/*
78
+ NOTE: A closed client connection makes the backend connection
79
+ obsolete. Without header transformations the request is finished
80
+ when the backend connection has been closed.
81
+ */var onClientClose=function onClientClose(){serverSocket.destroy()};clientSocket.once("close",onClientClose);serverSocket.on("close",function(){clientSocket.off("close",onClientClose);resolve()});serverSocket.on("connect",function(){var headerProcessed=false;var _iterator1=_createForOfIteratorHelper(request.socket.buffer.data),_step1;try{for(_iterator1.s();!(_step1=_iterator1.n()).done;){var buffer=_step1.value;if(!headerProcessed){var content=buffer.toString();void log.debug("\n ===> Got request header from client:\n\n".concat(content));if(forwarder.tls)// NOTE: TLS support was introduced in version 1.1.
70
82
  content=content.replace(/HTTP\/1\.0/i,"HTTP/1.1");// Overwrite proxy host with destination one.
71
- content=content.replace(/(($|\n)host: )[^\n]+/i,"$1".concat(forwarder.host).concat(portSuffix));content=transformHeaders(content,forwarder.headerTransformations.send,parameters);void log.debug("\n >>>> Send request header to backend:\n\n".concat(content));serverSocket.write(content);headerProcessed=true;continue}serverSocket.write(buffer)}}catch(err){_iterator1.e(err)}finally{_iterator1.f()}})}))}},_callee2)}));function reverseProxyBufferedRequest(_x4,_x5,_x6,_x7){return _reverseProxyBufferedRequest.apply(this,arguments)}return reverseProxyBufferedRequest}();/* harmony default export */ const helper = (reverseProxyBufferedRequest);
83
+ content=content.replace(/(($|\n)host: )[^\r\n]+/i,"$1".concat(forwarder.host).concat(portSuffix));content=transformHeaders(content,forwarder.headerTransformations.send,parameters);void log.debug("\n >>>> Send request header to backend:\n\n".concat(content));serverSocket.write(content);headerProcessed=true;continue}serverSocket.write(buffer)}}catch(err){_iterator1.e(err)}finally{_iterator1.f()}})}))}},_callee2)}));function reverseProxyBufferedRequest(_x4,_x5,_x6,_x7){return _reverseProxyBufferedRequest.apply(this,arguments)}return reverseProxyBufferedRequest}();// region server
84
+ /**
85
+ * Loads the package configuration extended by "configuration.json" and
86
+ * "secure-configuration.json" files found in given directory and evaluates
87
+ * all dynamic values.
88
+ * @param directoryPath - Directory to search configuration files in.
89
+ * @param baseConfiguration - Configuration to extend.
90
+ * @returns A promise resolving to the evaluated configuration.
91
+ */var loadConfiguration=/*#__PURE__*/function(){var _loadConfiguration=_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(directoryPath,baseConfiguration){var configuration,_iterator10,_step10,path,configurationPath,givenConfiguration,evaluationOptions,_t6,_t7;return _regenerator().w(function(_context3){while(1)switch(_context3.p=_context3.n){case 0:if(directoryPath===void 0){directoryPath=process.cwd()}if(baseConfiguration===void 0){baseConfiguration=package_namespaceObject.HF}configuration=(0,external_clientnode_.copy)(baseConfiguration);_iterator10=_createForOfIteratorHelper(["configuration.json","secure-configuration.json"]);_context3.p=1;_iterator10.s();case 2:if((_step10=_iterator10.n()).done){_context3.n=6;break}path=_step10.value;configurationPath=__WEBPACK_EXTERNAL_MODULE_path_resolve__(directoryPath,path);_context3.n=3;return (0,external_clientnode_.isFile)(configurationPath);case 3:if(!_context3.v){_context3.n=5;break}_t6=JSON;_context3.n=4;return __WEBPACK_EXTERNAL_MODULE_fs_promises_cc1b69f3_readFile__(configurationPath,{encoding:"utf-8"});case 4:givenConfiguration=_t6.parse.call(_t6,_context3.v);(0,external_clientnode_.extend)(true,(0,external_clientnode_.modifyObject)(configuration,givenConfiguration),givenConfiguration);case 5:_context3.n=2;break;case 6:_context3.n=8;break;case 7:_context3.p=7;_t7=_context3.v;_iterator10.e(_t7);case 8:_context3.p=8;_iterator10.f();return _context3.f(8);case 9:evaluationOptions={scope:_objectSpread(_objectSpread({},external_clientnode_.UTILITY_SCOPE),{},{configuration:configuration,environment:process.env})};return _context3.a(2,(0,external_clientnode_.evaluateAsyncDynamicData)((0,external_clientnode_.evaluateDynamicData)(configuration,evaluationOptions),evaluationOptions))}},_callee3,null,[[1,7,8,9]])}));function loadConfiguration(_x8,_x9){return _loadConfiguration.apply(this,arguments)}return loadConfiguration}();/**
92
+ * Waits until given request is fully buffered, determines its forwarder,
93
+ * applies the forwarder's state apis and forwards the request.
94
+ * @param request - Buffered client request.
95
+ * @param response - Response to the client.
96
+ * @param forwarders - Forwarders to choose from.
97
+ * @param parseBody - Indicates whether to parse a json request body.
98
+ * @returns A promise resolving when the request has been processed.
99
+ */var handleRequest=/*#__PURE__*/function(){var _handleRequest=_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(request,response,forwarders,parseBody){var iteration,forwarder,_yield$applyStateAPIs,result,scope,_t8;return _regenerator().w(function(_context4){while(1)switch(_context4.p=_context4.n){case 0:if(parseBody===void 0){parseBody=false}void log.info("|".concat("-".repeat(80-2),"|\nStart processing"),"".concat(request.method," request: ").concat(request.url,"\n")+request);// NOTE: We have to wait until client request is fully buffered.
100
+ iteration=0;case 1:if(!(iteration<external_clientnode_.MAXIMAL_NUMBER_OF_ITERATIONS.value*1000)){_context4.n=4;break}_context4.n=2;return (0,external_clientnode_.timeout)();case 2:if(!request.socket.buffer.finished){_context4.n=3;break}return _context4.a(3,4);case 3:iteration++;_context4.n=1;break;case 4:if(parseBody)addParsedContentToRequest(request);forwarder=determineForwarder(request,response,forwarders);if(!(forwarder===null)){_context4.n=5;break}void log.error("No forwarder found for given request:",request);response.statusCode=502;response.end();return _context4.a(2);case 5:_context4.p=5;_context4.n=6;return applyStateAPIs(request,response,forwarder);case 6:_yield$applyStateAPIs=_context4.v;result=_yield$applyStateAPIs.result;scope=_yield$applyStateAPIs.scope;if(!result){_context4.n=7;break}_context4.n=7;return reverseProxyBufferedRequest(request,response,forwarder,scope);case 7:_context4.n=9;break;case 8:_context4.p=8;_t8=_context4.v;void log.error(_t8);case 9:void log.info("\nEnd processing","".concat(request.method," request: ").concat(request.url,"\n")+"".concat(request,"|").concat("-".repeat(80-2),"|"));case 10:return _context4.a(2)}},_callee4,null,[[5,8]])}));function handleRequest(_x0,_x1,_x10,_x11){return _handleRequest.apply(this,arguments)}return handleRequest}();/**
101
+ * Creates a (not yet listening) server forwarding incoming requests.
102
+ * @param configuration - Server configuration.
103
+ * @param forwarders - Forwarders to use for incoming requests.
104
+ * @returns The created server.
105
+ */var createServer=function createServer(configuration,forwarders){if(forwarders===void 0){forwarders=resolveForwarders(configuration.forwarders)}var onIncomingMessage=function onIncomingMessage(request,response){void handleRequest(request,response,forwarders,configuration.parseBody)};var server={instance:configuration.publicKeyPath&&configuration.privateKeyPath?__WEBPACK_EXTERNAL_MODULE_http2_createSecureServer__(configuration.nodeServerOptions,onIncomingMessage):// NOTE: http2 compatibility mode does not work for
106
+ // unencrypted connections yet.
107
+ __WEBPACK_EXTERNAL_MODULE_http_createServer__(onIncomingMessage),streams:[],sockets:[],start:function start(){return new Promise(function(resolve,reject){server.instance.once("error",reject);server.instance.listen(configuration.port,function(){server.instance.off("error",reject);void log.info("Listen on port ".concat(String(configuration.port)," for ")+"incoming requests.");resolve()})})},stop:function stop(){return new Promise(function(resolve){server.instance.close(function(){void log.info("Shut server down.");resolve()});for(var _i3=0,_arr=[server.sockets,server.streams];_i3<_arr.length;_i3++){var connections=_arr[_i3];for(var _i4=0,_arr2=_toConsumableArray(connections);_i4<_arr2.length;_i4++){var connection=_arr2[_i4];connection.destroy()}}})}};server.instance.on("connection",function(socket){server.sockets.push(socket);socket.buffer={data:[],finished:false};socket.on("data",function(data){socket.buffer.data.push(data)});for(var _i5=0,_arr3=["done","finish","writableEnded","writableFinished"];_i5<_arr3.length;_i5++){var name=_arr3[_i5];socket.on(name,function(){socket.buffer.finished=true})}/*
108
+ NOTE: Workaround since none of the events above trigger before
109
+ responding to client occurred.
110
+ */void (0,external_clientnode_.timeout)(function(){socket.buffer.finished=true});socket.on("close",function(){socket.buffer.finished=true;server.sockets.splice(server.sockets.indexOf(socket),1)})});server.instance.on("stream",function(stream,headers){server.streams.push(stream);void log.info("Got stream",stream,headers);stream.on("close",function(){server.streams.splice(server.streams.indexOf(stream),1)})});return server};// endregion
111
+ /* harmony default export */ const helper = ((/* unused pure expression or super */ null && (reverseProxyBufferedRequest)));
72
112
 
73
113
  /***/ }),
74
114
  /* 1 */
@@ -86,12 +126,7 @@ module.exports = x({ ["CLOSE_EVENT_NAMES"]: () => (__WEBPACK_EXTERNAL_MODULE_cli
86
126
 
87
127
  __webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
88
128
  /* harmony import */ var clientnode__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
89
- /* harmony import */ var fs_promises__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
90
- /* harmony import */ var http__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
91
- /* harmony import */ var http2__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
92
- /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6);
93
- /* harmony import */ var _helper_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(0);
94
- /* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7);
129
+ /* harmony import */ var _helper_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
95
130
  // #!/usr/bin/env babel-node
96
131
  // -*- coding: utf-8 -*-
97
132
  /** @module web-node *//* !
@@ -108,21 +143,9 @@ __webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __we
108
143
  See https://creativecommons.org/licenses/by/3.0/deed.de
109
144
  endregion
110
145
  */// region imports
111
- function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,o)}return t}function _objectSpread(r){for(var t=1;t<arguments.length;t++){var o=null!=arguments[t]?arguments[t]:{};t%2?ownKeys(Object(o),!0).forEach(function(t){_defineProperty(r,t,o[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(o)):ownKeys(Object(o)).forEach(function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(o,e))})}return r}function _defineProperty(r,t,o){return(t=_toPropertyKey(t))in r?Object.defineProperty(r,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):r[t]=o,r}function _toPropertyKey(r){var o=_toPrimitive(r,"string");return"symbol"==_typeof(o)?o:o+""}function _toPrimitive(t,e){if("object"!=_typeof(t)||!t)return t;var r;if("undefined"!=typeof Symbol&&void 0!==(r=t[Symbol.toPrimitive])){var i=r.call(t,e||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}function _createForOfIteratorHelper(e,t){var _n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!_n){if(Array.isArray(e)||(_n=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length){_n&&(e=_n);var o=0,F=function F(){};return{s:F,n:function n(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function e(r){throw r},f:F}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u,i=!0;return{s:function s(){_n=_n.call(e)},n:function n(){i=!0;var r=_n.next();return r.done?{done:!0}:{value:r.value,done:i=!1}},e:function e(r){a=!0,u=r},f:function f(){try{i||null==_n.return||_n.return()}finally{if(a)throw u}}}}function _unsupportedIterableToArray(t,e){if(t){if("string"==typeof t)return _arrayLikeToArray(t,e);var o={}.toString.call(t).slice(8,-1);return"Object"===o&&t.constructor&&(o=t.constructor.name),"Map"===o||"Set"===o?Array.from(t):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?_arrayLikeToArray(t,e):void 0}}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var r,e,o="function"==typeof Symbol?Symbol:{},n=o.iterator||"@@iterator",a=o.toStringTag||"@@toStringTag";function i(o,n,a,i){var u=n&&n.prototype instanceof Generator?n:Generator,f=Object.create(u.prototype);return _regeneratorDefine2(f,"_invoke",function(t,o,n){var a,i,u,f=0,p=n||[],y=!1,G={p:0,n:0,v:r,a:l,f:l.bind(r,4),d:function d(t,e){return a=t,i=0,u=r,G.n=e,c}};function l(t,o){for(i=t,u=o,e=0;!y&&f&&!n&&e<p.length;e++){var n,a=p[e],l=G.p,F=a[2];t>3?(n=F===o)&&(u=a[(i=a[4])?5:(i=3,3)],a[4]=a[5]=r):a[0]<=l&&((n=t<2&&l<a[1])?(i=0,G.v=o,G.n=a[1]):l<F&&(n=t<3||a[0]>o||o>F)&&(a[4]=t,a[5]=o,G.n=F,i=0))}if(n||t>1)return c;throw y=!0,o}return function(n,p,F){if(f>1)throw TypeError("Generator is already running");for(y&&1===p&&l(p,F),i=p,u=F;(e=i<2?r:u)||!y;){a||(i?i<3?(i>1&&(G.n=-1),l(i,u)):G.n=u:G.v=u);try{if(f=2,a){if(i||(n="next"),e=a[n]){if(!(e=e.call(a,u)))throw TypeError("iterator result is not an object");if(!e.done)return e;u=e.value,i<2&&(i=0)}else 1===i&&(e=a.return)&&e.call(a),i<2&&(u=TypeError("The iterator does not provide a '"+n+"' method"),i=1);a=r}else if((e=(y=G.n<0)?u:t.call(o,G))!==c)break}catch(t){a=r,i=1,u=t}finally{f=1}}return{value:e,done:y}}}(o,a,i),!0),f}var c={};function Generator(){}function GeneratorFunction(){}function GeneratorFunctionPrototype(){}e=Object.getPrototypeOf;var u=[][n]?e(e([][n]())):(_regeneratorDefine2(e={},n,function(){return this}),e),f=GeneratorFunctionPrototype.prototype=Generator.prototype=Object.create(u);function p(r){return Object.setPrototypeOf?Object.setPrototypeOf(r,GeneratorFunctionPrototype):(r.__proto__=GeneratorFunctionPrototype,_regeneratorDefine2(r,a,"GeneratorFunction")),r.prototype=Object.create(f),r}return GeneratorFunction.prototype=GeneratorFunctionPrototype,_regeneratorDefine2(f,"constructor",GeneratorFunctionPrototype),_regeneratorDefine2(GeneratorFunctionPrototype,"constructor",GeneratorFunction),GeneratorFunction.displayName="GeneratorFunction",_regeneratorDefine2(GeneratorFunctionPrototype,a,"GeneratorFunction"),_regeneratorDefine2(f),_regeneratorDefine2(f,a,"Generator"),_regeneratorDefine2(f,n,function(){return this}),_regeneratorDefine2(f,"toString",function(){return"[object Generator]"}),(_regenerator=function _regenerator(){return{w:i,m:p}})()}function _regeneratorDefine2(e,r,n,t){var i=Object.defineProperty;try{i({},"",{})}catch(e){i=0}_regeneratorDefine2=function _regeneratorDefine(e,r,n,t){function o(r,n){_regeneratorDefine2(e,r,function(e){return this._invoke(r,n,e)})}r?i?i(e,r,{value:n,enumerable:!t,configurable:!t,writable:!t}):e[r]=n:(o("next",0),o("throw",1),o("return",2))},_regeneratorDefine2(e,r,n,t)}function asyncGeneratorStep(n,t,e,r,o,a,c){try{var i=n[a](c),u=i.value}catch(n){return void e(n)}i.done?t(u):Promise.resolve(u).then(r,o)}function _asyncToGenerator(n){return function(){var t=this,e=arguments;return new Promise(function(r,o){var a=n.apply(t,e);function _next(n){asyncGeneratorStep(a,r,o,_next,_throw,"next",n)}function _throw(n){asyncGeneratorStep(a,r,o,_next,_throw,"throw",n)}_next(void 0)})}}// NOTE: http2 compatibility mode does work for unencrypted connections yet.
112
- ;// endregion
113
- await (0,clientnode__WEBPACK_IMPORTED_MODULE_0__.importFilesystemAPI)();// region live cycle methods
114
- var onIncomingMessage=function onIncomingMessage(request,response){var bufferedRequest=request;void _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(){var iteration,forwarder,_yield$applyStateAPIs,result,scope,_t;return _regenerator().w(function(_context){while(1)switch(_context.p=_context.n){case 0:void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.info("|".concat("-".repeat(80-2),"|\nStart processing"),"".concat(bufferedRequest.method," request: ").concat(bufferedRequest.url,"\n")+bufferedRequest);// NOTE: We have to wait until client request is fully buffered.
115
- iteration=0;case 1:if(!(iteration<clientnode__WEBPACK_IMPORTED_MODULE_0__.MAXIMAL_NUMBER_OF_ITERATIONS.value*1000)){_context.n=4;break}_context.n=2;return (0,clientnode__WEBPACK_IMPORTED_MODULE_0__.timeout)();case 2:if(!bufferedRequest.socket.buffer.finished){_context.n=3;break}return _context.a(3,4);case 3:iteration++;_context.n=1;break;case 4:if(CONFIGURATION.parseBody)(0,_helper_js__WEBPACK_IMPORTED_MODULE_5__/* .addParsedContentToRequest */ .Ko)(bufferedRequest);forwarder=(0,_helper_js__WEBPACK_IMPORTED_MODULE_5__/* .determineForwarder */ .cP)(bufferedRequest,response,FORWARDERS);if(!(forwarder===null)){_context.n=5;break}void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.error("No forwarder found for given request:",bufferedRequest);response.statusCode=502;response.end();return _context.a(2);case 5:_context.p=5;_context.n=6;return (0,_helper_js__WEBPACK_IMPORTED_MODULE_5__/* .applyStateAPIs */ .BE)(bufferedRequest,response,forwarder);case 6:_yield$applyStateAPIs=_context.v;result=_yield$applyStateAPIs.result;scope=_yield$applyStateAPIs.scope;if(!result){_context.n=7;break}_context.n=7;return (0,_helper_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Ay)(bufferedRequest,response,forwarder,scope);case 7:_context.n=9;break;case 8:_context.p=8;_t=_context.v;void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.error(_t);case 9:void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.info("\nEnd processing","".concat(bufferedRequest.method," request: ").concat(bufferedRequest.url,"\n")+"".concat(bufferedRequest,"|").concat("-".repeat(80-2),"|"));case 10:return _context.a(2)}},_callee,null,[[5,8]])}))()};var onIncomingStream=function onIncomingStream(stream,headers){void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.info("Got stream",stream,headers)};// endregion
116
- // region configuration
117
- var BASE_CONFIGURATION=_package_json__WEBPACK_IMPORTED_MODULE_6__/* .configuration */ .HF;var _iterator=_createForOfIteratorHelper(["configuration.json","secure-configuration.json"]),_step;try{for(_iterator.s();!(_step=_iterator.n()).done;){var path=_step.value;var configurationPath=(0,path__WEBPACK_IMPORTED_MODULE_4__.resolve)(process.cwd(),path);if(await (0,clientnode__WEBPACK_IMPORTED_MODULE_0__.isFile)(configurationPath)){var configuration=JSON.parse(await (0,fs_promises__WEBPACK_IMPORTED_MODULE_1__.readFile)(configurationPath,{encoding:"utf-8"}));(0,clientnode__WEBPACK_IMPORTED_MODULE_0__.extend)(true,(0,clientnode__WEBPACK_IMPORTED_MODULE_0__.modifyObject)(BASE_CONFIGURATION,configuration),configuration)}}}catch(err){_iterator.e(err)}finally{_iterator.f()}var evaluationOptions={scope:_objectSpread(_objectSpread({},clientnode__WEBPACK_IMPORTED_MODULE_0__.UTILITY_SCOPE),{},{configuration:BASE_CONFIGURATION,environment:process.env})};var CONFIGURATION=await (0,clientnode__WEBPACK_IMPORTED_MODULE_0__.evaluateAsyncDynamicData)((0,clientnode__WEBPACK_IMPORTED_MODULE_0__.evaluateDynamicData)(BASE_CONFIGURATION,evaluationOptions),evaluationOptions);var FORWARDERS=(0,_helper_js__WEBPACK_IMPORTED_MODULE_5__/* .resolveForwarders */ .cx)(CONFIGURATION.forwarders);// endregion
118
- // region initialize server
119
- var server={instance:CONFIGURATION.publicKeyPath&&CONFIGURATION.privateKeyPath?(0,http2__WEBPACK_IMPORTED_MODULE_3__.createSecureServer)(CONFIGURATION.nodeServerOptions,onIncomingMessage):// NOTE: See import notice.
120
- (0,http__WEBPACK_IMPORTED_MODULE_2__.createServer)(onIncomingMessage),streams:[],sockets:[],start:function start(){server.instance.listen(CONFIGURATION.port,function(){void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.info("Listen on port ".concat(String(CONFIGURATION.port)," for ")+"incoming requests.")})},stop:function stop(){server.instance.close(function(){void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.info("Shut server down.")});for(var _i=0,_arr=[server.sockets,server.streams];_i<_arr.length;_i++){var connections=_arr[_i];if(Array.isArray(connections)){var _iterator2=_createForOfIteratorHelper(connections),_step2;try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){var connection=_step2.value;connection.destroy()}}catch(err){_iterator2.e(err)}finally{_iterator2.f()}}}}};server.instance.on("connection",function(socket){server.sockets.push(socket);socket.buffer={data:[],finished:false};socket.on("data",function(data){socket.buffer.data.push(data)});for(var _i2=0,_arr2=["done","finish","writableEnded","writableFinished"];_i2<_arr2.length;_i2++){var name=_arr2[_i2];socket.on(name,function(){socket.buffer.finished=true})}/*
121
- NOTE: Workaround since none of the events above trigger before
122
- responding to client occurred.
123
- */void (0,clientnode__WEBPACK_IMPORTED_MODULE_0__.timeout)(function(){socket.buffer.finished=true});socket.on("close",function(){socket.buffer.finished=true;server.sockets.splice(server.sockets.indexOf(socket),1)})});server.instance.on("stream",function(stream,headers){server.streams.push(stream);onIncomingStream(stream,headers);stream.on("close",function(){server.streams.splice(server.streams.indexOf(stream),1)})});// endregion
124
- // region start / stop
125
- if(import.meta.main){void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.info("Start server with configuration:",(0,clientnode__WEBPACK_IMPORTED_MODULE_0__.represent)(CONFIGURATION));void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.debug("Apply resolved forwarder:",(0,clientnode__WEBPACK_IMPORTED_MODULE_0__.represent)(FORWARDERS));server.start();var _iterator3=_createForOfIteratorHelper(clientnode__WEBPACK_IMPORTED_MODULE_0__.CLOSE_EVENT_NAMES),_step3;try{var _loop=function _loop(){var name=_step3.value;process.on(name,function(){void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.info("\nGot \"".concat(name,"\" signal: stopping server."));server.stop()})};for(_iterator3.s();!(_step3=_iterator3.n()).done;){_loop()}}catch(err){_iterator3.e(err)}finally{_iterator3.f()}}// endregion
146
+ function _createForOfIteratorHelper(e,t){var _n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!_n){if(Array.isArray(e)||(_n=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length){_n&&(e=_n);var o=0,F=function F(){};return{s:F,n:function n(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function e(r){throw r},f:F}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u,i=!0;return{s:function s(){_n=_n.call(e)},n:function n(){i=!0;var r=_n.next();return r.done?{done:!0}:{value:r.value,done:i=!1}},e:function e(r){a=!0,u=r},f:function f(){try{i||null==_n.return||_n.return()}finally{if(a)throw u}}}}function _unsupportedIterableToArray(t,e){if(t){if("string"==typeof t)return _arrayLikeToArray(t,e);var o={}.toString.call(t).slice(8,-1);return"Object"===o&&t.constructor&&(o=t.constructor.name),"Map"===o||"Set"===o?Array.from(t):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?_arrayLikeToArray(t,e):void 0}}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n};// endregion
147
+ await (0,clientnode__WEBPACK_IMPORTED_MODULE_0__.importFilesystemAPI)();var CONFIGURATION=await (0,_helper_js__WEBPACK_IMPORTED_MODULE_1__/* .loadConfiguration */ .vF)();var FORWARDERS=(0,_helper_js__WEBPACK_IMPORTED_MODULE_1__/* .resolveForwarders */ .cx)(CONFIGURATION.forwarders);var server=(0,_helper_js__WEBPACK_IMPORTED_MODULE_1__/* .createServer */ .sA)(CONFIGURATION,FORWARDERS);// region start / stop
148
+ if(import.meta.main){void _helper_js__WEBPACK_IMPORTED_MODULE_1__/* .log */ .Rm.info("Start server with configuration:",(0,clientnode__WEBPACK_IMPORTED_MODULE_0__.represent)(CONFIGURATION));void _helper_js__WEBPACK_IMPORTED_MODULE_1__/* .log */ .Rm.debug("Apply resolved forwarder:",(0,clientnode__WEBPACK_IMPORTED_MODULE_0__.represent)(FORWARDERS));void server.start();var _iterator=_createForOfIteratorHelper(clientnode__WEBPACK_IMPORTED_MODULE_0__.CLOSE_EVENT_NAMES),_step;try{var _loop=function _loop(){var name=_step.value;process.on(name,function(){void _helper_js__WEBPACK_IMPORTED_MODULE_1__/* .log */ .Rm.info("\nGot \"".concat(name,"\" signal: stopping server."));void server.stop()})};for(_iterator.s();!(_step=_iterator.n()).done;){_loop()}}catch(err){_iterator.e(err)}finally{_iterator.f()}}// endregion
126
149
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (server);
127
150
  /* harmony export */ __webpack_require__.d(__webpack_exports__, [
128
151
  /* harmony export */ "A", 0, __WEBPACK_DEFAULT_EXPORT__
@@ -131,52 +154,6 @@ if(import.meta.main){void _helper_js__WEBPACK_IMPORTED_MODULE_5__/* .log */ .Rm.
131
154
  __webpack_async_result__();
132
155
  } catch(e) { __webpack_async_result__(e); } }, 1);
133
156
 
134
- /***/ }),
135
- /* 3 */
136
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
137
-
138
- const x = (y) => {
139
- const x = {}; __webpack_require__.d(x, y); return x
140
- }
141
- const y = (x) => (() => (x))
142
- module.exports = x({ ["readFile"]: () => (__WEBPACK_EXTERNAL_MODULE_fs_promises_cc1b69f3__.readFile) });
143
-
144
- /***/ }),
145
- /* 4 */
146
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
147
-
148
- const x = (y) => {
149
- const x = {}; __webpack_require__.d(x, y); return x
150
- }
151
- const y = (x) => (() => (x))
152
- module.exports = x({ ["createServer"]: () => (__WEBPACK_EXTERNAL_MODULE_http__.createServer) });
153
-
154
- /***/ }),
155
- /* 5 */
156
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
157
-
158
- const x = (y) => {
159
- const x = {}; __webpack_require__.d(x, y); return x
160
- }
161
- const y = (x) => (() => (x))
162
- module.exports = x({ ["createSecureServer"]: () => (__WEBPACK_EXTERNAL_MODULE_http2__.createSecureServer) });
163
-
164
- /***/ }),
165
- /* 6 */
166
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
167
-
168
- const x = (y) => {
169
- const x = {}; __webpack_require__.d(x, y); return x
170
- }
171
- const y = (x) => (() => (x))
172
- module.exports = x({ ["resolve"]: () => (__WEBPACK_EXTERNAL_MODULE_path__.resolve) });
173
-
174
- /***/ }),
175
- /* 7 */
176
- /***/ ((module) => {
177
-
178
- module.exports = /*#__PURE__*/JSON.parse('{"HF":{"forwarders":{"base":{"headerTransformations":{"retrieve":[],"send":[]},"host":"localhost","port":443,"stateAPIs":[{"data":{},"expressions":{"post":"true","pre":"false"},"name":"base","options":{},"url":""}],"tls":true,"useExpression":"true"}},"host":"localhost","nodeServerOptions":{"allowHTTP1":true},"parseBody":false,"port":8080,"privateKeyPath":"","publicKeyPath":""}}');
179
-
180
157
  /***/ })
181
158
  /******/ ]);
182
159
  /************************************************************************/
package/dist/type.d.ts CHANGED
@@ -121,6 +121,6 @@ export interface Server {
121
121
  instance: HTTPServer;
122
122
  streams: Array<HTTPStream>;
123
123
  sockets: Array<Socket>;
124
- start: () => void;
125
- stop: () => void;
124
+ start: () => Promise<void>;
125
+ stop: () => Promise<void>;
126
126
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reverse-proxy-middleware",
3
- "version": "0.0.144",
3
+ "version": "0.0.145",
4
4
  "description": "A reverse proxy blocking bot requests.",
5
5
  "keywords": [
6
6
  "api",
@@ -55,9 +55,9 @@
55
55
  "serve:simple": "ln --force --symbolic examples/simple.json configuration.json && yarn serve",
56
56
  "serve:state-apis": "ln --force --symbolic examples/state-apis.json configuration.json && yarn serve",
57
57
  "start": "./dist/index.js",
58
- "test": "yarn clear && weboptimizer test",
59
- "test:coverage": "yarn clear && weboptimizer test:coverage",
60
- "test:coverage:report": "yarn clear && weboptimizer test:coverage:report",
58
+ "test": "weboptimizer test",
59
+ "test:coverage": "weboptimizer test:coverage",
60
+ "test:coverage:report": "weboptimizer test:coverage:report",
61
61
  "update:documentation": "web-documentation",
62
62
  "watch": "weboptimizer build --watch"
63
63
  },
@@ -79,8 +79,8 @@
79
79
  "jest": "^30.5.2",
80
80
  "jsdoc": "^4.0.5",
81
81
  "typescript-eslint": "^8.72.1",
82
- "web-documentation": "^1.0.71",
83
- "weboptimizer": "^4.0.102"
82
+ "web-documentation": "^1.0.72",
83
+ "weboptimizer": "^4.0.103"
84
84
  },
85
85
  "resolutions": {
86
86
  "colors": "1.4.0",