Sorry for the late answer.
On Sun, Jun 06, 2010 at 11:33:20PM +0100, Enrico Zini wrote:
> Bottle seems to be extracting the first element from the iterable in
> order to look at what the iterator returns and possibly add transparent
> recoding and whatnot, then it returns a chain iterator with the first
> element it took out and the rest.
>
> Now, the WSGI server, even if it supports the file_wrapper
> optimisation[1], will never be able to see that we are returning a
> file_wrapper, so the optimisation will never trigger, in the face of
> what Bottle's documentation says.
>
> The same also defeats the idea that in WSGI, if you return an object
> that has a close() method, it will be called at the end of the request.
> In this case, Bottle will wrap our returned generator (which has a close
> method) in one that doesn't.
>
> Goodbye cleanup after streaming ends.
Fixed in 590f213238d7b65eabc53fd5f7c47375b02a075e
> So, much more simple and readable, and with only one environ lookup:
>
> # Cast Files into iterables
> if hasattr(out, 'read'):
> wrapper = request.environ.get('wsgi.file_wrapper', None)
> if wrapper: out = wrapper(out)
> return out
The 'wsgi.file_wrapper' is optional and we must return an iterable. Some
file-like objects may not be iterable. A working fallback won't hurt :)
--
Mit freundlichen Grüßen
Marcel Hellkamp
>From 590f213238d7b65eabc53fd5f7c47375b02a075e Mon Sep 17 00:00:00 2001
From: Marcel Hellkamp <[email protected]>
Date: Fri, 18 Jun 2010 23:53:19 +0200
Subject: [PATCH] fix: Return wsgi.file_wrapper wrapped files directly to the wsgi server.
Thanks to Alex Popescu, Enrico Zini and David Paleino.
---
bottle.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/bottle.py b/bottle.py
index fef1837..e968bdd 100755
--- a/bottle.py
+++ b/bottle.py
@@ -508,8 +508,8 @@ class Bottle(object):
# File-like objects. Wrap or transfer in chunks that fit into memory.
if hasattr(out, 'read'):
- out = request.environ.get('wsgi.file_wrapper',
- lambda x, y: iter(lambda: x.read(y), tob('')))(out, 1024*64)
+ return request.environ.get('wsgi.file_wrapper',
+ lambda x: iter(lambda: x.read(1024*64), tob('')))(out)
# Handle Iterables. We peek into them to detect their inner type.
try:
--
1.7.0.4