Don't (mistakenly) set HTTP 204 on controllers which set response.body_file.

Fixes bug 1339121

Change-Id: I70785315837b3907b63bb10565f3ccdf07559e8d
This commit is contained in:
Ryan Petrello
2014-07-08 14:41:50 -04:00
parent 2260909302
commit 1a2933e23f
2 changed files with 105 additions and 2 deletions

View File

@@ -2,11 +2,12 @@ try:
from simplejson import dumps, loads
except ImportError: # pragma: no cover
from json import dumps, loads # noqa
from itertools import chain
from itertools import chain, tee
from mimetypes import guess_type, add_type
from os.path import splitext
import logging
import operator
import types
import six
@@ -566,7 +567,26 @@ class PecanBase(object):
elif result:
resp.body = result
elif response.status_int == 200:
resp.status = 204
# If the response is a generator...
if isinstance(response.app_iter, types.GeneratorType):
# Split the generator into two so we can peek at one of them
# and determine if there is any response body content
a, b = tee(response.app_iter)
try:
next(a)
except StopIteration:
# If we hit StopIteration, the body is empty
resp.status = 204
finally:
resp.app_iter = b
else:
text = None
if response.charset:
# `response.text` cannot be accessed without a charset
# (because we don't know which encoding to use)
text = response.text
if not any((response.body, text)):
resp.status = 204
if resp.status_int in (204, 304):
resp.content_type = None

View File

@@ -44,6 +44,30 @@ class TestEmptyContent(PecanTestCase):
def index(self):
pass
@expose()
def explicit_body(self):
response.body = b_('Hello, World!')
@expose()
def empty_body(self):
response.body = b_('')
@expose()
def explicit_text(self):
response.text = six.text_type('Hello, World!')
@expose()
def empty_text(self):
response.text = six.text_type('')
@expose()
def explicit_json(self):
response.json = {'foo': 'bar'}
@expose()
def explicit_json_body(self):
response.json_body = {'foo': 'bar'}
return TestApp(Pecan(RootController()))
def test_empty_index(self):
@@ -53,6 +77,65 @@ class TestEmptyContent(PecanTestCase):
self.assertEqual(r.headers['Content-Length'], '0')
self.assertEqual(len(r.body), 0)
def test_explicit_body(self):
r = self.app_.get('/explicit_body/')
self.assertEqual(r.status_int, 200)
self.assertEqual(r.body, b_('Hello, World!'))
def test_empty_body(self):
r = self.app_.get('/empty_body/')
self.assertEqual(r.status_int, 204)
self.assertEqual(r.body, b_(''))
def test_explicit_text(self):
r = self.app_.get('/explicit_text/')
self.assertEqual(r.status_int, 200)
self.assertEqual(r.body, b_('Hello, World!'))
def test_empty_text(self):
r = self.app_.get('/empty_text/')
self.assertEqual(r.status_int, 204)
self.assertEqual(r.body, b_(''))
def test_explicit_json(self):
r = self.app_.get('/explicit_json/')
self.assertEqual(r.status_int, 200)
json_resp = json.loads(r.body.decode())
assert json_resp == {'foo': 'bar'}
def test_explicit_json_body(self):
r = self.app_.get('/explicit_json_body/')
self.assertEqual(r.status_int, 200)
json_resp = json.loads(r.body.decode())
assert json_resp == {'foo': 'bar'}
class TestAppIterFile(PecanTestCase):
@property
def app_(self):
class RootController(object):
@expose()
def index(self):
body = six.BytesIO(b_('Hello, World!'))
response.body_file = body
@expose()
def empty(self):
body = six.BytesIO(b_(''))
response.body_file = body
return TestApp(Pecan(RootController()))
def test_body_generator(self):
r = self.app_.get('/')
self.assertEqual(r.status_int, 200)
assert r.body == b_('Hello, World!')
def test_empty_body_generator(self):
r = self.app_.get('/empty')
self.assertEqual(r.status_int, 204)
assert len(r.body) == 0
class TestIndexRouting(PecanTestCase):