[jToolkit-cvs] jToolkit/web simplewebserver.py,NONE,1.1
Brought to you by:
davidfraser,
friedelwolff
From: <dav...@us...> - 2003-12-02 08:17:04
|
Update of /cvsroot/jtoolkit/jToolkit/web In directory sc8-pr-cvs1:/tmp/cvs-serv12441 Added Files: simplewebserver.py Log Message: added simple web server for serving files without apache --- NEW FILE: simplewebserver.py --- #!/usr/bin/python2.2 """a simple web server so you don't have to run your app from inside Apache etc. mostly useful for testing / small setups""" # Copyright 2002, 2003 St James Software # # This file is part of jToolkit. # # jToolkit is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # jToolkit is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with jToolkit; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import BaseHTTPServer import urllib import posixpath import cgi import sys import os from jToolkit.web import getserver from jToolkit.web import httpcodes from jToolkit.widgets import widgets runforever = 1 server = getserver("jLogbook.python.config", "Demo") def run(server_class=BaseHTTPServer.HTTPServer, handler_class=BaseHTTPServer.BaseHTTPRequestHandler, port=9980): server_address = ('', port) httpd = server_class(server_address, handler_class) if runforever: # this means the server has to be interrupted manually... httpd.serve_forever() else: # otherwise, only handle one request, to aid debugging httpd.handle_request() class jToolkitHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): # methods based on *.webserver # TODO: inherit from something appropriate... def reset_response(self): self.sent_response = 0 protocol_version = "HTTP/1.1" def send_response_normal(self): """set up for a normal process""" # TODO: change this to a constant self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() def send_response_unauthorized(self, realm): # hold back the message till later... # TODO: change this to a constant self.send_response(401, 0) self.send_header("WWW-Authenticate", "Basic realm=%s" % repr(realm)) # now we can send the message... self.send_response_message(401) def writeline(self, line): """writes a line back to the client...""" # if no response yet, tell them we're OK if not self.sent_response: self.send_response_normal() self.wfile.write(line+'\n') # stuff based on BaseHTTPServer server_version = 'jToolkitHTTP/0.1' def log_message(self, format, *args): """Log an arbitrary message. This is used by all other logging functions. Override it if you have specific logging wishes. The first argument, FORMAT, is a format string for the message to be logged. If the format string contains any % escapes requiring parameters, they should be specified as subsequent arguments (it's just like printf!). The client host and current date/time are prefixed to every message. """ if not hasattr(self,'authuser'): self.authuser = '-' sys.stderr.write("%s - %s [%s] %s\n" % (self.address_string(), self.authuser, self.log_date_time_string(), format%args)) def do_GET(self): """Serve a GET request""" self.authuser = '-' querypos = self.path.find('?') if '?' != -1: path = self.path[:querypos] querystring = self.path[querypos+1:] argdict = cgi.parse_qs(querystring, 1, 0) else: path = self.path argdict = {} path = posixpath.normpath(urllib.unquote(path)) pathwords = filter(None, path.split('/')) # split into bits, strip out empty strings if len(pathwords) > 0 and pathwords[-1] == '.': pathwords = pathwords[:-1] sys.stderr.write("%r %r %r\n" % (path, pathwords, argdict)) # forget if we've served a response previously... self.reset_response() thepage = server.handle(self, pathwords, argdict) # session = server.getsession(self, argdict, None) # thepage = server.getpage(pathwords, session, argdict) self.sendpage(thepage) def sendpage(self, thepage): """sends the page back to the user""" # TODO: refactor this into jToolkit.web.server? if isinstance(thepage, widgets.Widget): # get the content type... if hasattr(thepage,'content_type'): content_type = thepage.content_type else: content_type = "text/html" response = thepage.gethtml() # return the html response (whether customized or standard) self.send_response(200) self.send_header("Content-type", content_type) self.end_headers() if type(response) == unicode: # TODO: get encoding from http request... self.wfile.write(response.encode('iso8859')) else: self.wfile.write(response) elif thepage is None: return self.send_response(404) # safeapache.apache.DECLINED else: # a non-widget means a return code... actually an integer, not a page return self.send_response(thepage) # safeapache.apache.DECLINED def do_POST(self): """Serve a POST request""" self.authuser = '-' contenttype = self.headers.gettype() if contenttype <> 'application/x-www-form-urlencoded': # check this self.send_response(501) self.end_headers() return contentlength = int(self.headers.getheader('Content-Length')) querystring = self.rfile.read(contentlength) argdict = cgi.parse_qs(querystring, 1, 0) path = posixpath.normpath(urllib.unquote(self.path)) pathwords = filter(None, path.split('/')) # split into bits, strip out empty strings # forget if we've served a response previously... self.reset_response() thepage = server.handle(self, pathwords, argdict) self.sendpage(thepage) def logpid(): pidfile = os.getenv('jtoolkit_pid_file') if pidfile is None: pidfile = "jtoolkit.pid" pid = os.getpid() f = open(pidfile,'w') f.write('%d' % pid) f.close() if __name__ == '__main__': # run the web server if "-B" in sys.argv: del sys.argv[sys.argv.index("-B")] # fork into background import os if os.fork(): # exit the parent sys.exit() # log the pid... logpid() if "-o" in sys.argv: oindex = sys.argv.index("-o") ofile = sys.argv[oindex+1] del sys.argv[oindex] del sys.argv[oindex] # print "writing to %r" % ofile sys.stdout = open(ofile,'a') sys.stderr = sys.stdout print "remaining args: %r" % sys.argv if len(sys.argv) > 1: port = int(sys.argv[1]) run(handler_class=jToolkitHTTPRequestHandler,port=port) else: run(handler_class=jToolkitHTTPRequestHandler) |