Fix missing content length of Response
This patch fixes swob.Response to set missing content length correctly. When a child class of swob.Response is initialized with both "body" and "headers" arguments which includes content length, swob.Response might loose the acutual content length generated from the body because "headers" will overwrite the content length property after the body assignment. It'll cause the difference between headers's content length and acutual body length. This would affect mainly 3rd party middleware(s) to make an original response as follows: req = swob.Request.blank('/') req.method = 'HEAD' resp = req.get_response(app) return HTTPOk(body='Ok', headers=resp.headers) This patch changes the order of headers updating and then fixes init() to set correct content length. Change-Id: Icd8b7cbfe6bbe2c7965175969af299a5eb7a74ef
This commit is contained in:
parent
8cf9107022
commit
6f21504ccc
@ -1112,6 +1112,10 @@ class Response(object):
|
||||
else:
|
||||
self.environ = {}
|
||||
if headers:
|
||||
if self._body and 'Content-Length' in headers:
|
||||
# If body is not empty, prioritize actual body length over
|
||||
# content_length in headers
|
||||
del headers['Content-Length']
|
||||
self.headers.update(headers)
|
||||
if self.status_int == 401 and 'www-authenticate' not in self.headers:
|
||||
self.headers.update({'www-authenticate': self.www_authenticate()})
|
||||
|
@ -1419,6 +1419,57 @@ class TestResponse(unittest.TestCase):
|
||||
'<html><h1>Insufficient Storage</h1><p>There was not enough space '
|
||||
'to save the resource. Drive: sda1</p></html>')
|
||||
|
||||
def test_200_with_body_and_headers(self):
|
||||
headers = {'Content-Length': '0'}
|
||||
content = 'foo'
|
||||
resp = swift.common.swob.HTTPOk(body=content, headers=headers)
|
||||
self.assertEquals(resp.body, content)
|
||||
self.assertEquals(resp.content_length, len(content))
|
||||
|
||||
def test_init_with_body_headers_app_iter(self):
|
||||
# body exists but no headers and no app_iter
|
||||
body = 'ok'
|
||||
resp = swift.common.swob.Response(body=body)
|
||||
self.assertEquals(resp.body, body)
|
||||
self.assertEquals(resp.content_length, len(body))
|
||||
|
||||
# body and headers with 0 content_length exist but no app_iter
|
||||
body = 'ok'
|
||||
resp = swift.common.swob.Response(
|
||||
body=body, headers={'Content-Length': '0'})
|
||||
self.assertEquals(resp.body, body)
|
||||
self.assertEquals(resp.content_length, len(body))
|
||||
|
||||
# body and headers with content_length exist but no app_iter
|
||||
body = 'ok'
|
||||
resp = swift.common.swob.Response(
|
||||
body=body, headers={'Content-Length': '5'})
|
||||
self.assertEquals(resp.body, body)
|
||||
self.assertEquals(resp.content_length, len(body))
|
||||
|
||||
# body and headers with no content_length exist but no app_iter
|
||||
body = 'ok'
|
||||
resp = swift.common.swob.Response(body=body, headers={})
|
||||
self.assertEquals(resp.body, body)
|
||||
self.assertEquals(resp.content_length, len(body))
|
||||
|
||||
# body, headers with content_length and app_iter exist
|
||||
resp = swift.common.swob.Response(
|
||||
body='ok', headers={'Content-Length': '5'}, app_iter=iter([]))
|
||||
self.assertEquals(resp.content_length, 5)
|
||||
self.assertEquals(resp.body, '')
|
||||
|
||||
# headers with content_length and app_iter exist but no body
|
||||
resp = swift.common.swob.Response(
|
||||
headers={'Content-Length': '5'}, app_iter=iter([]))
|
||||
self.assertEquals(resp.content_length, 5)
|
||||
self.assertEquals(resp.body, '')
|
||||
|
||||
# app_iter exists but no body and headers
|
||||
resp = swift.common.swob.Response(app_iter=iter([]))
|
||||
self.assertEquals(resp.content_length, None)
|
||||
self.assertEquals(resp.body, '')
|
||||
|
||||
|
||||
class TestUTC(unittest.TestCase):
|
||||
def test_tzname(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user