Update main.yml
[forward-proxy-mod.git] / index.js
blob578834eca5136c1c1d356823b83610c02d7b53db
1 var http = require("http");
2 var https = require("https");
3 var net = require("net");
4 var tls = require("tls");
6 function Mod() {}
7 Mod.prototype.callback = function callback(req, res, serverconsole, responseEnd, href, ext, uobject, search, defaultpage, users, page404, head, foot, fd, elseCallback, configJSON, callServerError, getCustomHeaders, origHref, redirect, parsePostData) {
8 return function () {
9 if (!res.writeHead) {
10 Mod.prototype.proxyCallback(req, res, serverconsole, responseEnd, href, ext)();
11 return;
13 var isProxy = (req.url && req.url.match(/^https?:\/\//));
14 if (isProxy) {
15 var reqUObject = {};
16 try {
17 reqUObject = new URL(req.url);
18 } catch (ex) {
19 callServerError(400, "forward-proxy-mod/1.0.0"); // Malformed URL
20 serverconsole.errmessage("Invalid request!");
22 var hdrs = JSON.parse(JSON.stringify(req.headers));
23 delete hdrs[":method"];
24 delete hdrs[":scheme"];
25 delete hdrs[":authority"];
26 delete hdrs[":path"];
27 delete hdrs["keep-alive"];
28 if ((req.httpVersion == "1.1" || req.httpVersion == "1.0") && String(hdrs["connection"]).toLowerCase() == "upgrade") {
29 var socket = ((reqUObject.protocol == "https:") ? tls : net).createConnection({
30 host: reqUObject.hostname,
31 port: reqUObject.port ? parseInt(reqUObject.port) : ((reqUObject.protocol == "https:") ? 443 : 80),
32 joinDuplicateHeaders: true,
33 rejectUnauthorized: false
34 }, function () {
35 serverconsole.resmessage("Connected to back-end!");
36 socket.pipe(res.socket);
37 socket.write(req.method + " " + reqUObject.pathname + reqUObject.search + reqUObject.hash + " HTTP/1.1\r\n");
38 Object.keys(hdrs).forEach(function (headerName) {
39 var header = hdrs[headerName];
40 if (typeof header === "object") {
41 header.forEach(function (value) {
42 socket.write(headerName + ": " + value + "\r\n");
43 });
44 } else {
45 socket.write(headerName + ": " + header + "\r\n");
47 });
48 socket.write("\r\n");
49 req.socket.pipe(socket);
50 }).on("error", function (ex) {
51 try {
52 if (ex.code == "ETIMEDOUT") {
53 callServerError(504, "forward-proxy-mod/1.0.0", ex); //Server error
54 } else {
55 callServerError(502, "forward-proxy-mod/1.0.0", ex); //Server error
57 } catch (ex) {}
58 serverconsole.errmessage("Client fails to recieve content."); //Log into SVR.JS
59 });
60 } else {
61 if (String(hdrs["connection"]).toLowerCase() != "upgrade") hdrs["connection"] = "close";
62 var options = {
63 hostname: reqUObject.hostname,
64 port: reqUObject.port ? parseInt(reqUObject.port) : ((reqUObject.protocol == "https:") ? 443 : 80),
65 path: reqUObject.pathname + reqUObject.search + reqUObject.hash,
66 method: req.method,
67 headers: hdrs,
68 joinDuplicateHeaders: true,
69 rejectUnauthorized: false
71 var proxy = ((reqUObject.protocol == "https:") ? https : http).request(options, function (sres) {
72 serverconsole.resmessage("Connected to back-end!");
73 if (String(hdrs["connection"]).toLowerCase() != "upgrade") {
74 delete sres.headers["connection"];
75 delete sres.headers["Connection"];
77 delete sres.headers["transfer-encoding"];
78 delete sres.headers["Transfer-Encoding"];
79 delete sres.headers["keep-alive"];
80 delete sres.headers["Keep-Alive"];
81 try {
82 res.writeHead(sres.statusCode, sres.headers);
83 sres.pipe(res);
84 res.prependListener("end", function () {
85 try {
86 sres.end();
87 } catch (ex) {}
88 });
89 } catch (ex) {
90 callServerError(502, "forward-proxy-mod/1.0.0", ex); //Server error
92 });
93 proxy.on("error", function (ex) {
94 try {
95 if (ex.code == "ETIMEDOUT") {
96 callServerError(504, "forward-proxy-mod/1.0.0", ex); //Server error
97 } else {
98 callServerError(502, "forward-proxy-mod/1.0.0", ex); //Server error
100 } catch (ex) {}
101 serverconsole.errmessage("Client fails to receive content."); //Log into SVR.JS
103 req.pipe(proxy);
104 req.prependListener("end", function () {
105 try {
106 proxy.end();
107 } catch (ex) {}
110 } else {
111 elseCallback();
116 Mod.prototype.proxyCallback = function proxyCallback(req, socket, head, configJSON, serverconsole, elseCallback) {
117 return function () {
118 var service = req.url;
119 var h = service.match(/^([^:]+):([0-9]{1,4}|[0-5][0-9]{5}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/);
120 if (!h) {
121 if (!socket.destroyed) socket.write("HTTP/1.1 400 Bad Request\n\n");
122 serverconsole.errmessage("Invalid request!");
124 var dSocket = net.createConnection({
125 host: h[1],
126 port: parseInt(h[2]),
127 joinDuplicateHeaders: true
128 }, function () {
129 serverconsole.resmessage("Connected to back-end!");
130 socket.write("HTTP/1.1 200 OK\n\n");
131 dSocket.pipe(socket);
132 if (head) dSocket.write(head);
133 socket.pipe(dSocket);
134 }).on("error", function (ex) {
135 try {
136 if (ex.code == "ETIMEDOUT") {
137 socket.write("HTTP/1.1 504 Gateway Timeout\n\n"); //Server error
138 } else {
139 socket.write("HTTP/1.1 502 Bad Gateway\n\n"); //Server error
141 socket.end();
142 } catch (ex) {}
143 serverconsole.errmessage("Client fails to receive content."); //Log into SVR.JS
148 module.exports = Mod; //SVR.JS mod export