6

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
  • 3
    "No browser knows the file's name, for example, so they use a random or default one." Content-Disposition header handles this, no? - ietf.org/rfc/rfc2183.txt Commented Sep 19, 2009 at 0:48

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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?

2 Comments

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.