Skip to content

bpo-40990: Add HTTPS support to http.server.HTTPServer #20923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

remilapeyre
Copy link
Contributor

@remilapeyre remilapeyre commented Jun 16, 2020

Copy link
Member

@tiran tiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ssl module is optional and may not be available. The http.server and its tests should still work when ssl is not present.
  • You have to deal with ALPN correctly and refuse connections when ALPN is present and does not contain correct protocol indicator
  • keys are usually protected and wrapped with PKCS#8 PBE2
  • tls is technically correct but we don't use it in arguments yet
  • SSLSocket may raise exceptions that are not yet handled by HTTPServer
  • HTTPSServer should be a separate class

Comment on lines +35 to +36
.. class:: HTTPServer(server_address, RequestHandlerClass, \
bind_and_activate=True, *, tls=None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a separate class, not an argument.

@@ -101,6 +101,7 @@
import socket # For gethostbyaddr()
import socketserver
import sys
import ssl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ssl support is optional, you have to wrap the import in a try/except block.

"""Wrap the socket in SSLSocket if TLS is enabled"""
super().server_activate()
if self.tls_cert and self.tls_key:
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ssl.create_default_context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default SSL context requires a TLS 1.3 certificate so it doesn't work with ssl_cert.pem:

ssl.SSLError: [SSL: TLSV13_ALERT_CERTIFICATE_REQUIRED] tlsv13 alert certificate required

Is this something that we want to force for a development server?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no such thing as a TLS 1.3 certificate. This is a TLS alert with message certificate required. Looks like the certificate does not have correct extensions to handle TLS 1.3.

You cannot use any file from test directory any way. The directory is often not installed or shipped to reduce disk space usage in containers or on small systems.

def __init__(self, server_address, RequestHandlerClass,
bind_and_activate=True, *, tls=None):
if tls is None:
self.tls_cert = self.tls_key = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a cert file, it's a cert chain file.

Comment on lines +1296 to +1297
parser.add_argument('--tls-cert',
help='Specify the path to a TLS certificate')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cert chain

Comment on lines +1304 to +1307
elif not args.tls_cert or not args.tls_key:
parser.error('Both --tls-cert and --tls-key must be provided to enable TLS')
else:
tls = (args.tls_cert, args.tls_key)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's common to have the private key and the cert chain in the same file. The key argument should be optional.

@@ -21,6 +21,7 @@
import html
import http.client
import urllib.parse
import ssl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try/except ImportError

# BaseHTTPServerTestCase.

# We have to use the correct path from the folder created by regtest
tls = ('../../Lib/test/ssl_cert.pem', '../../Lib/test/ssl_key.pem')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.path.join(os.path.dirname(__file__), 'ssl_cert.pem')

@@ -291,6 +299,31 @@ def test_head_via_send_error(self):
self.assertEqual(b'', data)


class BaseHTTPSServerTestCase(BaseTestCase):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skip the test if ssl module is not supported

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

And if you don't make the requested changes, you will be put in the comfy chair!

@jaswdr
Copy link

jaswdr commented May 12, 2021

@remilapeyre I'm happy to continue this PR if you are not able to continue it

@remilapeyre
Copy link
Contributor Author

@remilapeyre I'm happy to continue this PR if you are not able to continue it

Hi @jaswdr, I've been quite busy but should be able to finish it this week :)


.. warning::

The HTTPS support is for development and test puposes and must not be used
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spelling: purposes

@gpshead
Copy link
Member

gpshead commented Feb 3, 2025

closing this PR as abandoned as there's a new one up.

@gpshead gpshead closed this Feb 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants