103 lines
3.0 KiB
JavaScript
103 lines
3.0 KiB
JavaScript
var express = require("express");
|
|
var multer = require("multer");
|
|
var sanitizeFilename = require("sanitize-filename");
|
|
var serveIndex = require("serve-index");
|
|
var colors = require("colors");
|
|
var {WebSocketServer} = require("ws");
|
|
var qs = require("qs");
|
|
var proxyaddr = require("proxy-addr");
|
|
var fs = require("fs");
|
|
|
|
|
|
var app = express();
|
|
app.set("env", "production");
|
|
app.set("trust proxy", "loopback");
|
|
app.set("view engine", "pug");
|
|
var server = app.listen(process.env.PORT || 80);
|
|
|
|
var upload = multer({storage: multer.diskStorage({
|
|
destination: "uploads",
|
|
filename: (req, file, cb) => cb(null, safeFilename(file.filename))
|
|
})});
|
|
|
|
var wss = new WebSocketServer({server, maxPayload: 0});
|
|
wss.on("connection", (ws, req) => {
|
|
req.query = qs.parse(req.url.substring(req.url.indexOf('?')+1));
|
|
req.ip = proxyaddr(req, app.get("trust proxy"));
|
|
if (!req.query.name) return ws.close();
|
|
var d = new Date;
|
|
var filename = safeFilename(req.query.name);
|
|
var tmpname = Math.random().toString(36).substring(2);
|
|
try {
|
|
var fd = fs.openSync(`tmp/${tmpname}`, 'w');
|
|
} catch(error) {
|
|
ws.send(error.message);
|
|
return;
|
|
}
|
|
var complete = false;
|
|
ws.on("message", (data, isBinary) => {
|
|
if (isBinary) {
|
|
fs.write(fd, data, (error) => ws.send(error?.message));
|
|
} else {
|
|
if (data == "end") {
|
|
complete = true;
|
|
fs.closeSync(fd);
|
|
fs.renameSync(`tmp/${tmpname}`, `uploads/${filename}`);
|
|
ws.close();
|
|
}
|
|
}
|
|
});
|
|
ws.on("close", () => {
|
|
console.log(`${`[${d.toISOString()}]`.magenta} ${req.ip.cyan} ${"WebSocket".bold.yellow} ${req.headers.host}${req.url} ${`"${req.headers["user-agent"]}"`.gray} ${Date.now()-d}ms`);
|
|
if (!complete) {
|
|
fs.closeSync(fd);
|
|
fs.unlinkSync(`tmp/${tmpname}`);
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
app.use((req, res, next)=>{
|
|
var d = new Date;
|
|
res.on("finish", () => {
|
|
var sc = res.statusCode.toString(), sc = sc.startsWith('2') ? sc.green : sc.startsWith('3') ? sc.cyan : sc.startsWith('4') ? sc.red : sc.startsWith('5') ? sc.yellow.bgRed : sc;
|
|
console.log(`${`[${d.toISOString()}]`.magenta} ${req.ip.cyan} ${req.method.bold.yellow} ${req.hostname}${req.url} ${sc} ${`"${req.headers["user-agent"]}"`.gray} ${Date.now()-d}ms`);
|
|
});
|
|
next();
|
|
});
|
|
|
|
|
|
|
|
app.get("/upload", (req, res) => {
|
|
var files = fs.readdirSync("uploads").map(name => Object.assign({name}, fs.statSync(`uploads/${name}`))).sort((a,b) => b.mtime - a.mtime);
|
|
res.render("upload", {files});
|
|
});
|
|
app.post("/upload", upload.array("file"), (req, res) => {
|
|
res.header("Refresh", 3);
|
|
res.type("json").send(require('util').inspect(req.files));
|
|
});
|
|
|
|
app.use("/assets/", express.static("assets"));
|
|
//app.use((req, res) => serveHandler(req, res, {public: "public"}));
|
|
app.use(express.static("public"), serveIndex("public", {icons: true}));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function safeFilename(f) {
|
|
f = sanitizeFilename(f);
|
|
while (fs.existsSync(`uploads/${f}`)) {
|
|
var x = f.lastIndexOf('.');
|
|
if (x != -1) {
|
|
var fn = f.substring(0, x);
|
|
var fe = f.substring(x);
|
|
} else var fn = f, fe = '';
|
|
var m = fn.match(/(.*)(?<= )(\d+)$/);
|
|
if (m) fn = m[1] + ++m[2];
|
|
else fn += " 2";
|
|
f = fn + fe;
|
|
}
|
|
return f;
|
|
} |