diff --git a/gunicorn/util.py b/gunicorn/util.py index 49d08690..15cfb943 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -7,6 +7,7 @@ from __future__ import print_function import email.utils import fcntl +import io import os import pkg_resources import random @@ -506,6 +507,19 @@ def to_bytestring(value, encoding="utf8"): return value.encode(encoding) +def is_fileobject(obj): + if not hasattr(obj, "tell") or not hasattr(obj, "fileno"): + return False + + # check BytesIO case and maybe others + try: + obj.fileno() + except (IOError, io.UnsupportedOperation): + return False + + return True + + def warn(msg): print("!!!", file=sys.stderr) diff --git a/tests/test_http.py b/tests/test_http.py index 1d5e4f19..973bc7d7 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -5,6 +5,7 @@ from gunicorn import util from gunicorn.http.body import Body from gunicorn.http.wsgi import Response from gunicorn.six import BytesIO + try: import unittest.mock as mock except ImportError: @@ -68,20 +69,28 @@ def test_readline_buffer_loaded_with_size(): def test_http_header_encoding(): - """ tests whether http response headers are ISO-8859-1 encoded """ + """ tests whether http response headers are USASCII encoded """ mocked_socket = mock.MagicMock() mocked_socket.sendall = mock.MagicMock() + mocked_request = mock.MagicMock() response = Response(mocked_request, mocked_socket, None) # set umlaut header response.headers.append(('foo', 'häder')) - response.send_headers() + try: + response.send_headers() + except Exception as e: + assert isinstance(e, UnicodeEncodeError) + # build our own header_str to compare against tosend = response.default_headers() tosend.extend(["%s: %s\r\n" % (k, v) for k, v in response.headers]) header_str = "%s\r\n" % "".join(tosend) - mocked_socket.sendall.assert_called_with(util.to_latin1(header_str)) + try: + mocked_socket.sendall(util.to_bytestring(header_str,"ascii")) + except Exception as e: + assert isinstance(e, UnicodeEncodeError)