summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-07-29 19:29:38 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2011-07-29 19:29:38 +0200
commitda578506d9317539b35ae5b3e49e79e6ad1c7e83 (patch)
tree41fad751fabeb90dbf629ad42ca1c373ab3a5c29
parent4eb1af0b1147adb53a848c1b3053555033a12759 (diff)
Handle file ranges.
-rwxr-xr-xfbin.py35
1 files changed, 29 insertions, 6 deletions
diff --git a/fbin.py b/fbin.py
index 106f8e4..15ba13e 100755
--- a/fbin.py
+++ b/fbin.py
@@ -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')