Sometimes I give hands-on tutorials which involve a number of people working with examples that come from a webserver, and typically involve writing to and reading from the webserver. Although there are solutions that involve installing a server and database, and setting up accounts for everyone to log in, this can be time consuming, and involve a lot of administration.
To avoid the administration, I created a very simple webserver, xcontents (the name is a joke on Form and Content) where tutees would copy the website files to their machine, and install and use the webserver to access the files, where they could use any HTTP method, including GET, HEAD, PUT, POST, and DELETE to manage the files.
This was still somewhat inconvenient, because I had to explain what they had to do, the students had to do that work, and I had to keep several binaries available for the different computers they might use, with an additional difficulty that one anti-virus system saw one of those binaries as a virus.
So what I have now done is create a new version, xcontents2, that runs on a single machine, but makes it look like everyone using it has independent, unique access to the files, with no copying, no installing, no accounts, no logging in, but identical effect to the earlier version.
The server works in two modes: normal, and tutorial.
In normal mode it allows all the usual actions in the normal way: from the directory it is started in you can do GET, HEAD, PUT, POST (but not DELETE) on files in that directory and lower. This is the normal mode for the tutor(s) to prepare the website as necessary, using a Web editor with PUT/XForms/etc.
In tutorial mode, anyone can use it, there is no logging in, no administration, and it gives the appearance that they can edit or add any files they like in the whole site (startup directory and below). They can also DELETE any file they have edited or created (if they edit a file that was already on the site, deleting it returns it to its initial state, but the original file cannot be deleted).
In fact they are only working on shadow copies: editing a file, even the root index.html file, when saved is silently saved in a different location, and if that user then views it, it appears to have overwritten the original (it hasn't). No one else can see other users' changes or additions.
The only method that needs explaining is POST:
<post>...</post>.Therefore, if you don't like the tags <post>...</post> when the
file is created, you can first either PUT an empty file, or one containing only
the open and closing tags you want, e.g.
<data></data>, before you POST to it.
This is done so that if the user is POSTing XML documents, the resulting file is still a well-formed XML document.
(For information: original server ~500 lines of C, new server ~1000 lines).
It uses regular port numbers by default, but may be given a port number to use in the command line.
The server only reads and writes files in the directory it is started in and its subdirectories.
In requests to the server, if the path in the URL contains "/../" or ends with "/.." a 400 "Bad request" is returned.
If the resource URL ends in a slash "/", then "index.html" is appended.
There are two modes of working: "normal" and "tutorial". Tutorial mode is
started by the -t flag on the command line.
Normal mode works relative to the start-up directory, with no use of a cookie; DELETE is not allowed.
In normal mode, the methods work as follow:
If the file does not exist, it is created, with the submission content surrounded by the tags <post>...</post>.
If the file exists, the content is appended before the last closing XML tag, if the file ends with one, and otherwise at the end of the file, with a preceeding newline character.
Mediatypes are based on the file extension, the following:
.txt text/plain.html text/html.css text/css.xml text/xml.xsd text/xml.xsl text/xsl.xhtml application/xhtml+xml.js application/javascript.gif image/gif.jpg image/jpeg.png image/png.svg image/svg+xmlThese are read from the file mediatypes.txt, which can be added
to.
There is one cookie called xcontents: its value represents the
name of a direct subdirectory of the start-up directory.
If the cookie is not set:
If the cookie is set, but the subdirectory doesn't exist, the cookie is deleted, and processing proceeds as if the cookie hadn't been set.
If the cookie is set, and the directory exists,
Source: xcontents.c mediatypes.txt
gcc -O2 -Wall -o xcontents xcontents.c -lssl -lcrypto
cd web-root-directory xcontents [-t] [-p http_port] [-s https_port] [-c cert.pem] [-k key.pem] [-m mediatypes]
Acceptable media-types, and their mapping to file extensions are stored in
the file mediatypes.txt; a different
location can be specified with the -m parameter.
For https, it expects by default files called cert.pem and
key.pem in the root directory; you can supply different names with
the -c and -k parameters. If it doesn't find the
files, https is not used. These two files are never served.
The flag -t runs the server in tutorial mode.
It is strongly recommended to do a setuid with chmod
+s on the server binary, and a chown to a suitably harmless user (for
instance by creating a special user just for the server). That way, it won't
have permissions to overwrite files that don't belong to it.