We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Standalone server waits forever to drain clients during shutdown
Originally discovered in [a help thread on the forums](https://community.letsencrypt.org/t/certbot-hangs-on-stopping-server/102450?u=_az).

## My operating system is (include version):
Ubuntu 19.04

## I installed Certbot with (certbot-auto, OS package manager, pip, etc):
certbot-auto

## I ran this command and it produced this output:
    sudo certbot-auto certonly -d certbot.eff.org --standalone --dry-run

and simultaneously in a second terminal:

    nc -vvv localhost 80

Causes an infinite hang until the `nc` client disconnects:

    2019-09-20 19:29:28,932:DEBUG:certbot.error_handler:Calling registered functions
    2019-09-20 19:29:28,932:INFO:certbot.auth_handler:Cleaning up challenges
    2019-09-20 19:29:28,932:DEBUG:certbot.plugins.standalone:Stopping server at :::80...

## Certbot's behavior differed from what I expected because:
The standalone servers should not wait forever for clients to drain. I don't think they should wait at all and instead should just close the server socket. There is no reason to expect further legitimate traffic to the server. 

If a very patient internet crawler happens to hit the port, we need to dispatch of it quickly.

It may be appropriate to also add read and write timeouts to the socket, since it is practically always going to be exposed to the internet.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `acme/acme/standalone.py`
Content:
```
1 """Support for standalone client challenge solvers. """
2 import collections
3 import functools
4 import logging
5 import socket
6 import threading
7 
8 from six.moves import BaseHTTPServer  # type: ignore
9 from six.moves import http_client
10 from six.moves import socketserver  # type: ignore
11 
12 from acme import challenges
13 from acme import crypto_util
14 from acme.magic_typing import List
15 
16 logger = logging.getLogger(__name__)
17 
18 
19 class TLSServer(socketserver.TCPServer):
20     """Generic TLS Server."""
21 
22     def __init__(self, *args, **kwargs):
23         self.ipv6 = kwargs.pop("ipv6", False)
24         if self.ipv6:
25             self.address_family = socket.AF_INET6
26         else:
27             self.address_family = socket.AF_INET
28         self.certs = kwargs.pop("certs", {})
29         self.method = kwargs.pop(
30             "method", crypto_util._DEFAULT_SSL_METHOD)
31         self.allow_reuse_address = kwargs.pop("allow_reuse_address", True)
32         socketserver.TCPServer.__init__(self, *args, **kwargs)
33 
34     def _wrap_sock(self):
35         self.socket = crypto_util.SSLSocket(
36             self.socket, cert_selection=self._cert_selection,
37             alpn_selection=getattr(self, '_alpn_selection', None),
38             method=self.method)
39 
40     def _cert_selection(self, connection):  # pragma: no cover
41         """Callback selecting certificate for connection."""
42         server_name = connection.get_servername()
43         return self.certs.get(server_name, None)
44 
45     def server_bind(self):
46         self._wrap_sock()
47         return socketserver.TCPServer.server_bind(self)
48 
49 
50 class ACMEServerMixin:
51     """ACME server common settings mixin."""
52     # TODO: c.f. #858
53     server_version = "ACME client standalone challenge solver"
54     allow_reuse_address = True
55 
56 
57 class BaseDualNetworkedServers(object):
58     """Base class for a pair of IPv6 and IPv4 servers that tries to do everything
59        it's asked for both servers, but where failures in one server don't
60        affect the other.
61 
62        If two servers are instantiated, they will serve on the same port.
63        """
64 
65     def __init__(self, ServerClass, server_address, *remaining_args, **kwargs):
66         port = server_address[1]
67         self.threads = [] # type: List[threading.Thread]
68         self.servers = [] # type: List[ACMEServerMixin]
69 
70         # Must try True first.
71         # Ubuntu, for example, will fail to bind to IPv4 if we've already bound
72         # to IPv6. But that's ok, since it will accept IPv4 connections on the IPv6
73         # socket. On the other hand, FreeBSD will successfully bind to IPv4 on the
74         # same port, which means that server will accept the IPv4 connections.
75         # If Python is compiled without IPv6, we'll error out but (probably) successfully
76         # create the IPv4 server.
77         for ip_version in [True, False]:
78             try:
79                 kwargs["ipv6"] = ip_version
80                 new_address = (server_address[0],) + (port,) + server_address[2:]
81                 new_args = (new_address,) + remaining_args
82                 server = ServerClass(*new_args, **kwargs)
83                 logger.debug(
84                     "Successfully bound to %s:%s using %s", new_address[0],
85                     new_address[1], "IPv6" if ip_version else "IPv4")
86             except socket.error:
87                 if self.servers:
88                     # Already bound using IPv6.
89                     logger.debug(
90                         "Certbot wasn't able to bind to %s:%s using %s, this "
91                         "is often expected due to the dual stack nature of "
92                         "IPv6 socket implementations.",
93                         new_address[0], new_address[1],
94                         "IPv6" if ip_version else "IPv4")
95                 else:
96                     logger.debug(
97                         "Failed to bind to %s:%s using %s", new_address[0],
98                         new_address[1], "IPv6" if ip_version else "IPv4")
99             else:
100                 self.servers.append(server)
101                 # If two servers are set up and port 0 was passed in, ensure we always
102                 # bind to the same port for both servers.
103                 port = server.socket.getsockname()[1]
104         if not self.servers:
105             raise socket.error("Could not bind to IPv4 or IPv6.")
106 
107     def serve_forever(self):
108         """Wraps socketserver.TCPServer.serve_forever"""
109         for server in self.servers:
110             thread = threading.Thread(
111                 target=server.serve_forever)
112             thread.start()
113             self.threads.append(thread)
114 
115     def getsocknames(self):
116         """Wraps socketserver.TCPServer.socket.getsockname"""
117         return [server.socket.getsockname() for server in self.servers]
118 
119     def shutdown_and_server_close(self):
120         """Wraps socketserver.TCPServer.shutdown, socketserver.TCPServer.server_close, and
121            threading.Thread.join"""
122         for server in self.servers:
123             server.shutdown()
124             server.server_close()
125         for thread in self.threads:
126             thread.join()
127         self.threads = []
128 
129 
130 class TLSALPN01Server(TLSServer, ACMEServerMixin):
131     """TLSALPN01 Server."""
132 
133     ACME_TLS_1_PROTOCOL = b"acme-tls/1"
134 
135     def __init__(self, server_address, certs, challenge_certs, ipv6=False):
136         TLSServer.__init__(
137             self, server_address, _BaseRequestHandlerWithLogging, certs=certs,
138             ipv6=ipv6)
139         self.challenge_certs = challenge_certs
140 
141     def _cert_selection(self, connection):
142         # TODO: We would like to serve challenge cert only if asked for it via
143         # ALPN. To do this, we need to retrieve the list of protos from client
144         # hello, but this is currently impossible with openssl [0], and ALPN
145         # negotiation is done after cert selection.
146         # Therefore, currently we always return challenge cert, and terminate
147         # handshake in alpn_selection() if ALPN protos are not what we expect.
148         # [0] https://github.com/openssl/openssl/issues/4952
149         server_name = connection.get_servername()
150         logger.debug("Serving challenge cert for server name %s", server_name)
151         return self.challenge_certs.get(server_name, None)
152 
153     def _alpn_selection(self, _connection, alpn_protos):
154         """Callback to select alpn protocol."""
155         if len(alpn_protos) == 1 and alpn_protos[0] == self.ACME_TLS_1_PROTOCOL:
156             logger.debug("Agreed on %s ALPN", self.ACME_TLS_1_PROTOCOL)
157             return self.ACME_TLS_1_PROTOCOL
158         logger.debug("Cannot agree on ALPN proto. Got: %s", str(alpn_protos))
159         # Explicitly close the connection now, by returning an empty string.
160         # See https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_alpn_select_callback  # pylint: disable=line-too-long
161         return b""
162 
163 
164 class HTTPServer(BaseHTTPServer.HTTPServer):
165     """Generic HTTP Server."""
166 
167     def __init__(self, *args, **kwargs):
168         self.ipv6 = kwargs.pop("ipv6", False)
169         if self.ipv6:
170             self.address_family = socket.AF_INET6
171         else:
172             self.address_family = socket.AF_INET
173         BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
174 
175 
176 class HTTP01Server(HTTPServer, ACMEServerMixin):
177     """HTTP01 Server."""
178 
179     def __init__(self, server_address, resources, ipv6=False):
180         HTTPServer.__init__(
181             self, server_address, HTTP01RequestHandler.partial_init(
182                 simple_http_resources=resources), ipv6=ipv6)
183 
184 
185 class HTTP01DualNetworkedServers(BaseDualNetworkedServers):
186     """HTTP01Server Wrapper. Tries everything for both. Failures for one don't
187        affect the other."""
188 
189     def __init__(self, *args, **kwargs):
190         BaseDualNetworkedServers.__init__(self, HTTP01Server, *args, **kwargs)
191 
192 
193 class HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
194     """HTTP01 challenge handler.
195 
196     Adheres to the stdlib's `socketserver.BaseRequestHandler` interface.
197 
198     :ivar set simple_http_resources: A set of `HTTP01Resource`
199         objects. TODO: better name?
200 
201     """
202     HTTP01Resource = collections.namedtuple(
203         "HTTP01Resource", "chall response validation")
204 
205     def __init__(self, *args, **kwargs):
206         self.simple_http_resources = kwargs.pop("simple_http_resources", set())
207         BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
208 
209     def log_message(self, format, *args):  # pylint: disable=redefined-builtin
210         """Log arbitrary message."""
211         logger.debug("%s - - %s", self.client_address[0], format % args)
212 
213     def handle(self):
214         """Handle request."""
215         self.log_message("Incoming request")
216         BaseHTTPServer.BaseHTTPRequestHandler.handle(self)
217 
218     def do_GET(self):  # pylint: disable=invalid-name,missing-function-docstring
219         if self.path == "/":
220             self.handle_index()
221         elif self.path.startswith("/" + challenges.HTTP01.URI_ROOT_PATH):
222             self.handle_simple_http_resource()
223         else:
224             self.handle_404()
225 
226     def handle_index(self):
227         """Handle index page."""
228         self.send_response(200)
229         self.send_header("Content-Type", "text/html")
230         self.end_headers()
231         self.wfile.write(self.server.server_version.encode())
232 
233     def handle_404(self):
234         """Handler 404 Not Found errors."""
235         self.send_response(http_client.NOT_FOUND, message="Not Found")
236         self.send_header("Content-type", "text/html")
237         self.end_headers()
238         self.wfile.write(b"404")
239 
240     def handle_simple_http_resource(self):
241         """Handle HTTP01 provisioned resources."""
242         for resource in self.simple_http_resources:
243             if resource.chall.path == self.path:
244                 self.log_message("Serving HTTP01 with token %r",
245                                  resource.chall.encode("token"))
246                 self.send_response(http_client.OK)
247                 self.end_headers()
248                 self.wfile.write(resource.validation.encode())
249                 return
250         else:  # pylint: disable=useless-else-on-loop
251             self.log_message("No resources to serve")
252         self.log_message("%s does not correspond to any resource. ignoring",
253                          self.path)
254 
255     @classmethod
256     def partial_init(cls, simple_http_resources):
257         """Partially initialize this handler.
258 
259         This is useful because `socketserver.BaseServer` takes
260         uninitialized handler and initializes it with the current
261         request.
262 
263         """
264         return functools.partial(
265             cls, simple_http_resources=simple_http_resources)
266 
267 
268 class _BaseRequestHandlerWithLogging(socketserver.BaseRequestHandler):
269     """BaseRequestHandler with logging."""
270 
271     def log_message(self, format, *args):  # pylint: disable=redefined-builtin
272         """Log arbitrary message."""
273         logger.debug("%s - - %s", self.client_address[0], format % args)
274 
275     def handle(self):
276         """Handle request."""
277         self.log_message("Incoming request")
278         socketserver.BaseRequestHandler.handle(self)
279
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/acme/acme/standalone.py b/acme/acme/standalone.py
--- a/acme/acme/standalone.py
+++ b/acme/acme/standalone.py
@@ -176,10 +176,10 @@
 class HTTP01Server(HTTPServer, ACMEServerMixin):
     """HTTP01 Server."""
 
-    def __init__(self, server_address, resources, ipv6=False):
+    def __init__(self, server_address, resources, ipv6=False, timeout=30):
         HTTPServer.__init__(
             self, server_address, HTTP01RequestHandler.partial_init(
-                simple_http_resources=resources), ipv6=ipv6)
+                simple_http_resources=resources, timeout=timeout), ipv6=ipv6)
 
 
 class HTTP01DualNetworkedServers(BaseDualNetworkedServers):
@@ -204,6 +204,7 @@
 
     def __init__(self, *args, **kwargs):
         self.simple_http_resources = kwargs.pop("simple_http_resources", set())
+        self.timeout = kwargs.pop('timeout', 30)
         BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
 
     def log_message(self, format, *args):  # pylint: disable=redefined-builtin
@@ -253,7 +254,7 @@
                          self.path)
 
     @classmethod
-    def partial_init(cls, simple_http_resources):
+    def partial_init(cls, simple_http_resources, timeout):
         """Partially initialize this handler.
 
         This is useful because `socketserver.BaseServer` takes
@@ -262,7 +263,8 @@
 
         """
         return functools.partial(
-            cls, simple_http_resources=simple_http_resources)
+            cls, simple_http_resources=simple_http_resources,
+            timeout=timeout)
 
 
 class _BaseRequestHandlerWithLogging(socketserver.BaseRequestHandler):

{"golden_diff": "diff --git a/acme/acme/standalone.py b/acme/acme/standalone.py\n--- a/acme/acme/standalone.py\n+++ b/acme/acme/standalone.py\n@@ -176,10 +176,10 @@\n class HTTP01Server(HTTPServer, ACMEServerMixin):\n     \"\"\"HTTP01 Server.\"\"\"\n \n-    def __init__(self, server_address, resources, ipv6=False):\n+    def __init__(self, server_address, resources, ipv6=False, timeout=30):\n         HTTPServer.__init__(\n             self, server_address, HTTP01RequestHandler.partial_init(\n-                simple_http_resources=resources), ipv6=ipv6)\n+                simple_http_resources=resources, timeout=timeout), ipv6=ipv6)\n \n \n class HTTP01DualNetworkedServers(BaseDualNetworkedServers):\n@@ -204,6 +204,7 @@\n \n     def __init__(self, *args, **kwargs):\n         self.simple_http_resources = kwargs.pop(\"simple_http_resources\", set())\n+        self.timeout = kwargs.pop('timeout', 30)\n         BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kwargs)\n \n     def log_message(self, format, *args):  # pylint: disable=redefined-builtin\n@@ -253,7 +254,7 @@\n                          self.path)\n \n     @classmethod\n-    def partial_init(cls, simple_http_resources):\n+    def partial_init(cls, simple_http_resources, timeout):\n         \"\"\"Partially initialize this handler.\n \n         This is useful because `socketserver.BaseServer` takes\n@@ -262,7 +263,8 @@\n \n         \"\"\"\n         return functools.partial(\n-            cls, simple_http_resources=simple_http_resources)\n+            cls, simple_http_resources=simple_http_resources,\n+            timeout=timeout)\n \n \n class _BaseRequestHandlerWithLogging(socketserver.BaseRequestHandler):\n", "issue": "Standalone server waits forever to drain clients during shutdown\nOriginally discovered in [a help thread on the forums](https://community.letsencrypt.org/t/certbot-hangs-on-stopping-server/102450?u=_az).\r\n\r\n## My operating system is (include version):\r\nUbuntu 19.04\r\n\r\n## I installed Certbot with (certbot-auto, OS package manager, pip, etc):\r\ncertbot-auto\r\n\r\n## I ran this command and it produced this output:\r\n    sudo certbot-auto certonly -d certbot.eff.org --standalone --dry-run\r\n\r\nand simultaneously in a second terminal:\r\n\r\n    nc -vvv localhost 80\r\n\r\nCauses an infinite hang until the `nc` client disconnects:\r\n\r\n    2019-09-20 19:29:28,932:DEBUG:certbot.error_handler:Calling registered functions\r\n    2019-09-20 19:29:28,932:INFO:certbot.auth_handler:Cleaning up challenges\r\n    2019-09-20 19:29:28,932:DEBUG:certbot.plugins.standalone:Stopping server at :::80...\r\n\r\n## Certbot's behavior differed from what I expected because:\r\nThe standalone servers should not wait forever for clients to drain. I don't think they should wait at all and instead should just close the server socket. There is no reason to expect further legitimate traffic to the server. \r\n\r\nIf a very patient internet crawler happens to hit the port, we need to dispatch of it quickly.\r\n\r\nIt may be appropriate to also add read and write timeouts to the socket, since it is practically always going to be exposed to the internet.\n", "before_files": [{"content": "\"\"\"Support for standalone client challenge solvers. \"\"\"\nimport collections\nimport functools\nimport logging\nimport socket\nimport threading\n\nfrom six.moves import BaseHTTPServer  # type: ignore\nfrom six.moves import http_client\nfrom six.moves import socketserver  # type: ignore\n\nfrom acme import challenges\nfrom acme import crypto_util\nfrom acme.magic_typing import List\n\nlogger = logging.getLogger(__name__)\n\n\nclass TLSServer(socketserver.TCPServer):\n    \"\"\"Generic TLS Server.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self.ipv6 = kwargs.pop(\"ipv6\", False)\n        if self.ipv6:\n            self.address_family = socket.AF_INET6\n        else:\n            self.address_family = socket.AF_INET\n        self.certs = kwargs.pop(\"certs\", {})\n        self.method = kwargs.pop(\n            \"method\", crypto_util._DEFAULT_SSL_METHOD)\n        self.allow_reuse_address = kwargs.pop(\"allow_reuse_address\", True)\n        socketserver.TCPServer.__init__(self, *args, **kwargs)\n\n    def _wrap_sock(self):\n        self.socket = crypto_util.SSLSocket(\n            self.socket, cert_selection=self._cert_selection,\n            alpn_selection=getattr(self, '_alpn_selection', None),\n            method=self.method)\n\n    def _cert_selection(self, connection):  # pragma: no cover\n        \"\"\"Callback selecting certificate for connection.\"\"\"\n        server_name = connection.get_servername()\n        return self.certs.get(server_name, None)\n\n    def server_bind(self):\n        self._wrap_sock()\n        return socketserver.TCPServer.server_bind(self)\n\n\nclass ACMEServerMixin:\n    \"\"\"ACME server common settings mixin.\"\"\"\n    # TODO: c.f. #858\n    server_version = \"ACME client standalone challenge solver\"\n    allow_reuse_address = True\n\n\nclass BaseDualNetworkedServers(object):\n    \"\"\"Base class for a pair of IPv6 and IPv4 servers that tries to do everything\n       it's asked for both servers, but where failures in one server don't\n       affect the other.\n\n       If two servers are instantiated, they will serve on the same port.\n       \"\"\"\n\n    def __init__(self, ServerClass, server_address, *remaining_args, **kwargs):\n        port = server_address[1]\n        self.threads = [] # type: List[threading.Thread]\n        self.servers = [] # type: List[ACMEServerMixin]\n\n        # Must try True first.\n        # Ubuntu, for example, will fail to bind to IPv4 if we've already bound\n        # to IPv6. But that's ok, since it will accept IPv4 connections on the IPv6\n        # socket. On the other hand, FreeBSD will successfully bind to IPv4 on the\n        # same port, which means that server will accept the IPv4 connections.\n        # If Python is compiled without IPv6, we'll error out but (probably) successfully\n        # create the IPv4 server.\n        for ip_version in [True, False]:\n            try:\n                kwargs[\"ipv6\"] = ip_version\n                new_address = (server_address[0],) + (port,) + server_address[2:]\n                new_args = (new_address,) + remaining_args\n                server = ServerClass(*new_args, **kwargs)\n                logger.debug(\n                    \"Successfully bound to %s:%s using %s\", new_address[0],\n                    new_address[1], \"IPv6\" if ip_version else \"IPv4\")\n            except socket.error:\n                if self.servers:\n                    # Already bound using IPv6.\n                    logger.debug(\n                        \"Certbot wasn't able to bind to %s:%s using %s, this \"\n                        \"is often expected due to the dual stack nature of \"\n                        \"IPv6 socket implementations.\",\n                        new_address[0], new_address[1],\n                        \"IPv6\" if ip_version else \"IPv4\")\n                else:\n                    logger.debug(\n                        \"Failed to bind to %s:%s using %s\", new_address[0],\n                        new_address[1], \"IPv6\" if ip_version else \"IPv4\")\n            else:\n                self.servers.append(server)\n                # If two servers are set up and port 0 was passed in, ensure we always\n                # bind to the same port for both servers.\n                port = server.socket.getsockname()[1]\n        if not self.servers:\n            raise socket.error(\"Could not bind to IPv4 or IPv6.\")\n\n    def serve_forever(self):\n        \"\"\"Wraps socketserver.TCPServer.serve_forever\"\"\"\n        for server in self.servers:\n            thread = threading.Thread(\n                target=server.serve_forever)\n            thread.start()\n            self.threads.append(thread)\n\n    def getsocknames(self):\n        \"\"\"Wraps socketserver.TCPServer.socket.getsockname\"\"\"\n        return [server.socket.getsockname() for server in self.servers]\n\n    def shutdown_and_server_close(self):\n        \"\"\"Wraps socketserver.TCPServer.shutdown, socketserver.TCPServer.server_close, and\n           threading.Thread.join\"\"\"\n        for server in self.servers:\n            server.shutdown()\n            server.server_close()\n        for thread in self.threads:\n            thread.join()\n        self.threads = []\n\n\nclass TLSALPN01Server(TLSServer, ACMEServerMixin):\n    \"\"\"TLSALPN01 Server.\"\"\"\n\n    ACME_TLS_1_PROTOCOL = b\"acme-tls/1\"\n\n    def __init__(self, server_address, certs, challenge_certs, ipv6=False):\n        TLSServer.__init__(\n            self, server_address, _BaseRequestHandlerWithLogging, certs=certs,\n            ipv6=ipv6)\n        self.challenge_certs = challenge_certs\n\n    def _cert_selection(self, connection):\n        # TODO: We would like to serve challenge cert only if asked for it via\n        # ALPN. To do this, we need to retrieve the list of protos from client\n        # hello, but this is currently impossible with openssl [0], and ALPN\n        # negotiation is done after cert selection.\n        # Therefore, currently we always return challenge cert, and terminate\n        # handshake in alpn_selection() if ALPN protos are not what we expect.\n        # [0] https://github.com/openssl/openssl/issues/4952\n        server_name = connection.get_servername()\n        logger.debug(\"Serving challenge cert for server name %s\", server_name)\n        return self.challenge_certs.get(server_name, None)\n\n    def _alpn_selection(self, _connection, alpn_protos):\n        \"\"\"Callback to select alpn protocol.\"\"\"\n        if len(alpn_protos) == 1 and alpn_protos[0] == self.ACME_TLS_1_PROTOCOL:\n            logger.debug(\"Agreed on %s ALPN\", self.ACME_TLS_1_PROTOCOL)\n            return self.ACME_TLS_1_PROTOCOL\n        logger.debug(\"Cannot agree on ALPN proto. Got: %s\", str(alpn_protos))\n        # Explicitly close the connection now, by returning an empty string.\n        # See https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_alpn_select_callback  # pylint: disable=line-too-long\n        return b\"\"\n\n\nclass HTTPServer(BaseHTTPServer.HTTPServer):\n    \"\"\"Generic HTTP Server.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self.ipv6 = kwargs.pop(\"ipv6\", False)\n        if self.ipv6:\n            self.address_family = socket.AF_INET6\n        else:\n            self.address_family = socket.AF_INET\n        BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)\n\n\nclass HTTP01Server(HTTPServer, ACMEServerMixin):\n    \"\"\"HTTP01 Server.\"\"\"\n\n    def __init__(self, server_address, resources, ipv6=False):\n        HTTPServer.__init__(\n            self, server_address, HTTP01RequestHandler.partial_init(\n                simple_http_resources=resources), ipv6=ipv6)\n\n\nclass HTTP01DualNetworkedServers(BaseDualNetworkedServers):\n    \"\"\"HTTP01Server Wrapper. Tries everything for both. Failures for one don't\n       affect the other.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        BaseDualNetworkedServers.__init__(self, HTTP01Server, *args, **kwargs)\n\n\nclass HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):\n    \"\"\"HTTP01 challenge handler.\n\n    Adheres to the stdlib's `socketserver.BaseRequestHandler` interface.\n\n    :ivar set simple_http_resources: A set of `HTTP01Resource`\n        objects. TODO: better name?\n\n    \"\"\"\n    HTTP01Resource = collections.namedtuple(\n        \"HTTP01Resource\", \"chall response validation\")\n\n    def __init__(self, *args, **kwargs):\n        self.simple_http_resources = kwargs.pop(\"simple_http_resources\", set())\n        BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kwargs)\n\n    def log_message(self, format, *args):  # pylint: disable=redefined-builtin\n        \"\"\"Log arbitrary message.\"\"\"\n        logger.debug(\"%s - - %s\", self.client_address[0], format % args)\n\n    def handle(self):\n        \"\"\"Handle request.\"\"\"\n        self.log_message(\"Incoming request\")\n        BaseHTTPServer.BaseHTTPRequestHandler.handle(self)\n\n    def do_GET(self):  # pylint: disable=invalid-name,missing-function-docstring\n        if self.path == \"/\":\n            self.handle_index()\n        elif self.path.startswith(\"/\" + challenges.HTTP01.URI_ROOT_PATH):\n            self.handle_simple_http_resource()\n        else:\n            self.handle_404()\n\n    def handle_index(self):\n        \"\"\"Handle index page.\"\"\"\n        self.send_response(200)\n        self.send_header(\"Content-Type\", \"text/html\")\n        self.end_headers()\n        self.wfile.write(self.server.server_version.encode())\n\n    def handle_404(self):\n        \"\"\"Handler 404 Not Found errors.\"\"\"\n        self.send_response(http_client.NOT_FOUND, message=\"Not Found\")\n        self.send_header(\"Content-type\", \"text/html\")\n        self.end_headers()\n        self.wfile.write(b\"404\")\n\n    def handle_simple_http_resource(self):\n        \"\"\"Handle HTTP01 provisioned resources.\"\"\"\n        for resource in self.simple_http_resources:\n            if resource.chall.path == self.path:\n                self.log_message(\"Serving HTTP01 with token %r\",\n                                 resource.chall.encode(\"token\"))\n                self.send_response(http_client.OK)\n                self.end_headers()\n                self.wfile.write(resource.validation.encode())\n                return\n        else:  # pylint: disable=useless-else-on-loop\n            self.log_message(\"No resources to serve\")\n        self.log_message(\"%s does not correspond to any resource. ignoring\",\n                         self.path)\n\n    @classmethod\n    def partial_init(cls, simple_http_resources):\n        \"\"\"Partially initialize this handler.\n\n        This is useful because `socketserver.BaseServer` takes\n        uninitialized handler and initializes it with the current\n        request.\n\n        \"\"\"\n        return functools.partial(\n            cls, simple_http_resources=simple_http_resources)\n\n\nclass _BaseRequestHandlerWithLogging(socketserver.BaseRequestHandler):\n    \"\"\"BaseRequestHandler with logging.\"\"\"\n\n    def log_message(self, format, *args):  # pylint: disable=redefined-builtin\n        \"\"\"Log arbitrary message.\"\"\"\n        logger.debug(\"%s - - %s\", self.client_address[0], format % args)\n\n    def handle(self):\n        \"\"\"Handle request.\"\"\"\n        self.log_message(\"Incoming request\")\n        socketserver.BaseRequestHandler.handle(self)\n", "path": "acme/acme/standalone.py"}], "after_files": [{"content": "\"\"\"Support for standalone client challenge solvers. \"\"\"\nimport collections\nimport functools\nimport logging\nimport socket\nimport threading\n\nfrom six.moves import BaseHTTPServer  # type: ignore\nfrom six.moves import http_client\nfrom six.moves import socketserver  # type: ignore\n\nfrom acme import challenges\nfrom acme import crypto_util\nfrom acme.magic_typing import List\n\nlogger = logging.getLogger(__name__)\n\n\nclass TLSServer(socketserver.TCPServer):\n    \"\"\"Generic TLS Server.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self.ipv6 = kwargs.pop(\"ipv6\", False)\n        if self.ipv6:\n            self.address_family = socket.AF_INET6\n        else:\n            self.address_family = socket.AF_INET\n        self.certs = kwargs.pop(\"certs\", {})\n        self.method = kwargs.pop(\n            \"method\", crypto_util._DEFAULT_SSL_METHOD)\n        self.allow_reuse_address = kwargs.pop(\"allow_reuse_address\", True)\n        socketserver.TCPServer.__init__(self, *args, **kwargs)\n\n    def _wrap_sock(self):\n        self.socket = crypto_util.SSLSocket(\n            self.socket, cert_selection=self._cert_selection,\n            alpn_selection=getattr(self, '_alpn_selection', None),\n            method=self.method)\n\n    def _cert_selection(self, connection):  # pragma: no cover\n        \"\"\"Callback selecting certificate for connection.\"\"\"\n        server_name = connection.get_servername()\n        return self.certs.get(server_name, None)\n\n    def server_bind(self):\n        self._wrap_sock()\n        return socketserver.TCPServer.server_bind(self)\n\n\nclass ACMEServerMixin:\n    \"\"\"ACME server common settings mixin.\"\"\"\n    # TODO: c.f. #858\n    server_version = \"ACME client standalone challenge solver\"\n    allow_reuse_address = True\n\n\nclass BaseDualNetworkedServers(object):\n    \"\"\"Base class for a pair of IPv6 and IPv4 servers that tries to do everything\n       it's asked for both servers, but where failures in one server don't\n       affect the other.\n\n       If two servers are instantiated, they will serve on the same port.\n       \"\"\"\n\n    def __init__(self, ServerClass, server_address, *remaining_args, **kwargs):\n        port = server_address[1]\n        self.threads = [] # type: List[threading.Thread]\n        self.servers = [] # type: List[ACMEServerMixin]\n\n        # Must try True first.\n        # Ubuntu, for example, will fail to bind to IPv4 if we've already bound\n        # to IPv6. But that's ok, since it will accept IPv4 connections on the IPv6\n        # socket. On the other hand, FreeBSD will successfully bind to IPv4 on the\n        # same port, which means that server will accept the IPv4 connections.\n        # If Python is compiled without IPv6, we'll error out but (probably) successfully\n        # create the IPv4 server.\n        for ip_version in [True, False]:\n            try:\n                kwargs[\"ipv6\"] = ip_version\n                new_address = (server_address[0],) + (port,) + server_address[2:]\n                new_args = (new_address,) + remaining_args\n                server = ServerClass(*new_args, **kwargs)\n                logger.debug(\n                    \"Successfully bound to %s:%s using %s\", new_address[0],\n                    new_address[1], \"IPv6\" if ip_version else \"IPv4\")\n            except socket.error:\n                if self.servers:\n                    # Already bound using IPv6.\n                    logger.debug(\n                        \"Certbot wasn't able to bind to %s:%s using %s, this \"\n                        \"is often expected due to the dual stack nature of \"\n                        \"IPv6 socket implementations.\",\n                        new_address[0], new_address[1],\n                        \"IPv6\" if ip_version else \"IPv4\")\n                else:\n                    logger.debug(\n                        \"Failed to bind to %s:%s using %s\", new_address[0],\n                        new_address[1], \"IPv6\" if ip_version else \"IPv4\")\n            else:\n                self.servers.append(server)\n                # If two servers are set up and port 0 was passed in, ensure we always\n                # bind to the same port for both servers.\n                port = server.socket.getsockname()[1]\n        if not self.servers:\n            raise socket.error(\"Could not bind to IPv4 or IPv6.\")\n\n    def serve_forever(self):\n        \"\"\"Wraps socketserver.TCPServer.serve_forever\"\"\"\n        for server in self.servers:\n            thread = threading.Thread(\n                target=server.serve_forever)\n            thread.start()\n            self.threads.append(thread)\n\n    def getsocknames(self):\n        \"\"\"Wraps socketserver.TCPServer.socket.getsockname\"\"\"\n        return [server.socket.getsockname() for server in self.servers]\n\n    def shutdown_and_server_close(self):\n        \"\"\"Wraps socketserver.TCPServer.shutdown, socketserver.TCPServer.server_close, and\n           threading.Thread.join\"\"\"\n        for server in self.servers:\n            server.shutdown()\n            server.server_close()\n        for thread in self.threads:\n            thread.join()\n        self.threads = []\n\n\nclass TLSALPN01Server(TLSServer, ACMEServerMixin):\n    \"\"\"TLSALPN01 Server.\"\"\"\n\n    ACME_TLS_1_PROTOCOL = b\"acme-tls/1\"\n\n    def __init__(self, server_address, certs, challenge_certs, ipv6=False):\n        TLSServer.__init__(\n            self, server_address, _BaseRequestHandlerWithLogging, certs=certs,\n            ipv6=ipv6)\n        self.challenge_certs = challenge_certs\n\n    def _cert_selection(self, connection):\n        # TODO: We would like to serve challenge cert only if asked for it via\n        # ALPN. To do this, we need to retrieve the list of protos from client\n        # hello, but this is currently impossible with openssl [0], and ALPN\n        # negotiation is done after cert selection.\n        # Therefore, currently we always return challenge cert, and terminate\n        # handshake in alpn_selection() if ALPN protos are not what we expect.\n        # [0] https://github.com/openssl/openssl/issues/4952\n        server_name = connection.get_servername()\n        logger.debug(\"Serving challenge cert for server name %s\", server_name)\n        return self.challenge_certs.get(server_name, None)\n\n    def _alpn_selection(self, _connection, alpn_protos):\n        \"\"\"Callback to select alpn protocol.\"\"\"\n        if len(alpn_protos) == 1 and alpn_protos[0] == self.ACME_TLS_1_PROTOCOL:\n            logger.debug(\"Agreed on %s ALPN\", self.ACME_TLS_1_PROTOCOL)\n            return self.ACME_TLS_1_PROTOCOL\n        logger.debug(\"Cannot agree on ALPN proto. Got: %s\", str(alpn_protos))\n        # Explicitly close the connection now, by returning an empty string.\n        # See https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_alpn_select_callback  # pylint: disable=line-too-long\n        return b\"\"\n\n\nclass HTTPServer(BaseHTTPServer.HTTPServer):\n    \"\"\"Generic HTTP Server.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self.ipv6 = kwargs.pop(\"ipv6\", False)\n        if self.ipv6:\n            self.address_family = socket.AF_INET6\n        else:\n            self.address_family = socket.AF_INET\n        BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)\n\n\nclass HTTP01Server(HTTPServer, ACMEServerMixin):\n    \"\"\"HTTP01 Server.\"\"\"\n\n    def __init__(self, server_address, resources, ipv6=False, timeout=30):\n        HTTPServer.__init__(\n            self, server_address, HTTP01RequestHandler.partial_init(\n                simple_http_resources=resources, timeout=timeout), ipv6=ipv6)\n\n\nclass HTTP01DualNetworkedServers(BaseDualNetworkedServers):\n    \"\"\"HTTP01Server Wrapper. Tries everything for both. Failures for one don't\n       affect the other.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        BaseDualNetworkedServers.__init__(self, HTTP01Server, *args, **kwargs)\n\n\nclass HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):\n    \"\"\"HTTP01 challenge handler.\n\n    Adheres to the stdlib's `socketserver.BaseRequestHandler` interface.\n\n    :ivar set simple_http_resources: A set of `HTTP01Resource`\n        objects. TODO: better name?\n\n    \"\"\"\n    HTTP01Resource = collections.namedtuple(\n        \"HTTP01Resource\", \"chall response validation\")\n\n    def __init__(self, *args, **kwargs):\n        self.simple_http_resources = kwargs.pop(\"simple_http_resources\", set())\n        self.timeout = kwargs.pop('timeout', 30)\n        BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kwargs)\n\n    def log_message(self, format, *args):  # pylint: disable=redefined-builtin\n        \"\"\"Log arbitrary message.\"\"\"\n        logger.debug(\"%s - - %s\", self.client_address[0], format % args)\n\n    def handle(self):\n        \"\"\"Handle request.\"\"\"\n        self.log_message(\"Incoming request\")\n        BaseHTTPServer.BaseHTTPRequestHandler.handle(self)\n\n    def do_GET(self):  # pylint: disable=invalid-name,missing-function-docstring\n        if self.path == \"/\":\n            self.handle_index()\n        elif self.path.startswith(\"/\" + challenges.HTTP01.URI_ROOT_PATH):\n            self.handle_simple_http_resource()\n        else:\n            self.handle_404()\n\n    def handle_index(self):\n        \"\"\"Handle index page.\"\"\"\n        self.send_response(200)\n        self.send_header(\"Content-Type\", \"text/html\")\n        self.end_headers()\n        self.wfile.write(self.server.server_version.encode())\n\n    def handle_404(self):\n        \"\"\"Handler 404 Not Found errors.\"\"\"\n        self.send_response(http_client.NOT_FOUND, message=\"Not Found\")\n        self.send_header(\"Content-type\", \"text/html\")\n        self.end_headers()\n        self.wfile.write(b\"404\")\n\n    def handle_simple_http_resource(self):\n        \"\"\"Handle HTTP01 provisioned resources.\"\"\"\n        for resource in self.simple_http_resources:\n            if resource.chall.path == self.path:\n                self.log_message(\"Serving HTTP01 with token %r\",\n                                 resource.chall.encode(\"token\"))\n                self.send_response(http_client.OK)\n                self.end_headers()\n                self.wfile.write(resource.validation.encode())\n                return\n        else:  # pylint: disable=useless-else-on-loop\n            self.log_message(\"No resources to serve\")\n        self.log_message(\"%s does not correspond to any resource. ignoring\",\n                         self.path)\n\n    @classmethod\n    def partial_init(cls, simple_http_resources, timeout):\n        \"\"\"Partially initialize this handler.\n\n        This is useful because `socketserver.BaseServer` takes\n        uninitialized handler and initializes it with the current\n        request.\n\n        \"\"\"\n        return functools.partial(\n            cls, simple_http_resources=simple_http_resources,\n            timeout=timeout)\n\n\nclass _BaseRequestHandlerWithLogging(socketserver.BaseRequestHandler):\n    \"\"\"BaseRequestHandler with logging.\"\"\"\n\n    def log_message(self, format, *args):  # pylint: disable=redefined-builtin\n        \"\"\"Log arbitrary message.\"\"\"\n        logger.debug(\"%s - - %s\", self.client_address[0], format % args)\n\n    def handle(self):\n        \"\"\"Handle request.\"\"\"\n        self.log_message(\"Incoming request\")\n        socketserver.BaseRequestHandler.handle(self)\n", "path": "acme/acme/standalone.py"}]}