web status display for long running program
Kamilche
klachemin at comcast.net
Fri Feb 25 02:26:31 EST 2005
Cute! Thanks for posting that. I too like the 'web interface' concept,
it has made SmoothWall a pleasure to use, even on older machines.
I was inspired to enhance your code, and perform a critical bug-fix.
Your code would not have sent large files out to dialup users, because
it assumed all data was sent on the 'send' command. I added code to
check for the number of bytes sent, and loop until it's all gone. I
also turned it into a class, and made it 'command' based.
Have fun with it, Brian!
'''
miniweb: microscopic web server by Peter Hansen
This is a simple web server that handles one request at
a time. Therefore, it's useful mainly for administrative
tasks that have one person connected at a time.
It doesn't actually serve pages, it executes commands
based on the web page you request. The commands it
currently includes are:
time - Send the time
header - Echo back the original header
largefile - Test sending a large file back to the person
quit - Shut down the web server
To add more commands, add new functions prefixed with
'request_' similar to the sample functions below.
As you add functions, the menu choices displayed to
the user are automatically updated.
I fixed the 'send' feature so it could send large files.
Before, it would send the first X bytes, then stop
without checking to make sure all bytes were went.
I also made it a class, created the 'command based'
feature, and added the auto-updating menu choices.
Have fun with it!
--Kamilche
'''
import socket
import select
import datetime
_HEADER = '\r\n'.join([
'HTTP/1.0 %s',
'Server: Miniweb-0.1',
'Content-Type: text/html',
'Connection: close',
'Content-Length: %d',
'',
'',
])
_BODY = '\r\n'.join([
'<html><head><title>%s</title></head>',
'<body><h3>%s</h3>\r\n%s\r\n</body></html>',
])
_QUIT = False
class WebServer(object):
def __init__(self, port):
' Start listening on the specified port'
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind(('', port))
self.socket.listen(5)
' Build the list of menu choices'
self.menu = '<pre>\n'
for key, value in self.__class__.__dict__.items():
if key[:8] == 'request_':
self.menu += "%-10s- %s\r\n" % (key[8:], value.__doc__)
self.menu += '</pre>\n'
def Timer(self):
' Process new requests'
r, w, e = select.select([self.socket], [], [], 0.0)
if not r:
return
cs = self.socket.accept()[0]
header = ''
while not '\r\n\r\n' in header:
r, w, e = select.select([cs], [], [cs], 2.0)
if not r or e:
break
header += cs.recv(1024)
status = '200 OK'
title = "Miniweb!"
if not '\r\n\r\n' in header:
status = '408 Request Timeout'
body = ['Your request was not received in time.']
else:
lines = header.split('\r\n')
words = lines[0].split(' ')
request = ' '.join(words[1:-1])
request = request[1:]
if request == '':
fn = self.default
else:
fn = getattr(self, 'request_' + request, None)
if not fn:
status = '404 Not Found'
fn = self.notfound
body = fn(header, request)
body = _BODY % (title, title,
''.join([str(arg) for arg in body]))
header = _HEADER % (status, len(body))
data = header + body
while len(data) > 0:
cc = cs.send(data)
data = data[cc:]
cs.close()
def default(self, header, request):
' Print the available choices'
return ('Welcome to Miniweb!',
'Available commands are:<p>',
self.menu)
def notfound(self, header, request):
' Handle unknown requests'
return ('Unknown request <pre>', request, '</pre>',
'Your header was:<br><pre>', header, '</pre>',
'Available commands are:<p>', self.menu)
def request_time(self, header, request):
' Send the time'
return ('The time is ', datetime.datetime.now(), '<p>')
def request_header(self, header, request):
' Echo back the original header'
return ('Your header was:<br><pre>', header, '</pre>')
def request_largefile(self, header, request):
' Test sending a large file back to the person'
temp = ['<pre>\r\n']
for i in range(10000):
temp.append("This is line %d of the result.\r\n" % i)
temp.append('</pre>')
return temp
def request_quit(self, header, request):
' Shut down the web server'
global _QUIT
_QUIT = True
return ('Web server shut down at ', datetime.datetime.now())
def main():
' Main loop'
server = WebServer(80)
while not _QUIT:
server.Timer()
print "Done!"
main()
More information about the Python-list
mailing list