changeset 1744:d923c19262d3

send_file: fix cases when file-like objects have no real tell/seek methods only set Content-Length header when we really could determine it.
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 26 Aug 2012 19:57:01 +0200
parents fbe32ae2dd3d
children 6a788472c293
files MoinMoin/util/send_file.py
diffstat 1 files changed, 17 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/util/send_file.py	Sun Aug 26 18:53:11 2012 +0200
+++ b/MoinMoin/util/send_file.py	Sun Aug 26 19:57:01 2012 +0200
@@ -119,14 +119,24 @@
     # See `_ensure_sequence` in werkzeug/wrappers.py
     if filename:
         fsize = os.path.getsize(filename)
-    elif file:
-        # Seek 0 bytes (0) from the end of the file (2)
-        file.seek(0, 2)
-        fsize = file.tell()
-        file.seek(0, 0)
+    elif file and hasattr(file, 'seek') and hasattr(file, 'tell'):
+        fsize = None
+        # be extra careful as some file-like objects (like zip members) have a seek
+        # and tell methods, but they just raise some exception (e.g. UnsupportedOperation)
+        # instead of really doing what they are supposed to do (or just be missing).
+        try:
+            file.seek(0, 2)  # seek to EOF
+            try:
+                fsize = file.tell()  # tell position
+            except Exception:
+                pass
+            file.seek(0, 0)  # seek to start of file
+        except Exception:
+            pass
     else:
-        fsize = 0
-    headers.add('Content-Length', fsize)
+        fsize = None
+    if fsize is not None:
+        headers.add('Content-Length', fsize)
 
     if as_attachment:
         if attachment_filename is None: