annotate MoinMoin/util/send_file.py @ 2657:080673c3e60a

Now nameless items can also be downloaded and removed unnecessary blank spaces in items/content.py
author Saurabh Kathpalia <saurabh.kathpalia95@gmail.com>
date Sun, 06 Jul 2014 09:25:31 +0530
parents d923c19262d3
children
rev   line source
26
4cd8edde9e94 automatically transform module docstrings, moving legal stuff to comments
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 25
diff changeset
1 # Copyright: 2010 by Armin Ronacher (initial implementation)
4cd8edde9e94 automatically transform module docstrings, moving legal stuff to comments
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 25
diff changeset
2 # Copyright: 2011 by MoinMoin:ThomasWaldmann (modifications)
4cd8edde9e94 automatically transform module docstrings, moving legal stuff to comments
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 25
diff changeset
3 # License: BSD (see license of flask)
4cd8edde9e94 automatically transform module docstrings, moving legal stuff to comments
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 25
diff changeset
4
0
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
5 """
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
6 A better send_file
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
7 ------------------
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
8
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
9 Initially, this was a modified implementation of flask 0.6.0's send_file(),
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
10 trying to be as compatible as possible.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
11
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
12 For details see: https://github.com/mitsuhiko/flask/issues/issue/104 and the
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
13 history of this file in our repository. This code fixes all the issues
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
14 described in the bug report.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
15
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
16 As we forked send_file, we later modified it (without trying to stay
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
17 compatible), because we can easily adapt anyway and the code can be much
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
18 simpler without compatibility code.
26
4cd8edde9e94 automatically transform module docstrings, moving legal stuff to comments
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 25
diff changeset
19 """
0
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
20
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
21
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
22 import os
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
23 import mimetypes
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
24 from time import time
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
25 from zlib import adler32
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
26
296
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
27 from werkzeug import Headers, wrap_file, url_quote
0
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
28 from flask import current_app, request
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
29
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
30
296
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
31 def encode_rfc2231(value, coding='UTF-8', lang=''):
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
32 """
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
33 Encode a value according to RFC2231/5987.
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
34
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
35 :param value: the value to encode. must be either unicode or encoded in <coding>.
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
36 :param coding: the coding (charset) to use. it is a good idea to use 'UTF-8'.
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
37 :param lang: the language to use. defaults to empty string (no language given).
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
38 """
969
5bf6d7a2ffcf Convert all %r, %s, %x, %d, %i, %o to new Format String Syntax
Vedran Mileti? <rivanvx@gmail.com>
parents: 296
diff changeset
39 return "{0}'{1}'{2}".format(coding, lang, url_quote(value, charset=coding))
296
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
40
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
41
0
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
42 def send_file(filename=None, file=None,
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
43 mimetype=None,
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
44 as_attachment=False, attachment_filename=None,
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
45 mtime=None, cache_timeout=60 * 60 * 12,
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
46 add_etags=True, etag=None, conditional=False):
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
47 """Sends the contents of a file to the client.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
48
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
49 A file can be either a filesystem file or a file-like object (this code
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
50 is careful about not assuming that every file is a filesystem file).
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
51
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
52 This will use the most efficient method available, configured and possible
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
53 (for filesystem files some more optimizations may be possible that for
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
54 file-like objects not having a filesystem filename).
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
55 By default it will try to use the WSGI server's file_wrapper support.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
56 Alternatively you can set the application's :attr:`~Flask.use_x_sendfile`
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
57 attribute to ``True`` to directly emit an `X-Sendfile` header. This
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
58 however requires support of the underlying webserver for `X-Sendfile`.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
59
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
60 send_file will try to guess some stuff for you if you do not provide them:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
61
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
62 * mimetype (based on filename / attachment_filename)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
63 * mtime (based on filesystem file's metadata)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
64 * etag (based on filename, mtime, filesystem file size)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
65
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
66 If you do not provide enough information, send_file might raise a
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
67 TypeError.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
68
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
69 For extra security you probably want to sent certain files as attachment
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
70 (HTML for instance).
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
71
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
72 Please never pass filenames to this function from user sources without
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
73 checking them first. Something like this is usually sufficient to
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
74 avoid security problems::
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
75
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
76 if '..' in filename or filename.startswith('/'):
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
77 abort(404)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
78
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
79 :param filename: the filesystem filename of the file to send (relative to
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
80 the :attr:`~Flask.root_path` if a relative path is
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
81 specified).
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
82 If you just have an open filesystem file object f, give
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
83 `f.name` here.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
84 If you don't have a filesystem file nor a filesystem file
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
85 name, but just a file-like obj, don't use this argument.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
86 :param file: a file (or file-like) object, you may give it if you either do
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
87 not have a filesystem filename or if you already have an open
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
88 file anyway.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
89 :param mimetype: the mimetype of the file if provided, otherwise
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
90 auto detection happens based on the filename or
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
91 attachment_filename.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
92 :param as_attachment: set to `True` if you want to send this file with
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
93 a ``Content-Disposition: attachment`` header.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
94 :param attachment_filename: the filename for the attachment if it
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
95 differs from the filename argument.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
96 :param mtime: the modification time of the file if provided, otherwise
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
97 it will be determined automatically for filesystem files
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
98 :param cache_timeout: the timeout in seconds for the headers.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
99 :param conditional: set to `True` to enable conditional responses.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
100 :param add_etags: set to `False` to disable attaching of etags.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
101 :param etag: you can give an etag here, None means to try to compute the
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
102 etag from the file's filesystem metadata (the latter of course
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
103 only works for filesystem files). If you do not give a
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
104 filename, but you use add_etags, you must explicitely provide
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
105 the etag as it can't compute it for that case.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
106 """
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
107 if filename and not os.path.isabs(filename):
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
108 filename = os.path.join(current_app.root_path, filename)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
109
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
110 if mimetype is None and (filename or attachment_filename):
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
111 mimetype = mimetypes.guess_type(filename or attachment_filename)[0]
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
112 if mimetype is None:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
113 mimetype = 'application/octet-stream'
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
114
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
115 headers = Headers()
1154
e61194bb558e Pre-compute content_length in send_file (fixes #121)
Sam Toyer <samATqxcvDOTnet>
parents: 969
diff changeset
116
e61194bb558e Pre-compute content_length in send_file (fixes #121)
Sam Toyer <samATqxcvDOTnet>
parents: 969
diff changeset
117 # We must compute size the smart way rather than letting
e61194bb558e Pre-compute content_length in send_file (fixes #121)
Sam Toyer <samATqxcvDOTnet>
parents: 969
diff changeset
118 # werkzeug turn our iterable into an in-memory sequence
e61194bb558e Pre-compute content_length in send_file (fixes #121)
Sam Toyer <samATqxcvDOTnet>
parents: 969
diff changeset
119 # See `_ensure_sequence` in werkzeug/wrappers.py
e61194bb558e Pre-compute content_length in send_file (fixes #121)
Sam Toyer <samATqxcvDOTnet>
parents: 969
diff changeset
120 if filename:
e61194bb558e Pre-compute content_length in send_file (fixes #121)
Sam Toyer <samATqxcvDOTnet>
parents: 969
diff changeset
121 fsize = os.path.getsize(filename)
1744
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
122 elif file and hasattr(file, 'seek') and hasattr(file, 'tell'):
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
123 fsize = None
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
124 # be extra careful as some file-like objects (like zip members) have a seek
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
125 # and tell methods, but they just raise some exception (e.g. UnsupportedOperation)
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
126 # instead of really doing what they are supposed to do (or just be missing).
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
127 try:
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
128 file.seek(0, 2) # seek to EOF
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
129 try:
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
130 fsize = file.tell() # tell position
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
131 except Exception:
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
132 pass
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
133 file.seek(0, 0) # seek to start of file
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
134 except Exception:
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
135 pass
1156
4cd6611b0cf8 Fix send_file(None) and send_file unittest
Sam Toyer <samATqxcvDOTnet>
parents: 1154
diff changeset
136 else:
1744
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
137 fsize = None
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
138 if fsize is not None:
d923c19262d3 send_file: fix cases when file-like objects have no real tell/seek methods
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 1397
diff changeset
139 headers.add('Content-Length', fsize)
1154
e61194bb558e Pre-compute content_length in send_file (fixes #121)
Sam Toyer <samATqxcvDOTnet>
parents: 969
diff changeset
140
0
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
141 if as_attachment:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
142 if attachment_filename is None:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
143 if not filename:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
144 raise TypeError('filename unavailable, required for sending as attachment')
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
145 attachment_filename = os.path.basename(filename)
296
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
146 # Note: we only give filename* param, not filename param, hoping that a user agent that
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
147 # does not support filename* then falls back into using the last URL fragment (and decodes
1e9ec607913d fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 26
diff changeset
148 # that correctly). See there for details: http://greenbytes.de/tech/tc2231/
969
5bf6d7a2ffcf Convert all %r, %s, %x, %d, %i, %o to new Format String Syntax
Vedran Mileti? <rivanvx@gmail.com>
parents: 296
diff changeset
149 headers.add('Content-Disposition', 'attachment; filename*={0}'.format(encode_rfc2231(attachment_filename)))
0
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
150
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
151 if current_app.use_x_sendfile and filename:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
152 if file:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
153 file.close()
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
154 headers['X-Sendfile'] = filename
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
155 data = None
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
156 else:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
157 if filename:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
158 if not file:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
159 file = open(filename, 'rb')
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
160 if mtime is None:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
161 mtime = os.path.getmtime(filename)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
162 data = wrap_file(request.environ, file)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
163
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
164 rv = current_app.response_class(data, mimetype=mimetype, headers=headers, direct_passthrough=True)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
165
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
166 # if we know the file modification date, we can store it as the
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
167 # current time to better support conditional requests. Werkzeug
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
168 # as of 0.6.1 will override this value however in the conditional
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
169 # response with the current time. This will be fixed in Werkzeug
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
170 # with a new release, however many WSGI servers will still emit
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
171 # a separate date header.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
172 if mtime is not None:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
173 rv.date = int(mtime)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
174
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
175 rv.cache_control.public = True
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
176 if cache_timeout:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
177 rv.cache_control.max_age = cache_timeout
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
178 rv.expires = int(time() + cache_timeout)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
179
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
180 if add_etags:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
181 if etag is None and filename:
969
5bf6d7a2ffcf Convert all %r, %s, %x, %d, %i, %o to new Format String Syntax
Vedran Mileti? <rivanvx@gmail.com>
parents: 296
diff changeset
182 etag = 'flask-{0}-{1}-{2}'.format(
0
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
183 mtime or os.path.getmtime(filename),
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
184 os.path.getsize(filename),
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
185 adler32(filename) & 0xffffffff
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
186 )
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
187 if etag is None:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
188 raise TypeError("can't determine etag - please give etag or filename")
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
189 rv.set_etag(etag)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
190 if conditional:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
191 rv = rv.make_conditional(request)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
192 # make sure we don't send x-sendfile for servers that
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
193 # ignore the 304 status code for x-sendfile.
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
194 if rv.status_code == 304:
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
195 rv.headers.pop('x-sendfile', None)
5568cf133caf create moin/2.0 repo, drop all history (see notes below)
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
196 return rv