diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2011-07-29 19:29:38 +0200 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2011-07-29 19:29:38 +0200 |
commit | da578506d9317539b35ae5b3e49e79e6ad1c7e83 (patch) | |
tree | 41fad751fabeb90dbf629ad42ca1c373ab3a5c29 | |
parent | 4eb1af0b1147adb53a848c1b3053555033a12759 (diff) |
Handle file ranges.
-rwxr-xr-x | fbin.py | 35 |
1 files changed, 29 insertions, 6 deletions
@@ -144,17 +144,18 @@ class Application(object): do_range = 'HTTP_RANGE' in environ if do_range: - file_range = environ['HTTP_RANGE'] + file_range = environ['HTTP_RANGE'].split('bytes=')[1] mime = mimetypes.guess_type(file.filename, strict = False)[0] or 'application/octet-stream' + + # X-Sendfile handling if settings.use_xsendfile: headers = [('Last-Modified', file.date.strftime(rfc1123_format))] if do_range: - r = file_range.split('bytes=')[1] - headers.append(('X-Sendfile2', '{filename} {range}'.format(filename = urllib.quote(filename.encode('utf8')), range = r))) - if r.endswith('-'): - r += str(os.path.getsize(filename)-1) - headers.append(('Content-Range', 'bytes {r}/{size}'.format(r = r, size = os.path.getsize(filename)))) + headers.append(('X-Sendfile2', '{filename} {range}'.format(filename = urllib.quote(filename.encode('utf8')), range = file_range))) + if file_range.endswith('-'): + file_range += str(os.path.getsize(filename)-1) + headers.append(('Content-Range', 'bytes {range}/{size}'.format(range = file_range, size = os.path.getsize(filename)))) status = '206 Partial Content' else: headers.append(('X-Sendfile', filename.encode('utf8'))) @@ -162,6 +163,28 @@ class Application(object): start_response(status, headers) return [] + # Range handling + if do_range: + start, end = [int(x or 0) for x in file_range.split('-')] + size = os.path.getsize(filename) + + if end == 0: + end = size-1 + + write_out = start_response('206 Partial Content', [('Content-Type', mime), + ('Content-Range', 'bytes {start}-{end}/{size}'.format(start = start, end = end, size = size)), + ('Content-Length', str(end - start + 1)), ('Last-Modified', file.date.strftime(rfc1123_format))]) + + f = open(filename, 'rb') + f.seek(start) + remaining = end-start+1 + s = f.read(min(remaining, 1024)) + while s: + write_out(s) + remaining -= len(s) + s = f.read(min(remaining, 1024)) + return [] + start_response('200 OK', [('Content-Type', mime), ('Content-Length', str(os.path.getsize(filename))), ('Last-Modified', file.date.strftime(rfc1123_format))]) return open(filename, 'rb') |