See All Titles |
![]() ![]() Web (HTTP) ServersUntil 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 PythonSince 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.
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.
|
© 2002, O'Reilly & Associates, Inc. |