The magic_mime() function just returns a MIME type string based on the file extension, there's nothing clever here, the file is never tested to see if it really is what it says it is but it gives a quick way of deciding if something is an html file or a stylesheet when serving real files.
post2dict() function takes a POST form that's been effectively URL encoded (this wouldn't work for multipart/form data types) and returns the elements as a Python dictionary with any escape characters put back to their literals.
The listener() function does the main work, after setting up the socket to listen on it goes into an infinite loop, waiting for connections. Each connection is handled serially, so don't expect this to deal with running a real website, if someone has connected to it and is waiting for a page it will just ignore any more attempts to connect.
Receiving data from a TCP socket isn't as easy as reading a file, there's no indication when you've got it all (you could just set a timeout and wait a long time but that's slow), and you have to read it in chunks because of the way the underlying buffer structure is built. To do it right, you need to read all of the HTTP headers, take note of the "Content-Length" header which tells you how much extra data (POST form data for example) is after the headers. The end of the headers is defined as a blank line so after receiving the first buffer full of data my code goes into an infinite loop with a "break" if it finds a complete line blank (i.e. two newlines with only white space between). After that is a simple byte counting loop until all the form data is received.
Once a full request is received, the code decides what to do with it, this is done primarily based on the URL requested.
This is the "do it" URL, you send your code to this URL in a POST request. This causes it to dump your code to a temporary file and then calls a separate instance of Python using the subprocess module to run the logo_interp.py interpreter. If you request the page when the subprocess is still running it serves up a page that just says "Running..." at the moment, I'm thinking a nice highlighted version of the code showing you where it's got to would be a better page to return here. The "Running..." page has a meta-refresh tag set in the HTML, this causes it to keep refreshing the page automatically every 5 seconds, if the process has finished the server redirects the request to the index page so you can go back to editing the code.
If the request is the name of a real file that was stored when the server was started, the server looks up the file type with
Like most web servers if you access the root page it serves up "index.html" from the public folder. It fills in the code field with the text of the last program run though so if you just ran a program and got redirected back here after it finished you can start editing instead of having to save your code on your local machine.
If none of the handled URLs have matched the server responds with a 404 page of course.
Hand coding all this with such low level constructs as the socket library and string operations is not a very modder friendly way to build code but it is very quick for me as I don't need to read documentation about other people's modules. It also keeps the dependencies down which can be handy when you are working on an embedded platform.
|Python source code||Aug. 26, 2014, 10:11 p.m.||4.2 KB|