Commit a2e5e085 authored by CompileNix's avatar CompileNix

fix POSTed data potential disposed before completing reading

parent 82bd9d0d
...@@ -3,10 +3,10 @@ const http = require("http"); ...@@ -3,10 +3,10 @@ const http = require("http");
const url = require("url"); const url = require("url");
const fs = require("fs"); const fs = require("fs");
const zlib = require("zlib"); const zlib = require("zlib");
const WebSocketServer = require('ws').Server; const WebSocketServer = require("ws").Server;
const htmlencode = require("htmlencode").Encoder("htmlEncode").htmlEncode;
const cache = [ const cache = [{
{
path: "robots.txt", path: "robots.txt",
content: fs.readFileSync("./robots.txt", "utf8"), content: fs.readFileSync("./robots.txt", "utf8"),
content_type: "text/plain", content_type: "text/plain",
...@@ -41,12 +41,20 @@ const cache = [ ...@@ -41,12 +41,20 @@ const cache = [
} }
]; ];
cache.forEach((element) => { cache.forEach(element => {
const contentBuffer = new Buffer(element.content); const contentBuffer = new Buffer(element.content);
element.length = Buffer.byteLength(element.content, "utf8"); element.length = Buffer.byteLength(element.content, "utf8");
element.content_gzip = zlib.gzipSync(contentBuffer, { level: zlib.Z_BEST_COMPRESSION, memLevel: 9, flush: zlib.Z_NO_FLUSH }); element.content_gzip = zlib.gzipSync(contentBuffer, {
level: zlib.Z_BEST_COMPRESSION,
memLevel: 9,
flush: zlib.Z_NO_FLUSH
});
element.content_gzip_length = Buffer.byteLength(element.content_gzip); element.content_gzip_length = Buffer.byteLength(element.content_gzip);
element.content_deflate = zlib.deflateSync(contentBuffer, { level: zlib.Z_BEST_COMPRESSION, memLevel: 9, flush: zlib.Z_NO_FLUSH }); element.content_deflate = zlib.deflateSync(contentBuffer, {
level: zlib.Z_BEST_COMPRESSION,
memLevel: 9,
flush: zlib.Z_NO_FLUSH
});
element.content_deflate_length = Buffer.byteLength(element.content_deflate); element.content_deflate_length = Buffer.byteLength(element.content_deflate);
}); });
...@@ -69,9 +77,11 @@ class Server { ...@@ -69,9 +77,11 @@ class Server {
http.createServer(Server.onRequest).listen(this.port); http.createServer(Server.onRequest).listen(this.port);
this.socketServer = http.createServer(Server.onRequestSocketServer); this.socketServer = http.createServer(Server.onRequestSocketServer);
this.socketServer.listen(this.port + 1); this.socketServer.listen(this.port + 1);
this.socket = new WebSocketServer({server: this.socketServer}); this.socket = new WebSocketServer({
server: this.socketServer
});
this.socket.on('connection', (ws) => { this.socket.on('connection', ws => {
clients.push(ws); clients.push(ws);
ws.on('close', () => { ws.on('close', () => {
...@@ -86,7 +96,7 @@ class Server { ...@@ -86,7 +96,7 @@ class Server {
const queryPath = url.parse(request.url).path; const queryPath = url.parse(request.url).path;
let returns = false; let returns = false;
cache.forEach((element) => { cache.forEach(element => {
if (queryPath === `/${element.path}`) { if (queryPath === `/${element.path}`) {
Server.sendResponse(request, response, element); Server.sendResponse(request, response, element);
returns = true; returns = true;
...@@ -113,20 +123,16 @@ class Server { ...@@ -113,20 +123,16 @@ class Server {
static debugOut(request, data) { static debugOut(request, data) {
let stuff = { let stuff = {
Date: new Date(), Date: new Date(),
Method: request.method, Method: htmlencode(request.method),
RequestUrl: request.url, RequestUrl: htmlencode(request.url),
Data: data Data: htmlencode(data)
}; };
let stuffString = JSON.stringify(stuff); let stuffString = JSON.stringify(stuff);
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log("Date: " + new Date() + "\n" console.log(`Date: ${new Date()}\n${request.method}: ${request.url}\nHeaders: ${JSON.stringify(request.headers)}\nData: ${data}\n`);
+ request.method + ": " + request.url + "\n"
+ "Headers: " + JSON.stringify(request.headers) + "\n"
+ "Data: " + data
+ "\n");
clients.forEach((ws) => { clients.forEach(ws => {
if (ws.OPEN !== 1) { if (ws.OPEN !== 1) {
return; return;
} }
...@@ -147,9 +153,17 @@ class Server { ...@@ -147,9 +153,17 @@ class Server {
let data; let data;
const contentBuffer = new Buffer(element.content || ""); const contentBuffer = new Buffer(element.content || "");
element.length = Buffer.byteLength(element.content, "utf8"); element.length = Buffer.byteLength(element.content, "utf8");
element.content_gzip = zlib.gzipSync(contentBuffer, { level: zlib.Z_BEST_COMPRESSION, memLevel: 9, flush: zlib.Z_NO_FLUSH }); element.content_gzip = zlib.gzipSync(contentBuffer, {
level: zlib.Z_BEST_COMPRESSION,
memLevel: 9,
flush: zlib.Z_NO_FLUSH
});
element.content_gzip_length = Buffer.byteLength(element.content_gzip); element.content_gzip_length = Buffer.byteLength(element.content_gzip);
element.content_deflate = zlib.deflateSync(contentBuffer, { level: zlib.Z_BEST_COMPRESSION, memLevel: 9, flush: zlib.Z_NO_FLUSH }); element.content_deflate = zlib.deflateSync(contentBuffer, {
level: zlib.Z_BEST_COMPRESSION,
memLevel: 9,
flush: zlib.Z_NO_FLUSH
});
element.content_deflate_length = Buffer.byteLength(element.content_deflate); element.content_deflate_length = Buffer.byteLength(element.content_deflate);
if (request.headers["accept-encoding"]) { // if accept-encoding if (request.headers["accept-encoding"]) { // if accept-encoding
...@@ -206,7 +220,7 @@ class Server { ...@@ -206,7 +220,7 @@ class Server {
const queryPath = url.parse(request.url).path; const queryPath = url.parse(request.url).path;
let returns = false; let returns = false;
cache.forEach((element) => { cache.forEach(element => {
if (queryPath === `/${element.path}`) { if (queryPath === `/${element.path}`) {
Server.sendResponse(request, response, element); Server.sendResponse(request, response, element);
returns = true; returns = true;
...@@ -215,48 +229,61 @@ class Server { ...@@ -215,48 +229,61 @@ class Server {
if (returns) return; if (returns) return;
if (request.method === "POST") { let requestHasPayload = false;
let body = ""; let requestPayload = "";
switch (request.method) {
case "PUT":
case "POST":
requestHasPayload = true;
request.on("data", postData => {
if (requestPayload.length + postData.length < 1e6) { // ~1 Megabyte
requestPayload += postData;
} else {
Server.debugOut(request, "Request entity too large");
Server.sendResponse(request, response, {
status_code: 413,
content: "Request entity too large"
});
return;
}
});
request.on("end", () => {
switch (request.headers["content-type"]) {
case "application/x-www-form-urlencoded":
requestPayload = querystring.unescape(requestPayload);
break;
}
request.on("data", (postData) => {
// reading http POST body
if (body.length + postData.length < 5e7) { // // 50 Megabyte
body += postData;
} else {
Server.debugOut(request, "Request entity too large");
Server.sendResponse(request, response, { Server.sendResponse(request, response, {
status_code: 413, status_code: 200,
content: "Request entity too large" content: "OK"
}); });
return; Server.debugOut(request, requestPayload);
} });
}); break;
request.on("end", () => { case "HEAD":
switch(request.headers["content-type"]) { case "GET":
case "application/x-www-form-urlencoded": Server.debugOut(request, null);
body = querystring.unescape(body); break;
break;
} default:
Server.debugOut(request, null);
Server.sendResponse(request, response, {
status_code: 501,
content: "Not Implemented"
});
return;
}
Server.debugOut(request, body); if (!requestHasPayload) {
});
} else if (request.method === "GET") {
Server.debugOut(request, null);
} else {
Server.debugOut(request, null);
Server.sendResponse(request, response, { Server.sendResponse(request, response, {
status_code: 501, status_code: 200,
content: "Not Implemented" content: "OK"
}); });
return;
} }
Server.sendResponse(request, response, {
status_code: 200,
content: "OK"
});
return; return;
} }
} }
......
This diff is collapsed.
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"start": "npm install && node app.js" "start": "npm install && node app.js"
}, },
"dependencies": { "dependencies": {
"htmlencode": "*",
"jquery": "*", "jquery": "*",
"use-strict": "^1.0.1", "use-strict": "^1.0.1",
"ws": "^2.3.1" "ws": "^2.3.1"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment