Serving a file: Difference between revisions
No edit summary |
No edit summary |
||
(6 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
In many cases, a direct link to a file on a server will be sufficient to allow someone to get at a particular file, and download it to their local machine. In some situations, however, it is necessary or useful to have python act as an inbetween, and to "serve" the file from a script. For instance, an image serving CGI might create images on-the-fly when necessary, but have an option to serve any pre-made "cached" file as an optimization. Or you may want to serve files that are outside of the webserver's public document tree (perhaps using python to require a password or other kind of authentication to get at a file's contents). | In many cases, a direct link to a file on a server will be sufficient to allow someone to get at a particular file, and download it to their local machine. In some situations, however, it is necessary or useful to have python act as an inbetween, and to "serve" the file from a script. For instance, an image serving CGI might create images on-the-fly when necessary, but have an option to serve any pre-made "cached" file as an optimization. Or you may want to serve files that are outside of the webserver's public document tree (perhaps using python to require a password or other kind of authentication to get at a file's contents). | ||
== File download link == | |||
In this example, python is used to serve a file as a "download link". The particular headers used should force a web browser to prompt the user to save a file (using the original filename), and should override any attempt the browser might make to display | In this example, python is used to serve a file as a "download link". The particular headers used should force a web browser to prompt the user to save a file (using the original filename), and should override any attempt the browser might make to display the file in the browser. | ||
{{danger}} Note that in this case the filepath is hardcoded in, but would of course more likely be based on some cgi.FieldStorage input. Make sure in that case though that you are ''very careful'' with whatever value you get from the cgi. For instance, you would want to ensure that your filepath falls within some expected directory to avoid inadvertantly exposing the contents of files you didn't intend to serve up. Files with passwords for instance could be happily served up if someone simply makes the right request if you aren't careful. | |||
<source lang="python"> | <source lang="python"> | ||
Line 27: | Line 30: | ||
f.close() | f.close() | ||
</source> | </source> | ||
[[Category:Cookbook]] |
Latest revision as of 09:55, 31 January 2023
In many cases, a direct link to a file on a server will be sufficient to allow someone to get at a particular file, and download it to their local machine. In some situations, however, it is necessary or useful to have python act as an inbetween, and to "serve" the file from a script. For instance, an image serving CGI might create images on-the-fly when necessary, but have an option to serve any pre-made "cached" file as an optimization. Or you may want to serve files that are outside of the webserver's public document tree (perhaps using python to require a password or other kind of authentication to get at a file's contents).
File download link
In this example, python is used to serve a file as a "download link". The particular headers used should force a web browser to prompt the user to save a file (using the original filename), and should override any attempt the browser might make to display the file in the browser.
Note that in this case the filepath is hardcoded in, but would of course more likely be based on some cgi.FieldStorage input. Make sure in that case though that you are very careful with whatever value you get from the cgi. For instance, you would want to ensure that your filepath falls within some expected directory to avoid inadvertantly exposing the contents of files you didn't intend to serve up. Files with passwords for instance could be happily served up if someone simply makes the right request if you aren't careful.
#!/usr/bin/env python
import os
filepath = "/path/to/the/file.extension"
filelen = os.path.getsize(filepath)
print "Content-type: application/download"
print "Content-length: %d" % filelen
print "Content-transfer-encoding: binary"
print "Content-disposition: attachment; filename=%s" % os.path.basename(filepath)
print
f = open(filepath, "rb")
bytesserved = 0
while True:
data = f.read(1024)
if not data:
break
bytesserved += len(data)
sys.stdout.write(data)
f.close()