#!/usr/bin/env node
const http2 = require("http2" );
const fs = require("fs" );
const path = require("path" );
const [directory = "." , certFile, keyFile] = process.argv.slice(2 );
const opts = certFile
? { cert: fs.readFileSync(certFile), key: fs.readFileSync(keyFile) }
: {};
const server = certFile ? http2.createSecureServer(opts) : http2.createServer();
server.on("stream" , (stream, headers) => {
const reqPath = headers[":path" ];
let filePath = path.join(directory, reqPath);
if (
!path.resolve(filePath).startsWith(path.resolve(directory) + path.sep) &&
path.resolve(filePath) !== path.resolve(directory)
) {
stream.respond({ ":status" : 403 });
stream.end();
return;
}
if (filePath.endsWith("/" )) {
filePath += "index.html" ;
}
console.log(`${headers[":method" ]} ${reqPath}`);
const ext = path.extname(filePath);
const contentType =
{
".html" : "text/html" ,
".js" : "application/javascript" ,
".css" : "text/css" ,
".json" : "application/json" ,
".png" : "image/png" ,
".jpg" : "image/jpeg" ,
".gif" : "image/gif" ,
".svg" : "image/svg+xml" ,
".ico" : "image/x-icon" ,
}[ext] || "application/octet-stream" ;
fs.createReadStream(filePath)
.on("error" , () => {
stream.respond({ ":status" : 404 });
stream.end();
})
.on("open" , () => {
stream.respond({ ":status" : 200 , "content-type" : contentType });
})
.pipe(stream);
});
const protocol = certFile ? "https" : "http" ;
server.listen(8000 , () => {
console.log(`HTTP/2 server (${protocol}) listening on port 8000 `);
console.log(`Serving files from: ${path.resolve(directory)}`);
});
server.on("error" , err => {
console.error("Server error:" , err);
});
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.0 Sekunden
(vorverarbeitet am 2026-09-03)
¤
*© Formatika GbR, Deutschland