Skip to content

Commit

Permalink
Support str and bytes for UNIX socket addresses (#1882)
Browse files Browse the repository at this point in the history
Some systems report UNIX socket addresses as bytes while others will
report it as a unicode string type. This patch improves socket type
detection code to support both.

Fix #1861
  • Loading branch information
tilgovi authored and benoitc committed Sep 24, 2018
1 parent 30554fd commit e179dc2
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
4 changes: 2 additions & 2 deletions gunicorn/http/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ def parse_headers(self, data):
secure_scheme_headers = cfg.secure_scheme_headers
elif isinstance(self.unreader, SocketUnreader):
remote_addr = self.unreader.sock.getpeername()
if isinstance(remote_addr, tuple):
if self.unreader.sock.family in (socket.AF_INET, socket.AF_INET6):
remote_host = remote_addr[0]
if remote_host in cfg.forwarded_allow_ips:
secure_scheme_headers = cfg.secure_scheme_headers
elif isinstance(remote_addr, str):
elif self.unreader.sock.family == socket.AF_UNIX:
secure_scheme_headers = cfg.secure_scheme_headers

# Parse headers into key/value pairs paying attention
Expand Down
2 changes: 1 addition & 1 deletion gunicorn/sock.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def _sock_type(addr):
sock_type = TCP6Socket
else:
sock_type = TCPSocket
elif isinstance(addr, str):
elif isinstance(addr, (str, bytes)):
sock_type = UnixSocket
else:
raise TypeError("Unable to create socket from: %r" % addr)
Expand Down
21 changes: 21 additions & 0 deletions tests/test_sock.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@
from gunicorn import sock


@mock.patch('os.stat')
def test_create_sockets_unix_bytes(stat):
conf = mock.Mock(address=[b'127.0.0.1:8000'])
log = mock.Mock()
with mock.patch.object(sock.UnixSocket, '__init__', lambda *args: None):
listeners = sock.create_sockets(conf, log)
assert len(listeners) == 1
print(type(listeners[0]))
assert isinstance(listeners[0], sock.UnixSocket)


@mock.patch('os.stat')
def test_create_sockets_unix_strings(stat):
conf = mock.Mock(address=['127.0.0.1:8000'])
log = mock.Mock()
with mock.patch.object(sock.UnixSocket, '__init__', lambda *args: None):
listeners = sock.create_sockets(conf, log)
assert len(listeners) == 1
assert isinstance(listeners[0], sock.UnixSocket)


def test_socket_close():
listener1 = mock.Mock()
listener1.getsockname.return_value = ('127.0.0.1', '80')
Expand Down

0 comments on commit e179dc2

Please sign in to comment.