[mod_python] Trouble fetching POST arguments

Graham Dumpleton grahamd at dscpl.com.au
Wed Mar 16 22:00:54 EST 2005


Are you going direct to the server, or via a web proxy? Just a thought.
I have never heard of web proxies change POST requests to GET, but
I have had problems with web proxy caches before. This is why I
tend to explicitly use:

  req.headers_out['Pragma'] = 'no-cache'
  req.headers_out['Cache-Control'] = 'no-cache'
  req.headers_out['Expires'] = '-1'

When a handler is processing forms, whether it be GET or POST.

Graham

Davin Boling wrote ..
> I had already established that the method type is somehow getting 
> switched in the non-working handler. As much as it's hell-bent to force
> me to use a GET for my form, I'd much rather figure out why it's forcing
> a GET when I'm telling it to use a POST.
> 
> 
> 1) I can make a script from scratch that accepts a POST operation just
> fine. That's the one that I provided a moment ago.
> 2) req.read() isn't working on the bad handler, even if I put it at the
> top of the bad handler. That was my first hint that something was 
> strange, and by logging req.method I was able to find out that Apache 
> wants to use GET instead of POST with my non-working handler. It doesn't
> make sense, since I'm using the exact same form that worked with the 
> smaller (working) handler.
> 3) Before anyone asks, I'm manually killing my browser cache between 
> submissions just to be safe. The strange behavior is exhibited in both
> Mozilla and IE.
> 
> 
> Graham Dumpleton wrote:
> 
> > The content length will not be set for a GET, thus I had in mine:
> > 
> >     if req.method == "POST":
> >       length = int(req.headers_in["content-length"])
> >       template.req_read.content = req.read(length)
> > 
> > I believe that for a POST, content length must be provided by the
> > client, certainly for the content types that FieldStorage is designed
> > to work with.
> > 
> > Davin Boling wrote ..
> > 
> >>(forgive the double-mail Graham, replied direct and didn't hit the list
> >>by accident)
> >>
> >>
> >>I took your suggestion involving time.sleep, but it made no difference.
> >>As for grabbing the content-length in the method you described...the
> >>plot thickens!
> >>
> >>Using your code at the very beginning of the handler(req):, I get the
> >>following exception:
> >>
> >>
> >>Mod_python error: "PythonHandler handler"
> >>
> >>Traceback (most recent call last):
> >>
> >>   File "/usr/lib/python2.3/site-packages/mod_python/apache.py", line
> >>299, in HandlerDispatch
> >>     result = object(req)
> >>
> >>   File "/home/davin/public_html/demo/handler/__init__.py", line 83,
> in
> >>handler
> >>     length = int(req.headers_in["content-length"])
> >>
> >>KeyError: 'content-length'
> >>
> >>
> >>Graham Dumpleton wrote:
> >>
> >>
> >>>Davin Boling wrote ..
> >>>
> >>>
> >>>>I've got an example that works correctly already. The problem is that
> >>
> >>in
> >>
> >>>>the larger handler that I've written, SOMETHING is breaking. I can't
> >>>>understand at all why req.read() returns nothing on a POST when it's
> >>
> >>the
> >>
> >>>>very first thing I assign to a variable. I'm about to go on a commenting
> >>>>crusade to narrow down where the problem is.
> >>>>
> >>>>This is my "from scratch" handler, which works correctly...just to
> show
> >>>>that I know how to handle a POST:
> >>>>
> >>>>
> >>>
> >>>>from mod_python import apache
> >>>
> >>>>def handler(req):
> >>>>    head = """
> >>>>           <?xml version="1.0" encoding="utf-8"?>
> >>>>           <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
> >>>>            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> >>>>            <html>
> >>>>            <head>
> >>>>            <title>Debug</title>
> >>>>            </head>
> >>>>            <body>
> >>>>           """
> >>>>    data = req.read()
> >>>>    method = req.method
> >>>>    req.content_type = "text/html"
> >>>>    req.write(head + data + method + '</body></html>')
> >>>>    return apache.OK
> >>>
> >>>
> >>>Get the content length out of the headers and supply it to req.read()
> >>>and see if that makes a difference. Ie.,
> >>>
> >>>      length = int(req.headers_in["content-length"])
> >>>      data = req.read(length)
> >>>
> >>>Also note what documentation says about timeouts.
> >>>
> >>>  read([len])
> >>>
> >>>    Reads at most len bytes directly from the client, returning a  string
> >>>    with the data read. If the len argument is negative or omitted,
> reads
> >>>    all data given by the client.
> >>>
> >>>    This function is affected by the Timeout Apache configuration  directive.
> >>>    The read will be aborted and an IOError  raised if the Timeout is
> >>
> >>reached
> >>
> >>>    while reading client data.
> >>>
> >>>    This function relies on the client providing the Content-length
> >>
> >>header.
> >>
> >>>    Absence of the Content-length header will be treated as  if
> >>>    Content-length: 0 was supplied.
> >>>
> >>>    Incorrect Content-length may cause the function to try to read 
> more
> >>>    data than available, which will make the function block until a
> >>
> >>Timeout
> >>
> >>>    is reached.
> >>>
> >>>One would expect an IOError according to this if a timeout occured,
> but
> >>>maybe it isn't being generated for some reason.
> >>>
> >>>You might also add:
> >>>
> >>>  time.sleep(10)
> >>>
> >>>at the start of your handler and see if it makes a difference. Ie.,
> try
> >>
> >>and
> >>
> >>>determine if it is the time the client takes to send the post data.
> >>>
> >>>Graham
> >>>     


More information about the Mod_python mailing list