Ian Clelland
ian at veryfresh.com
Wed Mar 20 17:31:10 EST 2002
I have been experimenting with mod_python to evaluate it for some upcoming projects, and I recently came across what appeared to be a bug in mod_python. (After three days of scratching my head over this, the solution came to me as I was writing this message, but I'm sending it anyway in case someone else comes across this problem. -- Should this sort of thing go into the FAQ?) The problem was essentially that whenever I performed a GET request on a URL immediately following a POST request to that same URL, Apache would seem to confuse the two requests, and after the GET, I would receive an error message like this: HTTP/1.1 501 Method Not Implemented key=valueGET to /pytest not supported Invalid method in request key=valueGET /pytest Running tcpdump on the communication between the browser and server showed that the requests were all well-formed, and there was nothing unusual in the headers to suggest that anything but Apache/mod_python was at fault. The simplest script I could produce to replicate the problem was this: # ------------------------------------------------------------------- import sys from mod_python import apache def handler(req): if req.method == 'GET': req.content_type = "text/html" req.send_http_header() req.write("""<html> <head> <title>python test</title> </head> <body> <form method=\"post\" action=\"/pytest\"> <input name=\"key\" value=\"value\"> <input type=\"submit\"> </form> </body> </html> """) return apache.OK elif req.method == 'POST': req.content_type = "text/html" req.send_http_header() req.write("""<html> <head> <title>python test part 2</title> </head> <body> <p>POST successful. <a href=\"/pytest\">Click here</a></p> </body> </html> """) return apache.OK else: return apache.DECLINED # ------------------------------------------------------------------- It was supported by these Apache configuration directives: <Location "/pytest"> SetHandler python-program PythonPath "sys.path+['/home/ian/src/pytest']" PythonHandler python_test </Location> The script is accessable from the virtual URL /pytest, which runs the python_test.py module from a non-web-accessable directory. Going to the URL /pytest in Mozilla, hitting the submit button, then clicking on the 'Click here' link brings up the error message. The problem with this code (as it became apparent to me while writing this message) is that the POST handler never actually reads the POST data, and so it stays on stdin, and Apache treats it as the beginning of the next request. Simply inserting the line 'postdata = req.read()' gets rid of the error. Questions: Is this the correct behaviour for mod_python? Is it the python module writer's responsibility to read all POST data in all situations? What if the data is very large (say, a 5MB file when I expected a small text field) and I just want to discard it? Ian <ian at veryfresh.com>
|