Skip to content

Instantly share code, notes, and snippets.

@dotnetCarpenter
Last active January 27, 2022 16:54
Show Gist options
  • Save dotnetCarpenter/1cb0ce685e2962a74987a5fba6f49b9a to your computer and use it in GitHub Desktop.
Save dotnetCarpenter/1cb0ce685e2962a74987a5fba6f49b9a to your computer and use it in GitHub Desktop.

Revisions

  1. dotnetCarpenter revised this gist Jan 27, 2022. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions text.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    Foobar
    æøå
  2. dotnetCarpenter revised this gist Jan 27, 2022. 1 changed file with 13 additions and 0 deletions.
    13 changes: 13 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    </head>
    <body>
    <h1>Heading 1</h1>

    <iframe src="text.txt"></iframe>
    </body>
    </html>
  3. dotnetCarpenter created this gist Jan 27, 2022.
    79 changes: 79 additions & 0 deletions server.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    const http = require ('http')
    const fs = require ('fs')
    const path = require ('path')
    const S = require ('sanctuary')
    const $ = require ('sanctuary-def')
    const show = require ('sanctuary-show')
    const {
    State,
    } = require ('monastic')

    const setContentType = response => filePath => {
    switch (path.extname (filePath)) {
    case '.html':
    case '.htm':
    response.setHeader ('Content-Type', 'text/html; charset=utf-8')
    break
    case '.js':
    case '.mjs':
    response.setHeader ('Content-Type', 'application/javascript; charset=utf-8')
    break
    case '.json':
    case '.json5':
    case '.jsonc':
    response.setHeader ('Content-Type', 'application/json; charset=utf-8')
    default:
    response.setHeader ('Content-Type', 'text/plain; charset=utf-8')
    }

    return filePath
    }

    const readFile = cb => path => {
    fs.readFile (path, { encoding: 'utf-8' }, cb)
    return path
    }

    const payload = response => (error, data) => {
    if (error) {
    response.statusCode = 500
    response.end (JSON.stringify (error))
    } else {
    response.statusCode = 200
    response.end (String (data))
    }
    }

    const notAllowed = response => x => {
    response.statusCode = 403
    response.setHeader ('Content-Type', 'text/plain')
    response.end ('Not in allowed list')

    return x
    }

    // ---------------------------------------------->

    const hostname = '127.0.0.1'
    const port = 3000
    const allowed = {
    '/': path.resolve (__dirname, 'index.html'),
    '/text.txt' : path.resolve (__dirname, 'text.txt'),
    }

    const serve = (request, response) => {
    S.pipe ([
    S.flip (S.get (S.is ($.String))) (allowed),
    S.map (setContentType (response)),
    S.map (readFile (payload (response))),
    S.when (S.isNothing)
    (notAllowed (response)),
    ])
    (request.url)
    }

    const server = http.createServer (serve)

    server.listen (port, hostname, () => {
    console.log (`Server running at http://${hostname}:${port}/`)
    })