WebFund 2024F: Tutorial 2: Difference between revisions

From Soma-notes
No edit summary
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''This tutorial is not yet finalized.'''
In this tutorial you'll be playing with [http://homeostasis.scs.carleton.ca/~soma/webfund-2024f/code/simpleserver.js simpleserver.js], a static file webserver in Deno that has no external dependencies.
In this tutorial you'll be playing with [http://homeostasis.scs.carleton.ca/~soma/webfund-2024f/code/simpleserver.js simpleserver.js], a static file webserver in Deno that has no external dependencies.


Line 6: Line 4:


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 [http://homeostasis.scs.carleton.ca/~soma/webfund-2016w/code/hello.html 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.)
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 [http://homeostasis.scs.carleton.ca/~soma/webfund-2016w/code/hello.html 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.)
Remember you can edit files remotely in the VM using [https://carleton.ca/scs/2023/vscode-remote-access-and-code-editing/ VSCode] or Emacs!


==Questions==
==Questions==
Line 13: Line 13:


==Tasks==
==Tasks==
# 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.)
# Change simpleserver to use the standard Deno <tt>contentType</tt>. What code should this replace? You can import it by adding this code: <tt>import { contentType } from "jsr:@std/media-types";</tt>
# 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!)''
# Change simplserver 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.)
# Change simpleserver to retrieve the file <tt>index.html</tt> when a directory is accessed. What sort of functionality does this enable?
# Change simpleserver 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!)''
# Change simpleserver so that when there is a request for the file "number5", it returns a simple page or text file that says "The number is 5!". It should work when any positive integer is used instead of 5.


==Code==
==Code==

Latest revision as of 15:03, 24 September 2024

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.)

Remember you can edit files remotely in the VM using VSCode or Emacs!

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 simpleserver to use the standard Deno contentType. What code should this replace? You can import it by adding this code: import { contentType } from "jsr:@std/media-types";
  2. Change simplserver 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.)
  3. Change simpleserver to retrieve the file index.html when a directory is accessed. What sort of functionality does this enable?
  4. Change simpleserver 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!)
  5. Change simpleserver so that when there is a request for the file "number5", it returns a simple page or text file that says "The number is 5!". It should work when any positive integer is used instead of 5.

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);