WebFund 2024F: Tutorial 2

From Soma-notes
Revision as of 04:52, 19 September 2024 by Soma (talk | contribs) (→‎Questions)

This tutorial is not yet finalized.

In this tutorial you'll be playing with simpleserver.js, a static file webserver in Deno that has no external dependencies.

Getting Started

To run it, just type "deno run --allow-net --allow-read simpleserver.js". It will begin serving on the web the pages in the same directory as the script. You'll want to have some files files to serve; to start off, try having it serve hello.html from class. Then, move on to saving pages from the web and serving those. (Note: they probably will be broken in some way by simpleserver.)

Questions

  1. What port is the web server listening on? How can you connect to it? Make sure you are on the Carleton VPN, or that you forward the correct port with the -L option, e.g. ssh -L 8000:localhost:8000 134.117.33.1
  2. What is returned when you access the top-level directory on the server? Why?
  3. How does simpleserver determine the MIME type of a file?

Tasks

  1. Change the server to serve files from /home/student/public_html rather than the current directory. Be sure to put some files in it! (Hint: you can grab HTML files from any webserver using wget or curl.)
  2. Change simpleserver.js so it returns a simple HTML error page in response to 404 errors (page not found). (Hint: Make sure you keep all your JavaScript and HTML files in the same folder!)

Code

simpleserver.js

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2024 Anil Somayaji
//
// simpleserver.js
// for COMP 2406 (Fall 2024), Carleton University
// 
// Initial version: Sept 18, 2024
//
// Originally inspired by Rod Waldhoff's tiny node.js webserver
//   https://github.com/rodw/tiny-node.js-webserver
//

function MIMEtype(filename) {

    const MIME_TYPES = {
        'css': 'text/css',
        'gif': 'image/gif',
        'htm': 'text/html',
        'html': 'text/html',
        'ico': 'image/x-icon',
        'jpeg': 'image/jpeg',
        'jpg': 'image/jpeg',
        'js': 'text/javascript',
        'json': 'application/json',
        'png': 'image/png',
        'txt': 'text/text'
    };

    var extension = "";
    
    if (filename) {
        extension = filename.slice(filename.lastIndexOf('.')+1).toLowerCase();
    }

    return MIME_TYPES[extension] || "application/octet-stream";
};

async function handler(req) {

    var metadata = {
        status: 200,
        contentType: "text/plain"
    }

    const pathname = "." + new URL(req.url).pathname;
    var contents;
    
    metadata.contentType = MIMEtype(pathname);

    try {
        contents = await Deno.readFile(pathname);
    } catch (e) {
        contents = null;
    }
    
    if (!contents) {
        contents = "File not found: " + pathname;
        metadata.contentType = "text/plain";
        metadata.status = 404;

        console.log("error on request for " + pathname);
    } else {
        console.log("returning " + pathname +
                    " of type " + metadata.contentType);
    }

    return new Response(contents, metadata);
}

Deno.serve(handler);