python simple wsgi file upload script - What is wrong?

ぐ巨炮叔叔 提交于 2019-12-04 20:34:22

environ['wsgi.input'] is a stream like object. You need to cache it firstly to file like object, eg: tempfile.TemporaryFile or StringIO (io.BytesIO in python3):

from tempfile import TemporaryFile
import os, cgi

def read(environ):
    length = int(environ.get('CONTENT_LENGTH', 0))
    stream = environ['wsgi.input']
    body = TemporaryFile(mode='w+b')
    while length > 0:
        part = stream.read(min(length, 1024*200)) # 200KB buffer size
        if not part: break
        body.write(part)
        length -= len(part)
    body.seek(0)
    environ['wsgi.input'] = body
    return body

def Request(environ, start_response):
    # use cgi module to read data
    body = read(environ)
    form = cgi.FieldStorage(fp=body, environ=environ, keep_blank_values=True)
    # rest of your code

For safety reason consider to mask environ value which you pass to FieldStorage

Self - answer : Sorry I didn't said that This was PyISAPIe-specific problem. the file-like object environ['wsgi.input'] does not have readline() method like other environ varibles in different wsgi implementations would do.

the (inefficient workaround) is saving everything from environ['wsgi.input'] into a tempfile and pass it to FieldStorage.

So :

import tempfile, cgi
def some_wsgi_app(environ, start_response):
    temp_file = tempfile.TemporaryFile()
    temp_file.write(environ['wsgi.input'].read()) # or use buffered read()
    temp_file.seek(0)
    form = cgi.FieldStorage(fp=temp_file, environ=environ, keep_blank_values=True)
    # do_something #
    temp_file.close() #close and destroy temp file

    # ... start_response, return ... #

However above example will fail to operate properly if uploaded data from user is too big.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!