Skip to content

Commit b23f83b

Browse files
committed
using pipes for stdin to prevent ECONNRESET error
1 parent ea47024 commit b23f83b

File tree

1 file changed

+73
-87
lines changed

1 file changed

+73
-87
lines changed

main.js

Lines changed: 73 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1-
var url = require("url");
2-
var child = require("child_process");
3-
var path = require("path");
4-
var fs = require("fs");
1+
var url = require("url");
2+
var child = require("child_process");
3+
var path = require("path");
4+
var fs = require("fs");
55

66
function runPHP(req, response, next, phpdir){
77
var parts = url.parse(req.url);
88
var query = parts.query;
9-
10-
var file = path.join(phpdir, parts.pathname);
11-
9+
10+
var file = path.join(phpdir, parts.pathname);
11+
1212
if(!fs.existsSync(file)){
13-
file = path.join(phpdir, "index.php");
13+
file = path.join(phpdir, "index.php");
1414
} else if(fs.statSync(file).isDirectory()){
15-
file = path.join(file, "index.php");
15+
file = path.join(file, "index.php");
1616
}
17-
18-
var pathinfo = "";
19-
var i = req.url.indexOf(".php");
20-
if(i > 0) pathinfo = parts.pathname.substring(i+4);
21-
else pathinfo = parts.pathname;
22-
17+
18+
var pathinfo = "";
19+
var i = req.url.indexOf(".php");
20+
if(i > 0) pathinfo = parts.pathname.substring(i+4);
21+
else pathinfo = parts.pathname;
22+
2323
var env = {
24-
SERVER_SIGNATURE: "NodeJS server at localhost",
24+
SERVER_SIGNATURE: "NodeJS server at localhost",
2525
PATH_INFO: pathinfo, //The extra path information, as given in the requested URL. In fact, scripts can be accessed by their virtual path, followed by extra information at the end of this path. The extra information is sent in PATH_INFO.
2626
PATH_TRANSLATED: "", //The virtual-to-real mapped version of PATH_INFO.
2727
SCRIPT_NAME: parts.pathname, //The virtual path of the script being executed.
28-
SCRIPT_FILENAME: file,
28+
SCRIPT_FILENAME: file,
2929
REQUEST_FILENAME: file, //The real path of the script being executed.
3030
SCRIPT_URI: req.url, //The full URL to the current object requested by the client.
3131
URL: req.url, //The full URI of the current request. It is made of the concatenation of SCRIPT_NAME and PATH_INFO (if available.)
32-
SCRIPT_URL: req.url,
32+
SCRIPT_URL: req.url,
3333
REQUEST_URI: req.url, //The original request URI sent by the client.
3434
REQUEST_METHOD: req.method, //The method used by the current request; usually set to GET or POST.
3535
QUERY_STRING: parts.query||"", //The information which follows the ? character in the requested URL.
3636
CONTENT_TYPE: req.get("Content-type")||"", //"multipart/form-data", //"application/x-www-form-urlencoded", //The MIME type of the request body; set only for POST or PUT requests.
37-
CONTENT_LENGTH: req.rawBody.length||0, //The length in bytes of the request body; set only for POST or PUT requests.
37+
CONTENT_LENGTH: req.get("Content-Length") || 0, //The length in bytes of the request body; set only for POST or PUT requests.
3838
AUTH_TYPE: "", //The authentication type if the client has authenticated itself to access the script.
39-
AUTH_USER: "",
39+
AUTH_USER: "",
4040
REMOTE_USER: "", //The name of the user as issued by the client when authenticating itself to access the script.
4141
ALL_HTTP: Object.keys(req.headers).map(function(x){return "HTTP_"+x.toUpperCase().replace("-", "_")+": "+req.headers[x];}).reduce(function(a, b){return a+b+"\n";}, ""), //All HTTP headers sent by the client. Headers are separated by carriage return characters (ASCII 13 - \n) and each header name is prefixed by HTTP_, transformed to upper cases, and - characters it contains are replaced by _ characters.
4242
ALL_RAW: Object.keys(req.headers).map(function(x){return x+": "+req.headers[x];}).reduce(function(a, b){return a+b+"\n";}, ""), //All HTTP headers as sent by the client in raw form. No transformation on the header names is applied.
@@ -52,95 +52,81 @@ function runPHP(req, response, next, phpdir){
5252
INSTANCE_ID: "", //The numerical identifier of the host which served the request. On Abyss Web Server X1, it is always set to 1 since there is only a single host.
5353
APPL_MD_PATH: "", //The virtual path of the deepest alias which contains the request URI. If no alias contains the request URI, the variable is set to /.
5454
APPL_PHYSICAL_PATH: "", //The real path of the deepest alias which contains the request URI. If no alias contains the request URI, the variable is set to the same value as DOCUMENT_ROOT.
55-
IS_SUBREQ: "", //It is set to true if the current request is a subrequest, i.e. a request not directly invoked by a client. Otherwise, it is set to true. Subrequests are generated by the server for internal processing. XSSI includes for example result in subrequests.
55+
IS_SUBREQ: "", //It is set to true if the current request is a subrequest, i.e. a request not directly invoked by a client. Otherwise, it is set to true. Subrequests are generated by the server for internal processing. XSSI includes for example result in subrequests.
5656
REDIRECT_STATUS: 1
57-
};
58-
59-
Object.keys(req.headers).map(function(x){return env["HTTP_"+x.toUpperCase().replace("-", "_")] = req.headers[x];});
60-
57+
};
58+
59+
Object.keys(req.headers).map(function(x){return env["HTTP_"+x.toUpperCase().replace("-", "_")] = req.headers[x];});
60+
6161
if(/.*?\.php$/.test(file)){
62-
var res = "", err = "";
63-
62+
var res = "", err = "";
63+
6464
var php = child.spawn("php-cgi", [], {
6565
env: env
66-
});
67-
68-
//php.stdin.resume();
69-
//console.log(req.rawBody);
70-
//(new Stream(req.rawBody)).pipe(php.stdin);
71-
php.stdin.on("error", function(){});
72-
php.stdin.write(req.rawBody);
73-
//php.stdin.write("\n");
74-
75-
//php.stdin.end();
76-
66+
});
67+
68+
//php.stdin.resume();
69+
//console.log(req.rawBody);
70+
//(new Stream(req.rawBody)).pipe(php.stdin);
71+
php.stdin.on("error", function(){});
72+
req.pipe(php.stdin); // pipe request stream directly into the php process
73+
req.resume();
74+
//php.stdin.write("\n");
75+
76+
//php.stdin.end();
77+
7778
php.stdout.on("data", function(data){
78-
//console.log(data.toString());
79-
res += data.toString();
80-
});
79+
//console.log(data.toString());
80+
res += data.toString();
81+
});
8182
php.stderr.on("data", function(data){
82-
err += err.toString();
83-
});
83+
err += err.toString();
84+
});
8485
php.on("error", function(err){
85-
console.error(err);
86-
});
86+
console.error(err);
87+
});
8788
php.on("exit", function(){
88-
// extract headers
89-
php.stdin.end();
90-
91-
var lines = res.split("\r\n");
92-
var line = 0;
93-
var html = "";
89+
// extract headers
90+
php.stdin.end();
91+
92+
var lines = res.split("\r\n");
93+
var line = 0;
94+
var html = "";
9495
if(lines.length){
9596
do {
96-
var m = lines[line].split(": ");
97-
if(m[0] === "") break;
98-
99-
//console.log("HEADER: "+m[0]+": "+m[1]);
97+
var m = lines[line].split(": ");
98+
if(m[0] === "") break;
99+
100+
//console.log("HEADER: "+m[0]+": "+m[1]);
100101
if(m[0] == "Status"){
101-
response.statusCode = parseInt(m[1]);
102+
response.statusCode = parseInt(m[1]);
102103
}
103104
if(m.length == 2){
104-
response.setHeader(m[0], m[1]);
105+
response.setHeader(m[0], m[1]);
105106
}
106-
line++;
107-
} while(lines[line] !== "");
108-
109-
html = lines.splice(line+1).join("\n");
107+
line++;
108+
} while(lines[line] !== "");
109+
110+
html = lines.splice(line+1).join("\n");
110111
} else {
111-
html = res;
112+
html = res;
112113
}
113-
//console.log("STATUS: "+response.statusCode);
114-
//console.log(html);
115-
response.status(response.statusCode).send(html);
116-
response.end();
117-
});
118-
114+
//console.log("STATUS: "+response.statusCode);
115+
//console.log(html);
116+
response.status(response.statusCode).send(html);
117+
response.end();
118+
});
119+
119120
} else {
120121
response.sendFile(file);
121-
//response.end();
122-
//next();
122+
//response.end();
123+
//next();
123124
}
124125
}
125126

126127
exports.cgi = function(phproot){
127128
return function(req, res, next){
128-
var data = null;
129-
130-
//req.setEncoding('utf8');
131-
req.on('data', function(chunk) {
132-
//data.write(chunk.toString('binary'), data.length, chunk.length, 'binary');
133-
//console.log(chunk);
134-
if(!data) data = chunk;
135-
else data = data+chunk;
136-
//data = data.concat(chunk);
137-
});
138-
req.on('end', function() {
139-
req.rawBody = data||"";
140-
//console.log(req.rawBody);
141-
//console.log("ENCODING: "+req.get("Content-type")+", len: "+req.rawBody.length);
142-
runPHP(req, res, next, phproot);
143-
});
129+
req.pause(); // stop stream until child-process is opened
130+
runPHP(req, res, next, phproot);
144131
}
145132
}
146-

0 commit comments

Comments
 (0)