< BACKMake Note | BookmarkCONTINUE >
156135250194107072078175030179198180025031194137176049106218111004226053241016190125213244

Web (HTTP) Servers

Until now, we have been discussing the use of Python in creating Web clients and performing tasks to aid Web servers in CGI request processing. We know (and have seen earlier in Sections 19.2 and 19.3) that Python can be used to create both simple and complex Web clients. Complexity of CGI requests goes without saying.

However, we have yet to explore the creation of Web servers, and that is the focus of this section. If the Netscape, IE, Opera, Mozilla, and Lynx browsers are among the most popular Web clients, then what are the most common Web servers? They are Apache, Netscape, and IIS. In situations where these servers may be overkill for your desired application, we would like to use Python to help us create simple yet useful Web servers.

Creating Web Servers in Python

Since you have decided on building such an application, you will naturally be creating all the custom stuff, but all the base code you will need is already available in the Python Standard Library. To create a Web server, a base server and a "handler" are required.

The base (Web) server is a boilerplate item, a must have. Its role is to perform the necessary HTTP communication between client and server. The base server is (appropriately) named HTTPServer and is found in the BaseHTTPServer module.

The handler is the piece of software which does the majority of the "Web serving." It processes the client request and returns the appropriate file, whether static or dynamically-generated by CGI. The complexity of the handler determines the complexity of your Web server. The Python standard library provides three different handlers.

The most basic, plain, vanilla handler, named BaseHTTPRequestHandler, is found in the BaseHTTPServer module, along with the base Web server. Other than taking a client request, no other handling is implemented at all, so you have to do it all yourself, such as in our myhttpd.py server below.

The SimpleHTTPRequestHandler, available in the SimpleHTTP-Server module, builds on BaseHTTPRequestHandler by implementing the standard GET and HEAD requests in a fairly straightforward manner. Still nothing sexy, but it gets the simple jobs done.

Finally, we have the CGIHTTPRequestHandler, available in the CGIHTTPServer module, which takes the SimpleHTTPRequestHandler and adds support for POST requests. It has the ability to call CGI scripts to perform the requested processing and can send the generated HTML back to the client.

The three modules and their classes are summarized in Table 19-6.

Table 19.6. Web Server Modules and Classes

Module

Description

BaseHTTPServer

provides the base Web server and base handler classes, HTTPServer and BaseHTTPRequestHandler, respectively

SimpleHTTPServer

contains the SimpleHTTPRequestHandler class to perform GET and HEAD requests

CGIHTTPServer

contains the CGIHTTPRequestHandler class to process POST requests and perform CGI execution

To be able to understand how the more advanced handlers found in the SimpleHTTPServer and CGIHTTPServer modules work, we will implement simple GET processing for a BaseHTTPRequestHandler. In Example 19-7, we present the code for a fully working Web server, myhttpd.py.

This server subclasses BaseHTTPRequestHandler and consists of a single do_GET() method, which is called when the base server receives a GET request. We attempt to open the path passed in by the client and if present, return an "OK" status (200) and forward the downloaded Web page. If the file was not found, returning a 404 status.

The main() function simply instantiates our Web server class and invokes it to run our familiar infinite server loop; shutting it down if interrupted by ^C or similar keystroke. If you have appropriate access and can run this server, you will notice that it displays loggable output which will look something like:

Example 19.7. Simple Web Server (myhttpd.py)

This simple Web server can read GET requests, fetch a Web page (.html file) and return it to the calling client. It uses the BaseHTTPRequestHandler found in BaseHTTPServer and implements the do_GET() method to enable processing of GET requests

 <$nopage>
001 1   #!/usr/bin/env python
002 2
003 3   from os import curdir, sep
004 4   from BaseHTTPServer import \
005 5                BaseHTTPRequestHandler, HTTPServer
006 6
007 7   class MyHandler(BaseHTTPRequestHandler):
008 8
009 9       def do_GET(self):
010 10          try: <$nopage>
011 11              f = open(curdir + sep + self.path)
012 12              self.send_response(200)
013 13              self.send_header('Content-type',
014 14                                     'text/html')
015 15              self.end_headers()
016 16              self.wfile.write(f.read())
017 17              f.close()
018 18          except IOError:
019 19              self.send_error(404, \
020 20                  'File Not Found: %s' % self.path)
021 21
022 22  def main():
023 23      try: <$nopage>
024 24          server = HTTPServer(('', 80), MyHandler)
025 25          print 'Welcome to the machine…',
026 26          print 'Press ^C once or twice to quit.'
027 27          server.serve_forever()
028 28      except KeyboardInterrupt:
029 29          print '^C received, shutting down server'
030 30          server.socket.close()
031 31
032 32  if __name__ == '__main__':
033 33      main()
034  <$nopage>
						
# myhttpd.py
Welcome to the machine... Press ^C once or twice to quit
localhost - - [26/Aug/2000 03:01:35] "GET /index.html
HTTP/1.0" 200 -
localhost - - [26/Aug/2000 03:01:29] code 404, message
File Not Found: /dummy.html
localhost - - [26/Aug/2000 03:01:29] "GET /dummy.html
HTTP/1.0" 404 -
localhost - - [26/Aug/2000 03:02:03] "GET /hotlist.htm
HTTP/1.0" 200 -

					

Of course, our simple little Web server is so simple, that it cannot even process plain text files. We leave that as an exercise for the reader, which can be found at the end of the chapter.

As you can see, it doesn't take much to have a Web server up and running in pure Python. There is plenty more you can do to enhance the handlers to customize it to your specific application. Please review the Library Reference for more information on these modules (and their classes) discussed in this section.


Last updated on 9/14/2001
Core Python Programming, © 2002 Prentice Hall PTR

< BACKMake Note | BookmarkCONTINUE >

© 2002, O'Reilly & Associates, Inc.