forked from platypush/platypush
[media] Support HEAD method on media stream endpoints.
This commit is contained in:
parent
4373d4ceaa
commit
fa942b06e3
2 changed files with 32 additions and 9 deletions
|
@ -17,7 +17,7 @@ class MediaStreamRoute(StreamingRoute):
|
||||||
Route for media streams.
|
Route for media streams.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SUPPORTED_METHODS = ['GET', 'PUT', 'DELETE']
|
SUPPORTED_METHODS = ['GET', 'HEAD', 'PUT', 'DELETE']
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -50,6 +50,23 @@ class MediaStreamRoute(StreamingRoute):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._on_error(e)
|
self._on_error(e)
|
||||||
|
|
||||||
|
def head(self, media_id: Optional[str] = None):
|
||||||
|
"""
|
||||||
|
Streams a media resource by ID.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not media_id:
|
||||||
|
self.finish()
|
||||||
|
return
|
||||||
|
|
||||||
|
# Strip the extension
|
||||||
|
media_id = '.'.join(media_id.split('.')[:-1])
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.stream_media(media_id, head=True)
|
||||||
|
except Exception as e:
|
||||||
|
self._on_error(e)
|
||||||
|
|
||||||
def put(self, *_, **__):
|
def put(self, *_, **__):
|
||||||
"""
|
"""
|
||||||
The `PUT` route is used to prepare a new media resource for streaming.
|
The `PUT` route is used to prepare a new media resource for streaming.
|
||||||
|
@ -93,10 +110,10 @@ class MediaStreamRoute(StreamingRoute):
|
||||||
"""
|
"""
|
||||||
Returns the list of registered media resources.
|
Returns the list of registered media resources.
|
||||||
"""
|
"""
|
||||||
self.add_header('Content-Type', 'application/json')
|
self.set_header('Content-Type', 'application/json')
|
||||||
self.finish(json.dumps([dict(media) for media in load_media_map().values()]))
|
self.finish(json.dumps([dict(media) for media in load_media_map().values()]))
|
||||||
|
|
||||||
def stream_media(self, media_id: str):
|
def stream_media(self, media_id: str, head: bool = False):
|
||||||
"""
|
"""
|
||||||
Route to stream a media file given its ID.
|
Route to stream a media file given its ID.
|
||||||
"""
|
"""
|
||||||
|
@ -107,11 +124,11 @@ class MediaStreamRoute(StreamingRoute):
|
||||||
range_hdr = self.request.headers.get('Range')
|
range_hdr = self.request.headers.get('Range')
|
||||||
content_length = media_hndl.content_length
|
content_length = media_hndl.content_length
|
||||||
|
|
||||||
self.add_header('Accept-Ranges', 'bytes')
|
self.set_header('Accept-Ranges', 'bytes')
|
||||||
self.add_header('Content-Type', media_hndl.mime_type)
|
self.set_header('Content-Type', media_hndl.mime_type)
|
||||||
|
|
||||||
if 'download' in self.request.arguments:
|
if 'download' in self.request.arguments:
|
||||||
self.add_header(
|
self.set_header(
|
||||||
'Content-Disposition',
|
'Content-Disposition',
|
||||||
'attachment'
|
'attachment'
|
||||||
+ ('; filename="{media_hndl.filename}"' if media_hndl.filename else ''),
|
+ ('; filename="{media_hndl.filename}"' if media_hndl.filename else ''),
|
||||||
|
@ -129,7 +146,7 @@ class MediaStreamRoute(StreamingRoute):
|
||||||
content_length = to_bytes - from_bytes
|
content_length = to_bytes - from_bytes
|
||||||
|
|
||||||
self.set_status(206)
|
self.set_status(206)
|
||||||
self.add_header(
|
self.set_header(
|
||||||
'Content-Range',
|
'Content-Range',
|
||||||
f'bytes {from_bytes}-{to_bytes}/{media_hndl.content_length}',
|
f'bytes {from_bytes}-{to_bytes}/{media_hndl.content_length}',
|
||||||
)
|
)
|
||||||
|
@ -137,7 +154,13 @@ class MediaStreamRoute(StreamingRoute):
|
||||||
from_bytes = 0
|
from_bytes = 0
|
||||||
to_bytes = STREAMING_BLOCK_SIZE
|
to_bytes = STREAMING_BLOCK_SIZE
|
||||||
|
|
||||||
self.add_header('Content-Length', str(content_length))
|
self.set_header('Content-Length', str(content_length))
|
||||||
|
|
||||||
|
if head:
|
||||||
|
self.flush()
|
||||||
|
self.finish()
|
||||||
|
return
|
||||||
|
|
||||||
for chunk in media_hndl.get_data(
|
for chunk in media_hndl.get_data(
|
||||||
from_bytes=from_bytes,
|
from_bytes=from_bytes,
|
||||||
to_bytes=to_bytes,
|
to_bytes=to_bytes,
|
||||||
|
|
|
@ -36,7 +36,7 @@ class FileHandler(MediaHandler):
|
||||||
), f'{source} is not a valid media file (detected format: {self.mime_type})'
|
), f'{source} is not a valid media file (detected format: {self.mime_type})'
|
||||||
|
|
||||||
self.extension = mimetypes.guess_extension(self.mime_type)
|
self.extension = mimetypes.guess_extension(self.mime_type)
|
||||||
if self.url and self.extension:
|
if self.url and self.extension and not self.url.endswith(self.extension):
|
||||||
self.url += self.extension
|
self.url += self.extension
|
||||||
self.content_length = os.path.getsize(self.path)
|
self.content_length = os.path.getsize(self.path)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue