15

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"

2 Answers 2

22

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
Sign up to request clarification or add additional context in comments.

1 Comment

This blocked, for me. This was solved by reading the exact number of bytes: length = int(environ.get('CONTENT_LENGTH', '0')) and …read(length). This is consistent with the fact that the documentation linked to does not mention read() (no length) as having to be supported.
14

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().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.