Created
September 14, 2015 00:07
-
-
Save Ulu2005/99704339fdd0c59aed78 to your computer and use it in GitHub Desktop.
Lisod prototype
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import datetime | |
import BaseHTTPServer | |
import SocketServer | |
# hard-coded configurtion | |
WWW = '/tmp/www/' | |
PORT = 8080 | |
MIME = { | |
'.html' : 'text/html', | |
'.css' : 'text/css', | |
'.png' : 'image/png', | |
'.jpg' : 'image/jpeg', | |
'.gif' : 'image/gif' | |
} | |
# This is the 'select()' module---except we aren't showing it here | |
# or actually implementing it properly | |
class LisoPrototype(BaseHTTPServer.HTTPServer): | |
pass | |
# This is the HTTP/1.1 parsing module---except we don't show parsing | |
# only forming responses with the proper headers etc. | |
class LisoHandlerPrototype(BaseHTTPServer.BaseHTTPRequestHandler): | |
def return404(self): | |
self.send_error(404, 'Not Found') | |
def return411(self): | |
self.send_error(411, 'Length Required') | |
def return500(self): | |
self.send_error(500, 'Not Found') | |
def return505(self): | |
self.send_error(505, 'HTTP Version not supported') | |
def check_HTTP_version(self): | |
version = self.request_version.split('/') | |
version = version[1].split('.') | |
if version[0] != '1' or version[1] != '1': | |
self.return505() | |
return None | |
def do_GET(self): | |
self.check_HTTP_version() | |
# understand requested object/URI | |
URI = self.path | |
full_path = os.path.normpath(WWW + URI) | |
if os.path.isdir(full_path): | |
full_path = os.path.join(full_path, 'index.html') | |
if not os.path.exists(full_path): | |
self.return404() | |
return | |
message_body = '' | |
basename,extension = os.path.splitext(full_path) | |
# read in full file | |
try: | |
datestring = os.path.getmtime(full_path) | |
with open(full_path, 'r') as f: | |
message_body = f.read() | |
except IOError: | |
self.return_500() | |
return | |
# format datestring | |
datestring = datetime.datetime.utcfromtimestamp(datestring) | |
datestring = datestring.strftime('%a, %d %b %Y %H:%M:%S GMT') | |
# get proper mimetype | |
try: | |
mimetype = MIME[extension.lower()] | |
except KeyError: | |
mimetype = 'application/octet-stream' | |
# send response; Server and Date headers auto-generated | |
self.send_response(200, 'OK') | |
self.send_header('Connection', 'close') | |
self.send_header('Content-Type', mimetype) | |
self.send_header('Content-Length', len(message_body)) | |
self.send_header('Last-Modified', datestring) | |
self.end_headers() | |
self.wfile.write(message_body) | |
self.close_connection = 1 # hack for multi-connection browsers | |
# the server above us is dumb; that's why this hack is needed | |
def do_HEAD(self): | |
self.check_HTTP_version() | |
# understand requested object/URI | |
URI = self.path | |
full_path = os.path.normpath(WWW + URI) | |
if os.path.isdir(full_path): | |
full_path = os.path.join(full_path, 'index.html') | |
if not os.path.exists(full_path): | |
self.return404() | |
message_body = '' | |
basename,extension = os.path.splitext(full_path) | |
# get stats | |
datestring = os.path.getmtime(full_path) | |
fsize = os.path.getsize(full_path) | |
# format datestring | |
datestring = datetime.datetime.utcfromtimestamp(datestring) | |
datestring = datestring.strftime('%a, %d %b %Y %H:%M:%S %Z') | |
# get proper mimetype | |
try: | |
mimetype = MIME[extension.lower()] | |
except KeyError: | |
mimetype = 'application/octet-stream' | |
# send response; Server and Date headers auto-generated | |
self.send_response(200, 'OK') | |
self.send_header('Connection', 'close') | |
self.send_header('Content-Type', mimetype) | |
self.send_header('Content-Length', fsize) | |
self.send_header('Last-Modified', datestring) | |
self.end_headers() | |
self.close_connection = 1 | |
def do_POST(self): | |
self.check_HTTP_version() | |
if 'Content-length' not in self.headers: | |
return411() | |
return | |
self.send_response(200, 'OK') | |
self.send_header('Connection', 'close') | |
self.end_headers() | |
self.close_connection = 1 | |
def run(): | |
handler = LisoHandlerPrototype | |
# set version strings for auto-generated Server header amd response | |
handler.server_version = 'Liso/1.0' | |
handler.sys_version = '' | |
handler.protocol_version = 'HTTP/1.1' | |
# server startup | |
server_address = ('0.0.0.0', PORT) | |
httpd = LisoPrototype(server_address, handler) | |
httpd.serve_forever() | |
if __name__ == '__main__': | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment