I wrote most of the following script, useful for retrieving pages from the
web and serving web pages. Since it is so low level, it is much more
customizable than simpleHTTPserver, cgiHTTPserver, urllib, or urllib2 for
advanced users. For example, you can easily set your own headers when
retrieving and serving pages, such as the User-Agent header which you cannot
set in either urllib or urllib2.

(sorry for not putting in any comments!)

By the way, I just threw this together quickly, and haven't really had time
to test retrieve() very much. Please let me know if it is buggy.
I guess I should also write a dictToQuery() function. Oh well.


import socket

host,port='',80

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind((host,port))
sock.listen(1)

def serve(function=lambda *args:(args[2],200,'OK',{},'')):
    """\
def serve(function(method,filename,httpversion,headers,get,post))

    Serves one request, calling function() with the above
    parameters. function() must return (httpversion,code,
    accepted,headers,content) in that order. If you don't
    pass a function, then
    function=lambda *args:(args[2],200,'OK',{},'')
"""

    csock,caddr=sock.accept()
    rfile=csock.makefile('r',0)
    wfile=csock.makefile('w',0)

    # Protocol exchange - read request
    headers={}
    line=rfile.readline().strip()
    split1=line.find(' ')
    method,remainder=line[:split1].strip(),line[split1+1:].strip()
    split2=remainder.find(' ')

filename,httpversion=remainder[:split2].strip(),remainder[split2+1:].strip()
    while 1:
        line=rfile.readline().strip()
        print line
        if line=='':
            break
        else:
            split=line.find(':')
            key,value=line[:split],line[split+1:]
            headers[key.strip()]=value.strip()

    try:
        post=rfile.read(int(headers['Content-Length']))
    except:
        post=''
    get=queryToDict(filename)
    post=queryToDict(post)
    loc=filename.find("?")
    if loc>-1:
        filename=filename[:loc]
    print "get:",`get`
    print "post:",`post`

httpversion,code,accepted,headers,content=function(method,filename,httpversion,headers,get,post)
    wfile.write("%s %s %s\n"%(httpversion,code,accepted))
    for header in list(headers):
        wfile.write("%s: %s\n"%(header,headers[header]))
    wfile.write("\n%s\n"%content)
    wfile.close()
    csock.close()

def
retrieve(host,port=80,method='GET',filename='/',httpversion='HTTP/1.0',headers={},post=''):
    """\
Retrieves one web page from:
    http://host:port/filename
with the headers
"""
    sock.connect((host,port))
    rfile=sock.makefile('r',0)
    wfile=sock.makefile('w',0)
    wfile.write("%s %s %s\n"%(method,filename,httpversion))
    for header in list(headers):
        wfile.write("%s: %s\n"%(header,headers[header]))
    wfile.write('\n')
    wfile.write("%s\n"%post)

    headers={}
    line=rfile.readline().strip()
    split1=line.find(' ')
    httpversion,remainder=line[:split1].strip(),line[split1+1:].strip()
    split2=remainder.find(' ')
    code,accepted=remainder[:split2].strip(),remainder[split2+1:].strip()
    while 1:
        line=rfile.readline().strip()
        if line=='':
            break
        else:
            split=line.find(':')
            key,value=line[:split],line[split+1:]
            headers[key.strip()]=value.strip()
    return httpversion,code,accepted,headers,rfile

def queryToDict(query):
    if '?' in query:
        query=query[query.index('?')+1:]
    kvpairs=query.split("&")
    ret={}
    for kvpair in kvpairs:
        if '=' in kvpair:
            loc=kvpair.index('=')
            key,value=kvpair[:loc],kvpair[loc+1:]
            ret[key]=value
    return ret

if __name__=='__main__':
    i=0
    while True:
        i+=1
        print "\nserve #%d:"%i
        serve(lambda
*args:(args[2],200,'OK',{'Content-Type':'text/html'},'<h1>Go Away!</h1>'))

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to