Fix a bug in extension-based content-type guessing with a trailing slash.

Change-Id: I9b7e96ea1541af8b8964b95befa814297f404cd1
This commit is contained in:
Ryan Petrello
2015-06-25 13:57:47 -04:00
parent 8d4ce2b69b
commit b14f4aa168
2 changed files with 52 additions and 15 deletions

View File

@@ -445,13 +445,13 @@ class PecanBase(object):
if self.guess_content_type_from_ext \
and not pecan_state['content_type'] \
and '.' in path:
new_path, extension = splitext(path)
_, extension = splitext(path.rstrip('/'))
# preface with a letter to ensure compat for 2.5
potential_type = guess_type('x' + extension)[0]
if potential_type is not None:
path = new_path
if extension and potential_type is not None:
path = ''.join(path.rsplit(extension, 1))
pecan_state['extension'] = extension
pecan_state['content_type'] = potential_type

View File

@@ -1401,24 +1401,28 @@ class TestFileTypeExtensions(PecanTestCase):
return TestApp(Pecan(RootController()))
def test_html_extension(self):
r = self.app_.get('/index.html')
assert r.status_int == 200
assert r.body == b_('.html')
for path in ('/index.html', '/index.html/'):
r = self.app_.get(path)
assert r.status_int == 200
assert r.body == b_('.html')
def test_image_extension(self):
r = self.app_.get('/image.png')
assert r.status_int == 200
assert r.body == b_('.png')
for path in ('/index.png', '/index.png/'):
r = self.app_.get(path)
assert r.status_int == 200
assert r.body == b_('.png')
def test_hidden_file(self):
r = self.app_.get('/.vimrc')
assert r.status_int == 204
assert r.body == b_('')
for path in ('/.vimrc', '/.vimrc/'):
r = self.app_.get(path)
assert r.status_int == 204
assert r.body == b_('')
def test_multi_dot_extension(self):
r = self.app_.get('/gradient.min.js')
assert r.status_int == 200
assert r.body == b_('.js')
for path in ('/gradient.min.js', '/gradient.min.js/'):
r = self.app_.get(path)
assert r.status_int == 200
assert r.body == b_('.js')
def test_bad_content_type(self):
class RootController(object):
@@ -1469,6 +1473,39 @@ class TestFileTypeExtensions(PecanTestCase):
assert r.status_int == 200
assert r.body == b_('SOME VALUE')
def test_content_type_guessing_disabled(self):
class ResourceController(object):
def __init__(self, name):
self.name = name
assert self.name == 'file.html'
@expose('json')
def index(self):
return dict(name=self.name)
class RootController(object):
@expose()
def _lookup(self, name, *remainder):
return ResourceController(name), remainder
app = TestApp(
Pecan(RootController(), guess_content_type_from_ext=False)
)
r = app.get('/file.html/')
assert r.status_int == 200
result = dict(json.loads(r.body.decode()))
assert result == {'name': 'file.html'}
r = app.get('/file.html')
assert r.status_int == 302
r = r.follow()
result = dict(json.loads(r.body.decode()))
assert result == {'name': 'file.html'}
class TestContentTypeByAcceptHeaders(PecanTestCase):