very dirty hack for protoweb support
This commit is contained in:
@@ -850,7 +850,7 @@ minisrv-no-mail-count: true`;
|
|||||||
if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers)))));
|
if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers)))));
|
||||||
socket_sessions[socket.id].request_headers = request_headers;
|
socket_sessions[socket.id].request_headers = request_headers;
|
||||||
processPath(socket, urlToPath, request_headers, service_name, shared_romcache, pc_services);
|
processPath(socket, urlToPath, request_headers, service_name, shared_romcache, pc_services);
|
||||||
} else if ((shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) && !pc_services) {
|
} else if (shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0 || (minisrv_config.services[service_name].use_external_proxy == true && shortURL.indexOf(service_name + "://") >= 0) && !pc_services) {
|
||||||
doHTTPProxy(socket, request_headers);
|
doHTTPProxy(socket, request_headers);
|
||||||
} else if (shortURL.indexOf('file://') >= 0) {
|
} else if (shortURL.indexOf('file://') >= 0) {
|
||||||
shortURL = shortURL.replace("file://",'').replace("romcache", "ROMCache");
|
shortURL = shortURL.replace("file://",'').replace("romcache", "ROMCache");
|
||||||
@@ -886,14 +886,96 @@ minisrv-no-mail-count: true`;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array.prototype.replace = function(sub, newSub) {
|
||||||
|
splits = this.split(sub, 2);
|
||||||
|
return Array.concat(splits[0], newSub, splits[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleProxy(socket, request_type, request_headers, res, data) {
|
||||||
|
console.log(` * Proxy Request ${request_type.toUpperCase()} ${res.statusCode} for ${request_headers.request}`)
|
||||||
|
// an http response error is not a request error, and will come here under the 'end' event rather than an 'error' event.
|
||||||
|
switch (res.statusCode) {
|
||||||
|
case 404:
|
||||||
|
res.headers.Response = res.statusCode + " The publisher can’t find the page requested.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 401:
|
||||||
|
case 403:
|
||||||
|
res.headers.Response = res.statusCode + " The publisher of that page has not authorized you to use it.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 500:
|
||||||
|
res.headers.Response = res.statusCode + " The publisher of that page can’t be reached.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
res.headers.Response = res.statusCode + " " + res.statusMessage;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.headers['Content-yype']) {
|
||||||
|
res.headers['Content-Type'] = res.headers['Content-Type'];
|
||||||
|
delete (res.headers['Content-type'])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.headers['content-type']) {
|
||||||
|
res.headers['Content-Type'] = res.headers['content-type'];
|
||||||
|
delete (res.headers['content-type'])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.headers['Content-Type'].substr(0, 4) == "text" && request_type != "http" && request_type != "https") {
|
||||||
|
var data_t = data.toString().replaceAll("http://", request_type + "://").replaceAll("https://", request_type + "://");
|
||||||
|
data = [Buffer.from(data_t)]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// header pass-through whitelist, case insensitive comparsion to server, however, you should
|
||||||
|
// specify the header case as you intend for the client
|
||||||
|
var headers = stripHeaders(res.headers, [
|
||||||
|
'Connection',
|
||||||
|
'Server',
|
||||||
|
'Date',
|
||||||
|
'Content-Type',
|
||||||
|
'Cookie',
|
||||||
|
'Location',
|
||||||
|
'Accept-Ranges',
|
||||||
|
'Last-Modified'
|
||||||
|
]);
|
||||||
|
headers["wtv-http-proxy"] = true;
|
||||||
|
headers["wtv-trusted"] = false;
|
||||||
|
|
||||||
|
// if Connection: close header, set our internal variable to close the socket
|
||||||
|
if (headers['Connection']) {
|
||||||
|
if (headers['Connection'].toLowerCase().indexOf('close') !== -1) {
|
||||||
|
headers["wtv-connection-close"] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a wtv-explaination is defined for an error code (except 200), define the header here to
|
||||||
|
// show the 'Explain' button on the client error ShowAlert
|
||||||
|
if (minisrv_config.services['http']['wtv-explanation']) {
|
||||||
|
if (minisrv_config.services['http']['wtv-explanation'][res.statusCode]) {
|
||||||
|
headers['wtv-explanation-url'] = minisrv_config.services['http']['wtv-explanation'][res.statusCode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var data_hex = Buffer.concat(data).toString('hex');
|
||||||
|
if (data_hex.substring(0, 8) == "0d0a0d0a") data_hex = data_hex.substring(8);
|
||||||
|
if (data_hex.substring(0, 4) == "0a0a") data_hex = data_hex.substring(4);
|
||||||
|
sendToClient(socket, headers, Buffer.from(data_hex, 'hex'));
|
||||||
|
}
|
||||||
|
|
||||||
async function doHTTPProxy(socket, request_headers) {
|
async function doHTTPProxy(socket, request_headers) {
|
||||||
var request_type = (request_headers.request_url.substring(0, 5) == "https") ? "https" : "http";
|
// detect protocol name
|
||||||
|
var idx = request_headers.request_url.indexOf('/') - 1;
|
||||||
|
|
||||||
|
var request_type = request_headers.request_url.substring(0, idx);
|
||||||
if (minisrv_config.config.debug_flags.show_headers) console.log(request_type.toUpperCase() + " Proxy: Client Request Headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers)))));
|
if (minisrv_config.config.debug_flags.show_headers) console.log(request_type.toUpperCase() + " Proxy: Client Request Headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers)))));
|
||||||
switch (request_type) {
|
switch (request_type) {
|
||||||
case "https":
|
case "https":
|
||||||
var proxy_agent = https;
|
var proxy_agent = https;
|
||||||
break;
|
break;
|
||||||
case "http":
|
case "http":
|
||||||
|
case "proto":
|
||||||
var proxy_agent = http;
|
var proxy_agent = http;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -911,7 +993,6 @@ async function doHTTPProxy(socket, request_headers) {
|
|||||||
}
|
}
|
||||||
for (var i = 0; i < 3; i++) request_url_split.shift();
|
for (var i = 0; i < 3; i++) request_url_split.shift();
|
||||||
request_data.path = "/" + request_url_split.join('/');
|
request_data.path = "/" + request_url_split.join('/');
|
||||||
|
|
||||||
if (request_data.method && request_data.host && request_data.path) {
|
if (request_data.method && request_data.host && request_data.path) {
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
@@ -949,91 +1030,61 @@ async function doHTTPProxy(socket, request_headers) {
|
|||||||
options.port = minisrv_config.services[request_type].external_proxy_port;
|
options.port = minisrv_config.services[request_type].external_proxy_port;
|
||||||
options.path = request_headers.request.split(' ')[1];
|
options.path = request_headers.request.split(' ')[1];
|
||||||
options.headers.Host = request_data.host + ":" + request_data.port;
|
options.headers.Host = request_data.host + ":" + request_data.port;
|
||||||
|
options.headers.Connection = 'close';
|
||||||
|
options.insecureHTTPParser = true;
|
||||||
|
if (minisrv_config.services[request_type].replace_protocol) {
|
||||||
|
options.path = options.path.replace(request_type, minisrv_config.services[request_type].replace_protocol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (minisrv_config.services[request_type].external_proxy_is_http1) {
|
||||||
|
options.insecureHTTPParser = true;
|
||||||
|
options.headers.Connection = 'close'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const req = proxy_agent.request(options, function (res) {
|
const req = proxy_agent.request(options, function (res) {
|
||||||
var data = [];
|
var data = [];
|
||||||
|
var data_handled = false;
|
||||||
|
|
||||||
res.on('data', d => {
|
res.on('data', d => {
|
||||||
data.push(d);
|
data.push(d);
|
||||||
})
|
})
|
||||||
|
|
||||||
res.on('error', function (err) {
|
res.on('error', function (err) {
|
||||||
console.log(" * Unhandled Proxy Request Error:", err);
|
// hack for Protoweb ECONNRESET
|
||||||
|
if (minisrv_config.services[request_type].external_proxy_is_http1 && data.length > 0 && !data_handled) {
|
||||||
|
handleProxy(socket, request_type, request_headers, res, data);
|
||||||
|
data_handled = true
|
||||||
|
} else {
|
||||||
|
console.log(" * Unhandled Proxy Request Error:", err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.on('end', function () {
|
res.on('end', function () {
|
||||||
var data_hex = Buffer.concat(data).toString('hex');
|
// Hack for when old http proxies behave correctly
|
||||||
|
if (!minisrv_config.services[request_type].external_proxy_is_http1 || data.length > 0 && !data_handled) {
|
||||||
console.log(` * Proxy Request ${request_type.toUpperCase()} ${res.statusCode} for ${request_headers.request}`)
|
handleProxy(socket, request_type, request_headers, res, data);
|
||||||
// an http response error is not a request error, and will come here under the 'end' event rather than an 'error' event.
|
data_handled = true;
|
||||||
switch (res.statusCode) {
|
|
||||||
case 404:
|
|
||||||
res.headers.Response = res.statusCode + " The publisher can’t find the page requested.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 401:
|
|
||||||
case 403:
|
|
||||||
res.headers.Response = res.statusCode + " The publisher of that page has not authorized you to use it.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 500:
|
|
||||||
res.headers.Response = res.statusCode + " The publisher of that page can’t be reached.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
res.headers.Response = res.statusCode + " " + res.statusMessage;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// header pass-through whitelist, case insensitive comparsion to server, however, you should
|
|
||||||
// specify the header case as you intend for the client
|
|
||||||
var headers = stripHeaders(res.headers, [
|
|
||||||
'Connection',
|
|
||||||
'Server',
|
|
||||||
'Date',
|
|
||||||
'Content-Type',
|
|
||||||
'Cookie',
|
|
||||||
'Location',
|
|
||||||
'Accept-Ranges',
|
|
||||||
'Last-Modified'
|
|
||||||
]);
|
|
||||||
headers["wtv-http-proxy"] = true;
|
|
||||||
headers["wtv-trusted"] = false;
|
|
||||||
|
|
||||||
// if Connection: close header, set our internal variable to close the socket
|
|
||||||
if (headers['Connection']) {
|
|
||||||
if (headers['Connection'].toLowerCase().indexOf('close') !== -1) {
|
|
||||||
headers["wtv-connection-close"] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if a wtv-explaination is defined for an error code (except 200), define the header here to
|
|
||||||
// show the 'Explain' button on the client error ShowAlert
|
|
||||||
if (minisrv_config.services['http']['wtv-explanation']) {
|
|
||||||
if (minisrv_config.services['http']['wtv-explanation'][res.statusCode]) {
|
|
||||||
headers['wtv-explanation-url'] = minisrv_config.services['http']['wtv-explanation'][res.statusCode];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data_hex.substring(0, 8) == "0d0a0d0a") data_hex = data_hex.substring(8);
|
|
||||||
if (data_hex.substring(0, 4) == "0a0a") data_hex = data_hex.substring(4);
|
|
||||||
sendToClient(socket, headers, Buffer.from(data_hex, 'hex'));
|
|
||||||
});
|
});
|
||||||
}).on('error', function (err) {
|
}).on('error', function (err) {
|
||||||
// severe errors, such as unable to connect.
|
// severe errors, such as unable to connect.
|
||||||
var errpage, headers, data = null;
|
var errpage, headers, data = null;
|
||||||
if (err.code == "ENOTFOUND" || err.message.indexOf("HostUnreachable") > 0) {
|
if (err.code == "ENOTFOUND" || err.message.indexOf("HostUnreachable") > 0) {
|
||||||
errpage = wtvshared.doErrorPage(400, `The publisher <b>${request_data.host}</b> is unknown.`);
|
errpage = wtvshared.doErrorPage(400, `The publisher <b>${request_data.host}</b> is unknown.`);
|
||||||
|
} else {
|
||||||
|
if (minisrv_config.services[request_type].external_proxy_is_http1 && !data_handled) {
|
||||||
|
handleProxy(socket, request_type, request_headers, res, data);
|
||||||
|
data_handled = true;
|
||||||
|
} else {
|
||||||
|
console.log(" * Unhandled Proxy Request Error:", err);
|
||||||
|
errpage = wtvshared.doErrorPage(400);
|
||||||
|
headers = errpage[0];
|
||||||
|
data = errpage[1];
|
||||||
|
sendToClient(socket, headers, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
console.log(" * Unhandled Proxy Request Error:", err);
|
});
|
||||||
errpage = wtvshared.doErrorPage(400);
|
|
||||||
}
|
|
||||||
headers = errpage[0];
|
|
||||||
data = errpage[1];
|
|
||||||
sendToClient(socket, headers, data);
|
|
||||||
});;
|
|
||||||
if (request_headers.post_data) {
|
if (request_headers.post_data) {
|
||||||
req.write(Buffer.from(request_headers.post_data.toString(CryptoJS.enc.Hex), 'hex'), function () {
|
req.write(Buffer.from(request_headers.post_data.toString(CryptoJS.enc.Hex), 'hex'), function () {
|
||||||
req.end();
|
req.end();
|
||||||
|
|||||||
@@ -285,7 +285,7 @@
|
|||||||
"port": 1643,
|
"port": 1643,
|
||||||
"connections": 3,
|
"connections": 3,
|
||||||
"enable_multi_query": true,
|
"enable_multi_query": true,
|
||||||
"max_pages": 4,
|
"max_pages": 4,
|
||||||
"publish_mode": "service", // "service" or "directory"
|
"publish_mode": "service", // "service" or "directory"
|
||||||
"publish_dest": "pb_services", // service name, or directory path
|
"publish_dest": "pb_services", // service name, or directory path
|
||||||
"modules": [
|
"modules": [
|
||||||
@@ -311,13 +311,25 @@
|
|||||||
"external_proxy_port": 1080, // Port of proxy
|
"external_proxy_port": 1080, // Port of proxy
|
||||||
"flags": "0x00000001"
|
"flags": "0x00000001"
|
||||||
},
|
},
|
||||||
"pb_services": {
|
"proto": {
|
||||||
|
"port": 1650,
|
||||||
|
"connections": 3,
|
||||||
|
"use_external_proxy": true,
|
||||||
|
"replace_protocol": "http",
|
||||||
|
"external_proxy_is_socks": false,
|
||||||
|
"external_proxy_host": "wayback.protoweb.org",
|
||||||
|
"external_proxy_port": 7851,
|
||||||
|
"external_proxy_is_http1": true,
|
||||||
|
"flags": "0x00000001"
|
||||||
|
},
|
||||||
|
|
||||||
|
"pb_services": {
|
||||||
// PC Services for PageBuilder
|
// PC Services for PageBuilder
|
||||||
"port": 1697,
|
"port": 1697,
|
||||||
"pc_services": true, // defines service as a PC service
|
"pc_services": true, // defines service as a PC service
|
||||||
"hide_minisrv_version": true, // hide or show the minisrv version (eg like Apache version, can be hidden to hide known exploits for older version)
|
"hide_minisrv_version": true, // hide or show the minisrv version (eg like Apache version, can be hidden to hide known exploits for older version)
|
||||||
"servicevault_dir": "http_pb", // The service vault dir for the PC Services for PageBuilder
|
"servicevault_dir": "http_pb", // The service vault dir for the PC Services for PageBuilder
|
||||||
"service_vaults": ["PageBuilderVault"], // additional service vaults for this service
|
"service_vaults": [ "PageBuilderVault" ], // additional service vaults for this service
|
||||||
"drop_connection_on_wrong_port": true, // If true, resets connection if the PC browser connects to a port that is not PC Services enabled
|
"drop_connection_on_wrong_port": true, // If true, resets connection if the PC browser connects to a port that is not PC Services enabled
|
||||||
"show_verbose_errors": false, // extra debugging
|
"show_verbose_errors": false, // extra debugging
|
||||||
"allow_https": false, // for future use with LetsEncrypt
|
"allow_https": false, // for future use with LetsEncrypt
|
||||||
|
|||||||
4
zefie_wtvp_minisrv/package-lock.json
generated
4
zefie_wtvp_minisrv/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "zefie_wtvp_minisrv",
|
"name": "zefie_wtvp_minisrv",
|
||||||
"version": "0.9.47",
|
"version": "0.9.49",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "zefie_wtvp_minisrv",
|
"name": "zefie_wtvp_minisrv",
|
||||||
"version": "0.9.47",
|
"version": "0.9.49",
|
||||||
"license": "GPL3",
|
"license": "GPL3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mafintosh/vm2": "^3.9.2",
|
"@mafintosh/vm2": "^3.9.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user