Merge pull request #1403 from harshanarayana/fix/GIT-1398-Http_Response_Content_Length_Mismatch

Fix Content-Length Mismatch while using json and ujson
This commit is contained in:
7 2018-11-10 00:14:03 +08:00 committed by GitHub
commit 4cb40f2042
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 13 deletions

View File

@ -1,3 +1,4 @@
from functools import partial
from mimetypes import guess_type
from os import path
from urllib.parse import quote_plus
@ -12,7 +13,11 @@ from sanic.helpers import STATUS_CODES, has_message_body, remove_entity_headers
try:
from ujson import dumps as json_dumps
except BaseException:
from json import dumps as json_dumps
from json import dumps
# This is done in order to ensure that the JSON response is
# kept consistent across both ujson and inbuilt json usage.
json_dumps = partial(dumps, separators=(",", ":"))
class BaseHTTPResponse:

View File

@ -1,20 +1,19 @@
import sys
import asyncio
import inspect
import os
from aiofiles import os as async_os
from mimetypes import guess_type
from random import choice
from unittest.mock import MagicMock
from urllib.parse import unquote
import pytest
from random import choice
from aiofiles import os as async_os
from sanic.response import (
HTTPResponse, stream, StreamingHTTPResponse, file, file_stream, json
)
from sanic.server import HttpProtocol
from sanic.testing import HOST, PORT
from unittest.mock import MagicMock
JSON_DATA = {'ok': True}
@ -38,7 +37,6 @@ async def sample_streaming_fn(response):
def test_method_not_allowed(app):
@app.get('/')
async def test_get(request):
return response.json({'hello': 'world'})
@ -55,12 +53,12 @@ def test_method_not_allowed(app):
request, response = app.test_client.head('/')
assert response.status == 405
assert set(response.headers['Allow'].split(', ')) == set(['GET', 'POST'])
assert set(response.headers['Allow'].split(', ')) == {'GET', 'POST'}
assert response.headers['Content-Length'] == '0'
request, response = app.test_client.patch('/')
assert response.status == 405
assert set(response.headers['Allow'].split(', ')) == set(['GET', 'POST'])
assert set(response.headers['Allow'].split(', ')) == {'GET', 'POST'}
assert response.headers['Content-Length'] == '0'
@ -74,19 +72,62 @@ def test_response_header(app):
'CONTENT-TYPE': 'application/json'
})
is_windows = sys.platform in ['win32', 'cygwin']
request, response = app.test_client.get('/')
assert dict(response.headers) == {
'Connection': 'keep-alive',
'Keep-Alive': str(app.config.KEEP_ALIVE_TIMEOUT),
# response body contains an extra \r at the end if its windows
# TODO: this is the only place this difference shows up in our tests
# we should figure out a way to unify testing on both platforms
'Content-Length': '12' if is_windows else '11',
'Content-Length': '11',
'Content-Type': 'application/json',
}
def test_response_content_length(app):
@app.get("/response_with_space")
async def response_with_space(request):
return json({
"message": "Data",
"details": "Some Details"
}, headers={
'CONTENT-TYPE': 'application/json'
})
@app.get("/response_without_space")
async def response_without_space(request):
return json({
"message":"Data",
"details":"Some Details"
}, headers={
'CONTENT-TYPE': 'application/json'
})
_, response = app.test_client.get("/response_with_space")
content_length_for_response_with_space = response.headers.get("Content-Length")
_, response = app.test_client.get("/response_without_space")
content_length_for_response_without_space = response.headers.get("Content-Length")
assert content_length_for_response_with_space == content_length_for_response_without_space
assert content_length_for_response_with_space == '43'
def test_response_content_length_with_different_data_types(app):
@app.get("/")
async def get_data_with_different_types(request):
# Indentation issues in the Response is intentional. Please do not fix
return json({
'bool': True,
'none': None,
'string':'string',
'number': -1},
headers={
'CONTENT-TYPE': 'application/json'
})
_, response = app.test_client.get("/")
assert response.headers.get("Content-Length") == '55'
@pytest.fixture
def json_app(app):