Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code cleanup in file responses #1769

Merged
merged 2 commits into from
Jan 27, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 19 additions & 31 deletions sanic/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,22 +293,20 @@ async def file(
headers = headers or {}
if filename:
headers.setdefault(
"Content-Disposition", 'attachment; filename="{}"'.format(filename)
"Content-Disposition", f'attachment; filename="{filename}"'
)
filename = filename or path.split(location)[-1]

async with await open_async(location, mode="rb") as _file:
async with await open_async(location, mode="rb") as f:
if _range:
await _file.seek(_range.start)
out_stream = await _file.read(_range.size)
headers["Content-Range"] = "bytes %s-%s/%s" % (
_range.start,
_range.end,
_range.total,
)
await f.seek(_range.start)
out_stream = await f.read(_range.size)
headers[
"Content-Range"
] = "bytes {0.start}-{0.end}/{0.total}".format(_range)
status = 206
else:
out_stream = await _file.read()
out_stream = await f.read()

mime_type = mime_type or guess_type(filename)[0] or "text/plain"
return HTTPResponse(
Expand Down Expand Up @@ -342,44 +340,34 @@ async def file_stream(
headers = headers or {}
if filename:
headers.setdefault(
"Content-Disposition", 'attachment; filename="{}"'.format(filename)
"Content-Disposition", f'attachment; filename="{filename}"'
)
filename = filename or path.split(location)[-1]

_filectx = await open_async(location, mode="rb")
_file = await _filectx.__aenter__() # Will be exited by _streaming_fn
mime_type = mime_type or guess_type(filename)[0] or "text/plain"
if _range:
headers["Content-Range"] = "bytes {0.start}-{0.end}/{0.total}".format(
_range
)
status = 206

async def _streaming_fn(response):
nonlocal _file, chunk_size
try:
async with await open_async(location, mode="rb") as f:
if _range:
chunk_size = min((_range.size, chunk_size))
await _file.seek(_range.start)
await f.seek(_range.start)
to_send = _range.size
while to_send > 0:
content = await _file.read(chunk_size)
content = await f.read(min((_range.size, chunk_size)))
if len(content) < 1:
break
to_send -= len(content)
await response.write(content)
else:
while True:
content = await _file.read(chunk_size)
content = await f.read(chunk_size)
if len(content) < 1:
break
await response.write(content)
finally:
await _filectx.__aexit__(None, None, None)
return # Returning from this fn closes the stream

mime_type = mime_type or guess_type(filename)[0] or "text/plain"
if _range:
headers["Content-Range"] = "bytes %s-%s/%s" % (
_range.start,
_range.end,
_range.total,
)
status = 206
return StreamingHTTPResponse(
streaming_fn=_streaming_fn,
status=status,
Expand Down