Browse Source

Add middleware for range request

pull/1395/head
Hironsan 3 years ago
parent
commit
32a438e76c
2 changed files with 38 additions and 0 deletions
  1. 35
      backend/api/middleware.py
  2. 3
      backend/app/settings.py

35
backend/api/middleware.py

@ -0,0 +1,35 @@
import os
from django.utils.deprecation import MiddlewareMixin
class RangesMiddleware(MiddlewareMixin):
"""Quick solution. See:
https://stackoverflow.com/questions/14324250/byte-ranges-in-django/35928017#35928017
"""
def process_response(self, request, response):
if response.status_code != 200 or not hasattr(response, 'file_to_stream'):
return response
http_range = request.META.get('HTTP_RANGE')
if not (http_range and http_range.startswith('bytes=') and http_range.count('-') == 1):
return response
if_range = request.META.get('HTTP_IF_RANGE')
if if_range and if_range != response.get('Last-Modified') and if_range != response.get('ETag'):
return response
f = response.file_to_stream
statobj = os.fstat(f.fileno())
start, end = http_range.split('=')[1].split('-')
if not start: # requesting the last N bytes
start = max(0, statobj.st_size - int(end))
end = ''
start, end = int(start or 0), int(end or statobj.st_size - 1)
assert 0 <= start < statobj.st_size, (start, statobj.st_size)
end = min(end, statobj.st_size - 1)
f.seek(start)
old_read = f.read
f.read = lambda n: old_read(min(n, end + 1 - f.tell()))
response.status_code = 206
response['Content-Length'] = end + 1 - start
response['Content-Range'] = 'bytes %d-%d/%d' % (start, end, statobj.st_size)
return response

3
backend/app/settings.py

@ -88,6 +88,9 @@ MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
]
if DEBUG:
MIDDLEWARE.append('api.middleware.RangesMiddleware')
ROOT_URLCONF = 'app.urls'
TEMPLATES = [

Loading…
Cancel
Save