Commit fe19e932 authored by Jason Madden's avatar Jason Madden

Format the status code as a str on Python 3. Fixes #664.

parent 38e85ece
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
when logging) are much lighter weight. For example, they no longer when logging) are much lighter weight. For example, they no longer
allocate and then delete a :class:`~gevent.lock.Semaphore`, which is allocate and then delete a :class:`~gevent.lock.Semaphore`, which is
especially important for PyPy. especially important for PyPy.
- Request logging by :mod:`gevent.pywsgi` formats the status code
correctly on Python 3. Reported in :issue:`664` by Kevin Chen.
.. _details: https://mail.python.org/pipermail/cython-devel/2015-October/004571.html .. _details: https://mail.python.org/pipermail/cython-devel/2015-October/004571.html
......
...@@ -738,6 +738,7 @@ class WSGIHandler(object): ...@@ -738,6 +738,7 @@ class WSGIHandler(object):
code = int(status.split(' ', 1)[0]) code = int(status.split(' ', 1)[0])
self.status = status if not PY3 else status.encode("latin-1") self.status = status if not PY3 else status.encode("latin-1")
self._orig_status = status # Preserve the native string for logging
self.response_headers = response_headers self.response_headers = response_headers
self.code = code self.code = code
...@@ -784,7 +785,10 @@ class WSGIHandler(object): ...@@ -784,7 +785,10 @@ class WSGIHandler(object):
client_address or '-', client_address or '-',
now, now,
getattr(self, 'requestline', ''), getattr(self, 'requestline', ''),
(getattr(self, 'status', None) or '000').split()[0], # Use the native string version of the status, saved so we don't have to
# decode. But fallback to the encoded 'status' in case of subclasses
# (Is that really necessary? At least there's no overhead.)
(getattr(self, '_orig_status', None) or getattr(self, 'status', None) or '000').split()[0],
length, length,
delta) delta)
......
...@@ -1444,7 +1444,7 @@ class Test414(TestCase): ...@@ -1444,7 +1444,7 @@ class Test414(TestCase):
read_http(fd, code=414) read_http(fd, code=414)
class Test663(TestCase): class TestLogging(TestCase):
# Something that gets wrapped in a LoggingLogAdapter # Something that gets wrapped in a LoggingLogAdapter
class Logger(object): class Logger(object):
...@@ -1464,6 +1464,13 @@ class Test663(TestCase): ...@@ -1464,6 +1464,13 @@ class Test663(TestCase):
def init_logger(self): def init_logger(self):
return self.Logger() return self.Logger()
@staticmethod
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return [b'hello']
# Tests for issue #663
def test_proxy_methods_on_log(self): def test_proxy_methods_on_log(self):
# An object that looks like a logger gets wrapped # An object that looks like a logger gets wrapped
# with a proxy that # with a proxy that
...@@ -1481,6 +1488,12 @@ class Test663(TestCase): ...@@ -1481,6 +1488,12 @@ class Test663(TestCase):
del self.server.log.thing del self.server.log.thing
self.assertEqual(self.server.log.get_thing(), None) self.assertEqual(self.server.log.get_thing(), None)
def test_status_log(self):
# Issue 664: Make sure we format the status line as a string
self.urlopen()
self.assertTrue('"GET / HTTP/1.1" 200 ' in self.server.log.logged[1],
self.server.log.logged[1])
del CommonTests del CommonTests
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment