From: YOKOTA Hiroshi <yokota.hgml@gmail.com>
Date: Sat, 22 Oct 2022 18:33:07 +0900
Subject: IPv6 requires [] for host:port style notation

ex)
  IPv4: 127.0.0.1:8080
  IPv6: [::1]:8080
---
 src/calibre/gui2/actions/device.py     | 12 ++++++++++++
 src/calibre/gui2/preferences/server.py | 12 ++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/src/calibre/gui2/actions/device.py b/src/calibre/gui2/actions/device.py
index 2921b1d..0f22394 100644
--- a/src/calibre/gui2/actions/device.py
+++ b/src/calibre/gui2/actions/device.py
@@ -16,10 +16,22 @@ from calibre.utils.smtp import config as email_config
 
 
 def local_url_for_content_server():
+    def is_ipv6_addr(addr):
+        import socket
+        try:
+            socket.inet_pton(socket.AF_INET6, addr)
+            return True
+        except OSError:
+            return False
+
     from calibre.srv.opts import server_config
     opts = server_config()
     interface = opts.listen_on or '0.0.0.0'
     interface = {'0.0.0.0': '127.0.0.1', '::':'::1'}.get(interface)
+
+    if is_ipv6_addr(interface):
+        interface = f'[{interface}]'
+
     protocol = 'https' if opts.ssl_certfile and opts.ssl_keyfile else 'http'
     prefix = opts.url_prefix or ''
     port = opts.port
diff --git a/src/calibre/gui2/preferences/server.py b/src/calibre/gui2/preferences/server.py
index e7c10a8..ef9f130 100644
--- a/src/calibre/gui2/preferences/server.py
+++ b/src/calibre/gui2/preferences/server.py
@@ -1299,10 +1299,22 @@ class ConfigWidget(ConfigWidgetBase):
         self.stopping_msg.accept()
 
     def test_server(self):
+        def is_ipv6_addr(addr):
+            import socket
+            try:
+                socket.inet_pton(socket.AF_INET6, addr)
+                return True
+            except OSError:
+                return False
+
         prefix = self.advanced_tab.get('url_prefix') or ''
         protocol = 'https' if self.advanced_tab.has_ssl else 'http'
         lo = self.advanced_tab.get('listen_on') or '0.0.0.0'
         lo = {'0.0.0.0': '127.0.0.1', '::':'::1'}.get(lo)
+
+        if is_ipv6_addr(lo):
+            lo = f'[{lo}]'
+
         url = '{protocol}://{interface}:{port}{prefix}'.format(
             protocol=protocol, interface=lo,
             port=self.main_tab.opt_port.value(), prefix=prefix)
