views:

259

answers:

2

If a would-be-HTTP-server written in Python2.6 has local access to a file, what would be the most correct way for that server to return the file to a client, on request?

Let's say this is the current situation:

header('Content-Type', file.mimetype)
header('Content-Length', file.size) # file size in bytes
header('Content-MD5', file.hash)    # an md5 hash of the entire file

return open(file.path).read()

All the files are .zip or .rar archives no bigger than a couple of megabytes.

With the current situation, browsers handle the incoming download weirdly. No browser knows the file's name, for example, so they use a random or default one. (Firefox even saved the file with a .part extension, even though it was complete and completely usable.)

What would be the best way to fix this and other errors I may not even be aware of, yet?

What headers am I not sending?

Thanks!

+1  A: 

If you don't have to return the response body (that is, if you are given a stream for the response body by your framework) you can avoid holding the file in memory with something like this:

fp = file(path_to_the_file, 'rb')
while True:
    bytes = fp.read(8192)
    if bytes:
        response.write(bytes)
    else:
        return

What web framework are you using?

dcrosta
I'm using webpy. Since it doesn't seem to expose a file descriptor, my guess is I could slowly yield the file?
liszt
Seems to be exactly what the web.py authors recommend: http://webpy.org/cookbook/streaming_large_files
dcrosta
+4  A: 

This is how I send ZIP file,

    req.send_response(200)
    req.send_header('Content-Type', 'application/zip')
    req.send_header('Content-Disposition', 'attachment;'
                    'filename=%s' % filename)

Most browsers handle it correctly.

ZZ Coder