How do I copy wsgi.input if I want to process POST data more than once?

前端 未结 3 2035
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-20 14:58

In WSGI, post data is consumed by reading the file-like object environ[\'wsgi.input\']. If a second element in the stack also wants to read post data it may han

相关标签:
3条回答
  • 2020-12-20 15:29

    Go have a look at WebOb package. It provides functionality that allows one to designate that wsgi.input should be made seekable. This has the effect of allowing you to rewind the input stream such that content can be replayed through different handler. Even if you don't use WebOb, the way it does this should be instructive as would trust Ian to have done this in an appropriate way. For search results in documentation go here.

    0 讨论(0)
  • 2020-12-20 15:33

    You could try putting a file-like replica of the stream back in the environment:

    from cStringIO import StringIO
    
    length = int(environ.get('CONTENT_LENGTH', '0'))
    body = StringIO(environ['wsgi.input'].read(length))
    environ['wsgi.input'] = body
    

    Needing to do this is a bit of a smell, though. Ideally only one piece of code should be parsing the query string and post body, and delivering the results to other components.

    0 讨论(0)
  • 2020-12-20 15:54

    If you're gonna read it in one fell swoop, you could always read it in, create a CStringIO file-like object of the stuff you've read and then assign it back, like this:

    import cStringIO
    import copy
    lines = []
    for line in environ['wsgi.input']:
        lines.append(line)
    newlines = copy.copy(lines)
    environ['wsgi.input'] = cStringIO.StringIO(''.join(newlines))
    

    There's most likely a more efficient way to do this, but I in general find wsgi's post stuff pretty brittle if you want to do anything non-trivial (like read post data muptiple times)...

    0 讨论(0)
提交回复
热议问题