Serving a file

From XPUB & Lens-Based wiki

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 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 a 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 use (ensuring that they are 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 the path isn't carefully controlled).

#!/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()