Creating an HTTP Server to Handle POST Requests


import BaseHTTPServer, cgi class httpServHandler( \       BaseHTTPServer.BaseHTTPRequestHandler):     def do_POST(self):        self.query_string = self.rfile.read (int(self.headers['Content-Length']))        self.args = dict(cgi.parse_\                       qsl(self.query_string))        self.send_response(200)        self.send_header('Content-type', \                         'text/html')        self.end_headers()        sys.stdout = self.wfile        self.wfile.write( \            "<h2>Handling Post</h2><P>")        self.wfile.write( \            "<li>Location: <b>%s</b>"%(self.path))        self.wfile.write( \            "<li>Arguments:<b>%s</b><hr>"%                           (self.args))       execfile(self.path, self.args) serv = BaseHTTPServer.HTTPServer( \            servAddr, httpServHandler) serv.serve_forever()

A very common task when programming web services is to create web servers to handle special processing of POST requests from web browsers. The BaseHTTPServer module included with Python provides a set of classes and functions that allow you to create custom web servers to handle these requests.

The first step is to define a handler class derived from the BaseHTTPServer.BaseHTTPRequestHandler class that overrides the do_POST() method.

The first order of business inside the do_POST method is to get the arguments passed with the POST request. First, get the length of the content by accessing the value of the Content-Length key in the headers attribute of the handler object. When you know the size of the contents, read the query string from the rfile attribute into a buffer.

After you have the query string of the POST request in a buffer, use cgi.parse_qsl(string) to parse the query string into a dictionary, as shown in the example http_post_serv.py. The arguments will be added to the dictionary and can be accessed by using standard Python syntax.

Note

In the sample code, we are using the web server to remotely execute a Python script. We redirect the sys.stdout to the wfile attribute of the handler class so that normal output from the script executing will be displayed in the web browser.


After you have defined the handler class and overridden the do_POST method, create an instance of the web server using BaseHTTPServer.HTTPServer(address, handler). The address argument is a list including the server address and port, respectively. The handler argument is the custom handler class you defined earlier.

Once you have created an instance of the web server, start the web server by calling its serve_forever() function.

import os, sys import BaseHTTPServer, cgi servAddr = ('',80) #Define the HTTP handler that overrides do_POST class httpServHandler( \       BaseHTTPServer.BaseHTTPRequestHandler):     def do_POST(self): #Get arguments from query string         self.query_string = self.rfile.read( \             int(self.headers['Content-Length']))         self.args = dict(cgi.parse_ \                          qsl(self.query_string))         self.send_response(200)         self.send_header('Content-type', \                          'text/html')         self.end_headers() #Redirect output to browser         sys.stdout = self.wfile #Handle the post         self.wfile.write("<h2>Handling \             Post</h2><P>")         self.wfile.write("<li>Location: \             <b>%s</b>"%(self.path))         self.wfile.write("<li>Arguments: \             <b>%s</b><hr>"%(self.args)) #Execute the script remotely         execfile(self.path, self.args) #Set the root directory os.chdir('/myTest') #Create server object serv = BaseHTTPServer.HTTPServer( \            servAddr, httpServHandler) #Start Server serv.serve_forever()


http_post_serv.py

<!DOCTYPE html> <html lang="en"> <head> <meta content="text/html; charset=utf-8" http-equiv="content-type"/> <title>Form Page</title> </head> <body> <form method="POST" action=  "http://testserver.net/myTest/http_text.py">     Name <input type="TEXT" name="name">     <p>     Quote <input type="TEXT" NAME="quote" size="80">     <p>     <input type="SUBMIT" value="send"> </form> </body> </html>


post_form.html

if name and quote:     print "<b>%s</b> says <i>%s</i>"% (name, quote) else:     print "There were errors in the parameters."


http_text.py

Figure 10.8 shows post_form.html displayed in a web browser.

Figure 10.8. Web browser view of post_form.html code.


Figure 10.9 shows the web page generated by http_post_serv.py when it receives a POST request.

Figure 10.9. Output HTML page created by http_post_serv.py code.




Python Phrasebook(c) Essential Code and Commands
Python Phrasebook
ISBN: 0672329107
EAN: 2147483647
Year: N/A
Pages: 138
Authors: Brad Dayley

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net