handle io.BytesIO object with file_wrapper

fix #595
This commit is contained in:
benoitc 2013-08-27 11:45:32 +02:00
parent 40bc38bb2f
commit dc97e54412
3 changed files with 34 additions and 4 deletions

View File

@ -0,0 +1,14 @@
import io
from flask import Flask, send_file
app = Flask(__name__)
@app.route('/')
def index():
buf = io.BytesIO()
buf.write('hello world')
buf.seek(0)
return send_file(buf,
attachment_filename="testing.txt",
as_attachment=True)

View File

@ -10,6 +10,7 @@ import sys
from gunicorn.six import unquote_to_wsgi_str, string_types, binary_type, reraise
from gunicorn import SERVER_SOFTWARE
import gunicorn.six as six
import gunicorn.util as util
try:
@ -330,11 +331,13 @@ class Response(object):
sent += sendfile(sockno, fileno, offset + sent, nbytes - sent)
def write_file(self, respiter):
if sendfile is not None and \
hasattr(respiter.filelike, 'fileno') and \
hasattr(respiter.filelike, 'tell'):
if sendfile is not None and util.is_fileobject(respiter.filelike):
# sometimes the fileno isn't a callable
if six.callable(respiter.filelike.fileno):
fileno = respiter.filelike.fileno()
else:
fileno = respiter.filelike.fileno
fileno = respiter.filelike.fileno()
fd_offset = os.lseek(fileno, 0, os.SEEK_CUR)
fo_offset = respiter.filelike.tell()
nbytes = max(os.fstat(fileno).st_size - fo_offset, 0)

View File

@ -5,6 +5,7 @@
import fcntl
import io
import os
import pkg_resources
import random
@ -507,3 +508,15 @@ def to_bytestring(value):
return value
assert isinstance(value, text_type)
return value.encode("utf-8")
def is_fileobject(obj):
if not hasattr(obj, "tell") or not hasattr(obj, "fileno"):
return False
# check BytesIO case and maybe others
try:
obj.fileno()
except io.UnsupportedOperation:
return False
return True