From d75bec75a95d5c9e73a065d6fa3551aa2f5ac784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Sun, 23 Jul 2023 09:31:54 +0200 Subject: [PATCH] [upd] plankton --- lib/plankton/plankton.d.ts | 4 +- lib/plankton/plankton.js | 214 +++++++++++++++++++++++-------------- 2 files changed, 136 insertions(+), 82 deletions(-) diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index 3acdf2f..4ac797e 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -1800,8 +1800,7 @@ declare namespace lib_plankton.http { * @author fenris */ type type_request = { - host: string; - query: string; + target: string; method: enum_method; headers: Record; body: string; @@ -1840,6 +1839,7 @@ declare namespace lib_plankton.http { function call(request: type_request, options?: { timeout?: (null | float); follow_redirects?: boolean; + implementation?: ("fetch" | "http_module"); }): Promise; } declare namespace lib_plankton.http { diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index dde6633..308576d 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -4237,7 +4237,7 @@ var lib_plankton; return (new Promise(function (resolve, reject) { nm_fs.readFile(path, { "encoding": "utf8", - "flag": "r" + "flag": "r", }, function (error, content) { if (error == null) { resolve(content); @@ -4256,7 +4256,7 @@ var lib_plankton; var nm_fs = require("fs"); return (new Promise(function (resolve, reject) { nm_fs.readFile(path, { - "flag": "r" + "flag": "r", }, function (error, content) { if (error == null) { resolve(content); @@ -4293,13 +4293,13 @@ var lib_plankton; function write(path, content, options) { if (options === void 0) { options = {}; } options = Object.assign({ - "encoding": "utf-8" + "encoding": "utf-8", }, options); var nm_fs = require("fs"); return (new Promise(function (resolve, reject) { nm_fs.writeFile(path, content, { "encoding": options.encoding, - "flag": "w" + "flag": "w", }, function (error) { if (error == null) { resolve(undefined); @@ -4320,7 +4320,7 @@ var lib_plankton; var nm_fs = require("fs"); return (new Promise(function (resolve, reject) { nm_fs.writeFile(path, content, { - "flag": "w" + "flag": "w", }, function (error) { if (error == null) { resolve(undefined); @@ -4814,8 +4814,8 @@ var lib_plankton; "info": info, "hidden": hidden, "parameters": { - "index": index - } + "index": index, + }, })); }; /** @@ -4833,8 +4833,8 @@ var lib_plankton; "hidden": hidden, "parameters": { "indicators_short": indicators_short, - "indicators_long": indicators_long - } + "indicators_long": indicators_long, + }, })); }; /** @@ -5080,17 +5080,17 @@ var lib_plankton; "symbols": { "delimiter": " ", "prefix": "--", - "assignment": "=" - } + "assignment": "=", + }, }, "url": { "symbols": { "delimiter": "&", "prefix": "", - "assignment": "=" + "assignment": "=", } } - } + }, }; /** * @author fenris @@ -5167,14 +5167,14 @@ var lib_plankton; "pattern_from": pattern_from, "pattern_to": pattern_to, "input": input, - "result": result + "result": result, }); input = result; } } } lib_plankton.log.debug("lib_args:read:current_input", { - "input": input + "input": input, }); } // parsing @@ -5185,18 +5185,18 @@ var lib_plankton; var index_expected_1 = 0; parts.forEach(function (part) { lib_plankton.log.debug("lib_args:read:analyzing", { - "part": part + "part": part, }); var found = [ function () { lib_plankton.log.debug("lib_args:read:probing_as_volatile", { - "part": part + "part": part, }); for (var _i = 0, _a = Object.entries(_this.filter(args.enum_kind.volatile)); _i < _a.length; _i++) { var _b = _a[_i], name = _b[0], argument = _b[1]; lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", { "part": part, - "argument": argument.toString() + "argument": argument.toString(), }); var pattern = ""; { @@ -5215,12 +5215,12 @@ var lib_plankton; pattern += pattern_back; } lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", { - "pattern": pattern + "pattern": pattern, }); var regexp = new RegExp(pattern); var matching = regexp.exec(part); lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", { - "matching": matching + "matching": matching, }); if (matching == null) { // do nothing @@ -5234,7 +5234,7 @@ var lib_plankton; }, function () { lib_plankton.log.debug("lib_args:read:probing_as_positional", { - "part": part + "part": part, }); var positional = _this.filter(args.enum_kind.positional); for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) { @@ -5245,7 +5245,7 @@ var lib_plankton; else { lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", { "part": part, - "argument": argument.toString() + "argument": argument.toString(), }); var pattern = ""; { @@ -5254,12 +5254,12 @@ var lib_plankton; pattern += pattern_back; } lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", { - "pattern": pattern + "pattern": pattern, }); var regexp = new RegExp(pattern); var matching = regexp.exec(part); lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", { - "matching": matching + "matching": matching, }); if (matching == null) { return false; @@ -5276,7 +5276,7 @@ var lib_plankton; ].some(function (x) { return x(); }); if (!found) { lib_plankton.log.warning("lib_args:read:could_not_parse", { - "part": part + "part": part, }); } }); @@ -5625,8 +5625,8 @@ var lib_plankton; */ function encode_request(request) { let request_raw = ""; - request_raw += (encode_method(request.method) + " " + request.query + " " + "HTTP/1.1" + linebreak); - request_raw += ("Host: " + request.host + linebreak); + request_raw += (encode_method(request.method) + " " + request.target + " " + "HTTP/1.1" + linebreak); + // request_raw += ("Host: " + request.host + linebreak); for (const [key, value] of Object.entries(request.headers)) { request_raw += (key + ": " + value + linebreak); } @@ -5641,7 +5641,7 @@ var lib_plankton; function decode_request(request_raw) { const lines = request_raw.split(linebreak); const first = lines.shift(); - const [method_raw, query, version] = first.split(" "); + const [method_raw, target, version] = first.split(" "); let headers = {}; while (true) { const line = lines.shift(); @@ -5655,8 +5655,9 @@ var lib_plankton; } const body = lines.join(linebreak); const request = { - "host": headers["Host"], - "query": query, + // "host": headers["Host"], + // "query": query, + "target": target, "method": decode_method(method_raw), "headers": headers, "body": body, @@ -5714,60 +5715,113 @@ var lib_plankton; options = Object.assign({ "timeout": 5.0, "follow_redirects": false, + "implementation": "fetch", }, options); - function core(signal) { - return (fetch((request.host + request.query), { - "method": ((method => { - switch (method) { - case http.enum_method.get: return "GET"; - case http.enum_method.post: return "POST"; - case http.enum_method.patch: return "PATCH"; - case http.enum_method.put: return "PUT"; - case http.enum_method.delete: return "DELETE"; - case http.enum_method.options: return "OPTIONS"; - case http.enum_method.head: return "HEAD"; - } - })(request.method)), - "redirect": (options.follow_redirects ? "follow" : "manual"), - "signal": (signal ?? undefined), - }) - .then((response_raw) => (response_raw.text() - .then((body) => Promise.resolve({ - "statuscode": response_raw.status, - "headers": ((headers_raw => { - let headers = {}; - headers_raw.forEach((value, key) => { - headers[key] = value; - }); - return headers; - })(response_raw.headers)), - "body": body, - }))))); - } - function timeout(controller) { - return (new Promise((resolve, reject) => { - if (options.timeout === null) { - // do nothing (neither resolve nor reject ever) + switch (options.implementation) { + default: { + return Promise.reject("invalid implementation: " + options.implementation); + break; + } + case "fetch": { + function core(signal) { + return (fetch( + // (request.host + request.query), + request.target, { + "method": ((method => { + switch (method) { + case http.enum_method.get: return "GET"; + case http.enum_method.post: return "POST"; + case http.enum_method.patch: return "PATCH"; + case http.enum_method.put: return "PUT"; + case http.enum_method.delete: return "DELETE"; + case http.enum_method.options: return "OPTIONS"; + case http.enum_method.head: return "HEAD"; + } + })(request.method)), + "redirect": (options.follow_redirects ? "follow" : "manual"), + "signal": (signal ?? undefined), + }) + .catch((reason) => { + console.info(reason); + return Promise.reject(reason); + }) + .then((response_raw) => (response_raw.text() + .then((body) => Promise.resolve({ + "statuscode": response_raw.status, + "headers": ((headers_raw => { + let headers = {}; + headers_raw.forEach((value, key) => { + headers[key] = value; + }); + return headers; + })(response_raw.headers)), + "body": body, + }))))); + } + function timeout(controller) { + return (new Promise((resolve, reject) => { + if (options.timeout === null) { + // do nothing (neither resolve nor reject ever) + } + else { + setTimeout(() => { + controller.abort(); + resolve(null); + }, (options.timeout * 1000)); + } + })); + } + const controller = new AbortController(); + const signal = controller.signal; + const response = await Promise.race([ + timeout(controller), + core(signal), + ]); + if (response === null) { + throw (new Error("http_request_timeout")); } else { - setTimeout(() => { - controller.abort(); - resolve(null); - }, (options.timeout * 1000)); + return response; } - })); - } - const controller = new AbortController(); - const signal = controller.signal; - const response = await Promise.race([ - timeout(controller), - core(signal), - ]); - if (response === null) { - throw (new Error("http_request_timeout")); - } - else { - return response; + break; + } + case "http_module": { + const nm_http = require("http"); + const nm_https = require("https"); + return (new Promise((resolve, reject) => { + const req = (request.target.includes("https") + ? nm_https + : nm_http) + .request(request.target, { + "method": request.method, + "headers": request.headers, + }, (res) => { + try { + let response_body = ""; + res.setEncoding("utf8"); + res.on("data", (chunk) => { + response_body += chunk; + }); + res.on("end", () => { + resolve({ + "statuscode": res.statusCode, + "headers": res.headers, + "body": response_body, + }); + }); + } + catch (error) { + reject(error); + } + }); + req.on("error", (error) => { + reject(error); + }); + req.write(request.body); + req.end(); + })); + break; + } } } http.call = call;