diff options
| author | hodbn <hodbn@users.noreply.github.com> | 2020-07-16 09:05:57 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-16 11:05:57 -0500 |
| commit | 688584d692f3d77f5d6beca6bb97faef15f0977b (patch) | |
| tree | 5390f148b6e7682ac8eeeeaa549c1b27ff7ee4db /dummyserver | |
| parent | fe1f73b69838c04a516170478fd508966854c415 (diff) | |
| download | urllib3-688584d692f3d77f5d6beca6bb97faef15f0977b.tar.gz | |
Send "http/1.1" ALPN extension during TLS handshake
Diffstat (limited to 'dummyserver')
| -rw-r--r-- | dummyserver/handlers.py | 5 | ||||
| -rwxr-xr-x | dummyserver/server.py | 41 |
2 files changed, 45 insertions, 1 deletions
diff --git a/dummyserver/handlers.py b/dummyserver/handlers.py index 696dbab0..f199dee3 100644 --- a/dummyserver/handlers.py +++ b/dummyserver/handlers.py @@ -116,6 +116,11 @@ class TestingApp(RequestHandler): subject = dict((k, v) for (k, v) in [y for z in cert["subject"] for y in z]) return Response(json.dumps(subject)) + def alpn_protocol(self, request): + """Return the selected ALPN protocol.""" + proto = request.connection.stream.socket.selected_alpn_protocol() + return Response(proto.encode("utf8") if proto is not None else u"") + def source_address(self, request): """Return the requester's IP address.""" return Response(request.remote_ip) diff --git a/dummyserver/server.py b/dummyserver/server.py index 68f38353..f8b4dff5 100755 --- a/dummyserver/server.py +++ b/dummyserver/server.py @@ -15,6 +15,7 @@ import ssl from datetime import datetime from urllib3.exceptions import HTTPWarning +from urllib3.util import resolve_cert_reqs, resolve_ssl_version, ALPN_PROTOCOLS from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization @@ -33,6 +34,7 @@ DEFAULT_CERTS = { "keyfile": os.path.join(CERTS_PATH, "server.key"), "cert_reqs": ssl.CERT_OPTIONAL, "ca_certs": os.path.join(CERTS_PATH, "cacert.pem"), + "alpn_protocols": ALPN_PROTOCOLS, } DEFAULT_CA = os.path.join(CERTS_PATH, "cacert.pem") DEFAULT_CA_KEY = os.path.join(CERTS_PATH, "cacert.key") @@ -133,6 +135,39 @@ class SocketServerThread(threading.Thread): self.server = self._start_server() +def ssl_options_to_context( + keyfile=None, + certfile=None, + server_side=None, + cert_reqs=None, + ssl_version=None, + ca_certs=None, + do_handshake_on_connect=None, + suppress_ragged_eofs=None, + ciphers=None, + alpn_protocols=None, +): + """Return an equivalent SSLContext based on ssl.wrap_socket args.""" + ssl_version = resolve_ssl_version(ssl_version) + cert_none = resolve_cert_reqs("CERT_NONE") + if cert_reqs is None: + cert_reqs = cert_none + else: + cert_reqs = resolve_cert_reqs(cert_reqs) + + ctx = ssl.SSLContext(ssl_version) + ctx.load_cert_chain(certfile, keyfile) + ctx.verify_mode = cert_reqs + if ctx.verify_mode != cert_none: + ctx.load_verify_locations(cafile=ca_certs) + if alpn_protocols and hasattr(ctx, "set_alpn_protocols"): + try: + ctx.set_alpn_protocols(alpn_protocols) + except NotImplementedError: + pass + return ctx + + def run_tornado_app(app, io_loop, certs, scheme, host): assert io_loop == tornado.ioloop.IOLoop.current() @@ -141,7 +176,11 @@ def run_tornado_app(app, io_loop, certs, scheme, host): app.last_req = datetime(1970, 1, 1) if scheme == "https": - http_server = tornado.httpserver.HTTPServer(app, ssl_options=certs) + if sys.version_info < (2, 7, 9): + ssl_opts = certs + else: + ssl_opts = ssl_options_to_context(**certs) + http_server = tornado.httpserver.HTTPServer(app, ssl_options=ssl_opts) else: http_server = tornado.httpserver.HTTPServer(app) |
