control: tags -1 patch
I have a fix for this issue that allows calypso to listen on addresses
from addressing families other than AF_INET. This means that by default,
not specifying anything, the server will typically listen on :: and
service IPv4 addresses too.
I could not clone the specified upstream repo but did add a merge
request to the maintainer repo so please use that or the following patch
at your convenience!
Thank you,
Andrew
From 8c161af0febb99bfb956ff5793ac378581230129 Mon Sep 17 00:00:00 2001
From: Andrew Bower <andrew@bower.uk>
Date: Tue, 22 Oct 2024 23:15:43 +0100
Subject: [PATCH] Listen on appropriate addressing family
Rather than only listening on AF_INET, regardless of the addressing
family needed to support the supplied hostname, listen on the addressing
family of the first result from getaddrinfo() after re-ordering to make
sure AF_INET6 addresses come first.
This enables dual-stack listening by default with no hostname specified.
---
calypso/__init__.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/calypso/__init__.py b/calypso/__init__.py
index 7c9a81b..d3285c9 100644
--- a/calypso/__init__.py
+++ b/calypso/__init__.py
@@ -99,6 +99,22 @@ def _check(request, function):
# pylint: enable=W0212
+def resolve_server_address(address):
+ """Get server address details from string."""
+ (host, port) = address
+ addrs = socket.getaddrinfo(None if host == '' else host, port,
+ type=socket.SOCK_STREAM,
+ flags=socket.AI_PASSIVE)
+
+ # Put IPv6 addresses first, resulting in dual stack listener by default,
+ # otherwise preserving ordering.
+ inorder = [a for a in addrs if a[0] == socket.AF_INET6]
+ inorder.extend([a for a in addrs if a[0] != socket.AF_INET6])
+
+ # Ideally we would listen on each returned address separately.
+ return inorder[0] if inorder else None
+
+
class HTTPServer(server.HTTPServer):
"""HTTP server."""
PROTOCOL = "http"
@@ -107,6 +123,9 @@ class HTTPServer(server.HTTPServer):
# pylint: disable=W0231
def __init__(self, address, handler):
"""Create server."""
+ addrinfo = resolve_server_address(address)
+ self.address_family = addrinfo[0]
+ self.socket_type = addrinfo[1]
http_server.__init__(self, address, handler)
self.acl = acl.load()
# pylint: enable=W0231