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

Posted in: Code by nsundin
Copyright © 2011-2025 Programmatic Verse · RSS Feed
Built on Skeleton
Powerered by Wordpress