Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python POST data using mod_wsgi

This must be a very simple question, but I don't seem to be able to figure out.

I'm using apache + mod_wsgi to host my python application, and I'd like to get the post content submitted in one of the forms -however, neither the environment values, nor sys.stdin contains any of this data. Mind giving me a quick hand?

Edit: Tried already:

  • environ["CONTENT_TYPE"] = 'application/x-www-form-urlencoded' (no data)
  • environ["wsgi.input"] seems a plausible way, however, both environ["wsgi.input"].read(), and environ["wsgi.input"].read(-1) returns an empty string (yes, content has been posted, and environ["request_method"] = "post"
like image 764
Silver Dragon Avatar asked Dec 26 '08 23:12

Silver Dragon


2 Answers

PEP 333 says you must read environ['wsgi.input'].

I just saved the following code and made apache's mod_wsgi run it. It works.

You must be doing something wrong.

from pprint import pformat

def application(environ, start_response):
    # show the environment:
    output = ['<pre>']
    output.append(pformat(environ))
    output.append('</pre>')

    #create a simple form:
    output.append('<form method="post">')
    output.append('<input type="text" name="test">')
    output.append('<input type="submit">')
    output.append('</form>')

    if environ['REQUEST_METHOD'] == 'POST':
        # show form data as received by POST:
        output.append('<h1>FORM DATA</h1>')
        output.append(pformat(environ['wsgi.input'].read()))

    # send results
    output_len = sum(len(line) for line in output)
    start_response('200 OK', [('Content-type', 'text/html'),
                              ('Content-Length', str(output_len))])
    return output
like image 127
nosklo Avatar answered Nov 18 '22 22:11

nosklo


Be aware that technically speaking calling read() or read(-1) on wsgi.input is a violation of the WSGI specification even though Apache/mod_wsgi allows it. This is because the WSGI specification requires that a valid length argument be supplied. The WSGI specification also says you shouldn't read more data than is specified by the CONTENT_LENGTH.

So, the code above may work in Apache/mod_wsgi but it isn't portable WSGI code and will fail on some other WSGI implementations. To be correct, determine request content length and supply that value to read().

like image 21
Graham Dumpleton Avatar answered Nov 18 '22 22:11

Graham Dumpleton