commit a8257389adda6ed7a94387602bfcc7d9b46e64d3 Author: schrom01 Date: Fri Nov 4 07:58:11 2022 +0100 initial commit diff --git a/code/expresso/index.js b/code/expresso/index.js new file mode 100644 index 0000000..f39eea5 --- /dev/null +++ b/code/expresso/index.js @@ -0,0 +1,91 @@ +/** + * Webservice mit Express + * WBE-Praktikum + */ + +var express = require('express') +var app = express() + +// Fehlerobjekt anlegen +// +function error(status, msg) { + var err = new Error(msg) + err.status = status + return err +} + +// Zufällige ID erzeugen, Quelle: +// https://stackoverflow.com/questions/6860853/generate-random-string-for-div-id#6860916 +// +function guidGenerator() { + var S4 = function() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1) + } + return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()) +} + +// API-Key überprüfen +// +app.use('/api', function(req, res, next){ + var key = req.query['api-key'] + + // Key fehlt + if (!key) { + return next(error(400, 'api key required')) + } + // Key falsch + if (!~apiKeys.indexOf(key)) { + return next(error(401, 'invalid api key')) + } + // korrekter Key + req.key = key + next() +}) + +// JSON-Daten akzeptieren +app.use(express.json()) + +// gültige API-Keys +var apiKeys = ['wbeweb'] + +// unsere tolle in-memory Datenbank :) +var data = {1234567890: {demodata: "wbe is an inspiring challenge"}} + +// GET-Request bearbeiten +// +app.get('/api/data/:id', function(req, res, next){ + var id = req.params.id + var result = data[id] + + if (result) res.send(result) + else next() +}) + +// POST-Request bearbeiten +// +app.post('/api/data', function (req, res, next) { + let id = guidGenerator() + data[id] = req.body + res.send({id}) +}) + +// Middleware mit vier Argumenten wird zur Fehlerbehandlung verwendet +// +app.use(function(err, req, res, next){ + res.status(err.status || 500) + res.send({ error: err.message }) +}) + +// Catch-all: wenn keine vorangehende Middleware geantwortet hat, wird +// hier ein 404 (not found) erzeugt +// +app.use(function(req, res){ + res.status(404) + res.send({ error: "not found" }) +}) + +app.listen(3000) +console.log('Express started on port 3000') + + + diff --git a/code/expresso/package.json b/code/expresso/package.json new file mode 100644 index 0000000..9505de9 --- /dev/null +++ b/code/expresso/package.json @@ -0,0 +1,14 @@ +{ + "name": "expresso", + "version": "1.0.0", + "description": "Express Demo Project", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "bkrt", + "license": "ISC", + "dependencies": { + "express": "^4.17.1" + } +} diff --git a/code/fileserver/fileserver.js b/code/fileserver/fileserver.js new file mode 100644 index 0000000..a865df8 --- /dev/null +++ b/code/fileserver/fileserver.js @@ -0,0 +1,109 @@ +const {createServer} = require("http"); + +const methods = Object.create(null); + +createServer((request, response) => { + let handler = methods[request.method] || notAllowed; + handler(request) + .catch(error => { + if (error.status != null) return error; + return {body: String(error), status: 500}; + }) + .then(({body, status = 200, type = "text/plain"}) => { + response.writeHead(status, {"Content-Type": type}); + if (body && body.pipe) body.pipe(response); + else response.end(body); + }); +}).listen(8000); + +async function notAllowed(request) { + return { + status: 405, + body: `Method ${request.method} not allowed.` + }; +} + +var {parse} = require("url"); +var {resolve, sep} = require("path"); + +var baseDirectory = process.cwd(); + +function urlPath(url) { + let {pathname} = parse(url); + let path = resolve(decodeURIComponent(pathname).slice(1)); + if (path != baseDirectory && + !path.startsWith(baseDirectory + sep)) { + throw {status: 403, body: "Forbidden"}; + } + return path; +} + +const {createReadStream} = require("fs"); +const {stat, readdir} = require("fs").promises; +const mime = require("mime"); + +methods.GET = async function(request) { + let path = urlPath(request.url); + let stats; + try { + stats = await stat(path); + } catch (error) { + if (error.code != "ENOENT") throw error; + else return {status: 404, body: "File not found"}; + } + if (stats.isDirectory()) { + return {body: (await readdir(path)).join("\n")}; + } else { + return {body: createReadStream(path), + type: mime.getType(path)}; + } +}; + +const {rmdir, unlink} = require("fs").promises; + +methods.DELETE = async function(request) { + let path = urlPath(request.url); + let stats; + try { + stats = await stat(path); + } catch (error) { + if (error.code != "ENOENT") throw error; + else return {status: 204}; + } + if (stats.isDirectory()) await rmdir(path); + else await unlink(path); + return {status: 204}; +}; + +const {createWriteStream} = require("fs"); + +function pipeStream(from, to) { + return new Promise((resolve, reject) => { + from.on("error", reject); + to.on("error", reject); + to.on("finish", resolve); + from.pipe(to); + }); +} + +methods.PUT = async function(request) { + let path = urlPath(request.url); + await pipeStream(request, createWriteStream(path)); + return {status: 204}; +}; + +const {mkdir} = require("fs").promises; + +methods.MKCOL = async function(request) { + let path = urlPath(request.url); + let stats; + try { + stats = await stat(path); + } catch (error) { + if (error.code != "ENOENT") throw error; + await mkdir(path); + return {status: 204}; + } + if (stats.isDirectory()) return {status: 204}; + else return {status: 400, body: "Not a directory"}; +}; \ No newline at end of file diff --git a/code/fileserver/package.json b/code/fileserver/package.json new file mode 100644 index 0000000..0bcd51f --- /dev/null +++ b/code/fileserver/package.json @@ -0,0 +1,14 @@ +{ + "name": "fileserver", + "version": "1.0.0", + "description": "Demo Fileserver", + "main": "fileserver.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Eloquent JavaScript", + "license": "ISC", + "dependencies": { + "mime": "^2.2.0" + } +} diff --git a/praktikum.pdf b/praktikum.pdf new file mode 100644 index 0000000..3cff52f Binary files /dev/null and b/praktikum.pdf differ