Ignore writing headers when in ASGI mode (#1957)
* Ignore writing headers when in ASGI mode for streaming responses * Move asgi set on streaming until after response type check * Adds multidict==5.0.0 to pass tests * Bump version to 20.9.1
This commit is contained in:
parent
9e048bc0c3
commit
e5aed4c067
|
@ -7,8 +7,8 @@
|
|||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from sanic import Sanic, response
|
||||
|
||||
from sanic import Sanic, response
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
|
@ -42,9 +42,7 @@ async def handler_file(request):
|
|||
|
||||
@app.route("/file_stream")
|
||||
async def handler_file_stream(request):
|
||||
return await response.file_stream(
|
||||
Path("../") / "setup.py", chunk_size=1024
|
||||
)
|
||||
return await response.file_stream(Path("../") / "setup.py", chunk_size=1024)
|
||||
|
||||
|
||||
@app.route("/stream", stream=True)
|
||||
|
|
|
@ -1 +1 @@
|
|||
__version__ = "20.9.0"
|
||||
__version__ = "20.9.1"
|
||||
|
|
|
@ -350,6 +350,8 @@ class ASGIApp:
|
|||
if name not in (b"Set-Cookie",)
|
||||
]
|
||||
|
||||
response.asgi = True
|
||||
|
||||
if "content-length" not in response.headers and not isinstance(
|
||||
response, StreamingHTTPResponse
|
||||
):
|
||||
|
|
|
@ -22,6 +22,9 @@ except ImportError:
|
|||
|
||||
|
||||
class BaseHTTPResponse:
|
||||
def __init__(self):
|
||||
self.asgi = False
|
||||
|
||||
def _encode_body(self, data):
|
||||
return data.encode() if hasattr(data, "encode") else data
|
||||
|
||||
|
@ -80,6 +83,8 @@ class StreamingHTTPResponse(BaseHTTPResponse):
|
|||
content_type="text/plain; charset=utf-8",
|
||||
chunked=True,
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.content_type = content_type
|
||||
self.streaming_fn = streaming_fn
|
||||
self.status = status
|
||||
|
@ -109,6 +114,7 @@ class StreamingHTTPResponse(BaseHTTPResponse):
|
|||
"""
|
||||
if version != "1.1":
|
||||
self.chunked = False
|
||||
if not getattr(self, "asgi", False):
|
||||
headers = self.get_headers(
|
||||
version,
|
||||
keep_alive=keep_alive,
|
||||
|
@ -143,6 +149,8 @@ class HTTPResponse(BaseHTTPResponse):
|
|||
content_type=None,
|
||||
body_bytes=b"",
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.content_type = content_type
|
||||
self.body = body_bytes if body is None else self._encode_body(body)
|
||||
self.status = status
|
||||
|
|
|
@ -235,6 +235,12 @@ def test_chunked_streaming_returns_correct_content(streaming_app):
|
|||
assert response.text == "foo,bar"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_chunked_streaming_returns_correct_content_asgi(streaming_app):
|
||||
request, response = await streaming_app.asgi_client.get("/")
|
||||
assert response.text == "4\r\nfoo,\r\n3\r\nbar\r\n0\r\n\r\n"
|
||||
|
||||
|
||||
def test_non_chunked_streaming_adds_correct_headers(non_chunked_streaming_app):
|
||||
request, response = non_chunked_streaming_app.test_client.get("/")
|
||||
assert "Transfer-Encoding" not in response.headers
|
||||
|
@ -242,6 +248,16 @@ def test_non_chunked_streaming_adds_correct_headers(non_chunked_streaming_app):
|
|||
assert response.headers["Content-Length"] == "7"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_non_chunked_streaming_adds_correct_headers_asgi(
|
||||
non_chunked_streaming_app,
|
||||
):
|
||||
request, response = await non_chunked_streaming_app.asgi_client.get("/")
|
||||
assert "Transfer-Encoding" not in response.headers
|
||||
assert response.headers["Content-Type"] == "text/csv"
|
||||
assert response.headers["Content-Length"] == "7"
|
||||
|
||||
|
||||
def test_non_chunked_streaming_returns_correct_content(
|
||||
non_chunked_streaming_app,
|
||||
):
|
||||
|
|
Loading…
Reference in New Issue
Block a user