http_server_01
For those averse to using the easy-to-use BaseHTTPServer included with every Python distribution, this one’s for you. This was more fun and educational than useful. There is nothing like going out into the woods, chopping down some trees and crafting a server from scratch with your bare hands.
import socket import os import threading host = "192.168.1.46" port = 80 webdocs = "webdocs" binarytypes = [".jpg",".jpg",".gif",".ico",".png",".bmp"] def getDirSize(dirpath): totalsize = 0.0 for (path, dirs, files) in os.walk(dirpath): for file in files: totalsize += os.path.getsize(os.path.join(dirpath, file)) return totalsize # # #print "Folder = %0.1f MB" % (folder_size/(1024*1024.0)) class WebServer: def __init__(self, host, webdocs, port=80): self.server_threads = [] self.webdocs = webdocs self.host = host self.port = port self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) self.sock.bind((self.host,self.port)) self.sock.listen(1) print "HTTP server starting on host: %s port: %i" % (self.host, self.port) def StartServingLoop(self): while 1: #cull dead threads from list i = 0 while i<len(self.server_threads): if self.server_threads[i].isAlive(): i+=1 else: self.server_threads.pop(i) if self.server_threads: print self.server_threads csock,caddr = self.sock.accept() t = threading.Thread(target=self.HandleGet,args=(csock,)) self.server_threads.append(t) t.start() def getServerPath(self, get_path): get_path = get_path.replace("%20"," ") ## print "getServerPath(%s, %s)" % (webdocspath, get_path) rtn = self.webdocs+get_path if rtn.endswith("/"): rtn = rtn[:len(rtn)-1] ## print "getServerPath: returning '%s'" % rtn return rtn def getIndexFile(self, serverpath): dirList = os.listdir(serverpath) for item in dirList: if item == "index.html" or item == "index.htm": return item return None def getDirListing(self, get_path, serverpath): if get_path == "/": get_path = "" file_n_dirlisting = "" dirlist = os.listdir(serverpath) longestnamelen = 0 for itemname in dirlist: if len(itemname) > longestnamelen: longestnamelen = len(itemname) for itemname in dirlist: itempath = os.path.join(serverpath, itemname) hrefname = "%s/%s" % (get_path, itemname) if os.path.isfile(itempath): itemsize = os.path.getsize(itempath) elif os.path.isdir(itempath): itemsize = getDirSize(itempath) else: itemsize = 0 itemsizeK = itemsize/(1024.0) if itemsizeK < 1: itemsizestr = "%i B" %itemsize else: itemsizestr = "%0.1f K" % itemsizeK file_n_dirlisting+='<a href="%s">%s</a>%s%s</br>' % (hrefname, itemname, " "*(longestnamelen+50-(len(itemsizestr+itemname))), itemsizestr) file_n_dir_head = 'Name%sSize</br>' % (" "*(longestnamelen+50-(len("Size"+"Name")))) return "<h1>Index of %s</h1><br><pre>%s<hr>%s</pre>" % (get_path,file_n_dir_head, file_n_dirlisting) def HandleRequestOfDir(self, cfile, get_path, serverpath): idxfile = self.getIndexFile(serverpath) if idxfile: openedf = open(serverpath+"/"+idxfile,"r") cfile.write(openedf.read()) openedf.close() else: self.WriteServerInfoMessage(cfile,"Index of %s" % get_path, self.getDirListing(get_path,serverpath)) def HandleRequestOfFile(self, cfile, serverpath): if os.path.splitext(serverpath)[1] in binarytypes: openedf = open(serverpath,"rb") else: openedf = open(serverpath,"r") cfile.write(openedf.read()) openedf.close() def WriteServerInfoMessage(self,cfile,pagetitle,pagemessage): cfile.write("""<html><head> <title>%s</title> </head></body> %s <hr> <address>Nick's Python Server at %s Port %i</address> </body></html>""" % (pagetitle,pagemessage,self.host, self.port)) def HandleNotFound(self, cfile, get_path): self.WriteServerInfoMessage(cfile,"404 Not Found","<h1>Not Found</h1><p>The requested URL %s was not found on this server.</p>" % get_path) # "<h2>File not found</h2>" def HandleGet(self, csock): cfile = csock.makefile('rw',0) get_path = "" while 1: line = cfile.readline().strip() if line.startswith("GET"): get_path = line.split()[1] # print "wanting to get at %s" % get_path if line == '': serverpath = self.getServerPath(get_path) # print serverpath cfile.write("HTTP/1.0 200 OKnn") if os.path.isdir(serverpath): self.HandleRequestOfDir(cfile, get_path, serverpath) elif os.path.isfile(serverpath): self.HandleRequestOfFile(cfile, serverpath) else: self.HandleNotFound(cfile, get_path) cfile.close() csock.close() break server = WebServer(host,webdocs) server.StartServingLoop()