I have an HTTPServing serving static files for testing some other code of mine. I need a server that responds to HTTPS requests to be able to test it properly. HTTP requests works just fine, however, HTTPS requests simply timeout on me:
[matt@arch ~] curl https://localhost:56714/empty.html -m 1 -vvk
* Trying ::1:56714...
* Connected to localhost (::1) port 56714 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* Operation timed out after 1000 milliseconds with 0 out of 0 bytes received
* Closing connection 0
curl: (28) Operation timed out after 1000 milliseconds with 0 out of 0 bytes received
However, HTTP requests work just fine:
[matt@arch ~] curl http://localhost:56714/empty.html -m 1 -vvk
* Trying ::1:56714...
* Connected to localhost (::1) port 56714 (#0)
> GET /empty.html HTTP/1.1
> Host: localhost:56714
> User-Agent: curl/7.69.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: TornadoServer/6.0.4
< Content-Type: text/html
< Date: Thu, 30 Apr 2020 02:12:50 GMT
< Accept-Ranges: bytes
< Etag: "d41d8cd98f00b204e9800998ecf8427e"
< Last-Modified: Tue, 21 Apr 2020 04:51:17 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
Here's the relevant portions of my code:
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
parent_dir = Path(__file__).parent
ssl_ctx.load_cert_chain(certfile=parent_dir / 'cert.pem', keyfile=parent_dir / 'private.key')
port = get_free_port()
app = _Application(handlers, static_path=static_path, ssl_options=ssl_ctx).listen(port)
I found this random comment on a related issue that suggests HTTP and HTTPS on the same port isn't possible, however I'm not sure if it still applies, and when I tried listening on more than one port it still didn't work.
Here's my cert.pem
(don't worry, it's a test certificate):
-----BEGIN CERTIFICATE-----
MIIDjTCCAnWgAwIBAgIUdMCkdMCJdsyoS4chRW5p8fIwOzEwDQYJKoZIhvcNAQEL
BQAwVjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgMB0FsYmVydGExITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJcHlwcGV0ZWVyMB4XDTIw
MDQyOTIzMzQwMloXDTMwMDQyNzIzMzQwMlowVjELMAkGA1UEBhMCQ0ExEDAOBgNV
BAgMB0FsYmVydGExITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDES
MBAGA1UEAwwJcHlwcGV0ZWVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAzRv5uYazLfwcFn7TB3/utAdM+jJN2ao7124zA1a2R+9nnLQJDIR0yDSTClkn
i0mlG7hfjxDxAZxAIMl42pA+5YIGuo4uuFJdEF6gn3rz1nk/B7RMdLxiBpq3Yc4c
zsGqsl2HdKRiRUoAASYxHLaqJbDAz04YS90qhStjx0nBmjGVk2jaisIk85E2QTWh
y9U0sl1x1a5Yxk2w+nkinFnEWrn5jOdmi5aXBVYOWjT+Q13VUVZx6FgeIvV6xwiu
lO1VGk7c3OLxgQiljZX5kT1seV6in+OZb4oF80fzDMI7SSOGUNqmtcVOJg8aAdV6
yiySxq4cFJVEW367EFn4uDs6ywIDAQABo1MwUTAdBgNVHQ4EFgQULMhzM13CaHTO
jddh3QghomTW448wHwYDVR0jBBgwFoAULMhzM13CaHTOjddh3QghomTW448wDwYD
VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAjwdG01/P9/9DNnI/8BZH
7eJV8jsTksh9xOgQsaZK9TrwtmHcvOGozpy/iezu105amvDqiv0K152r6L16+uK6
jT8jc0YNJRoXWmepJhtz/AMbHLVu9nzSgYucAAT4cFh64sQb3Y2om6+wRYAOCuzP
z3NiIjuYqST3mXKjoFDopZO2QoVJoXME76wGYUl3QKifCTpROXb/uqb+oJUweBNa
C7A/HLV50yV4o3XOkMcIGgy4tTTXHkQ+u1SaYJiawCjM4vwKwhdvYnke7gpA7IJB
pVV6xrAMl+ut/GjcfphmaQauMFIw6QWWsx3tOH2toMS4sdDgkHdLm/34207AmruY
6A==
-----END CERTIFICATE-----
And private.key
:
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNG/m5hrMt/BwW
ftMHf+60B0z6Mk3ZqjvXbjMDVrZH72ectAkMhHTINJMKWSeLSaUbuF+PEPEBnEAg
yXjakD7lgga6ji64Ul0QXqCfevPWeT8HtEx0vGIGmrdhzhzOwaqyXYd0pGJFSgAB
JjEctqolsMDPThhL3SqFK2PHScGaMZWTaNqKwiTzkTZBNaHL1TSyXXHVrljGTbD6
eSKcWcRaufmM52aLlpcFVg5aNP5DXdVRVnHoWB4i9XrHCK6U7VUaTtzc4vGBCKWN
lfmRPWx5XqKf45lvigXzR/MMwjtJI4ZQ2qa1xU4mDxoB1XrKLJLGrhwUlURbfrsQ
Wfi4OzrLAgMBAAECggEAJxYis7k4ohW+IIdQnchCa+pMQA2gCk/HkZk9fXBj0jeM
Li+c3dbMDm7+amVtBL0nCq5K/4+B7gWhrt3V+wisA76Qm7KGsrd3ZqwxvdKHbyKx
4Tz5qPFRWOLY+Xl2wevkJJNwQckltQCSGaX2i/s/V2lkhNzkAmkGNlR7cjna/BAJ
adP1INvo2hpAABI8v2iDG51HMIsECF+Lt3rVtcNhG+avbyTN4lSNygYIl0j6URgS
1HuXdbAPqBeO/ferCnMxQUXcbVm9twza387ADnDLSLnd+Nr2PkF6FGdz3EkMXcXt
XMUB2c1naiumJW1c+aRRiBaYVzFMp/OzJNnBVTVcOQKBgQDzsNZh+O84OTDeyZQT
5fU5s7wNOfY4xJlLBOqyrbnAAsCOzHKjZYutdI/JdnYvdwAqv903rbPZN7Cm0JYO
78xmOJZYIgjYROYAj5VearkPd+dn/V0tXWyxEJDyXV7Qi9djIu6ENV4mYfb1vEsd
E2iYcG1FRRgOgWGHQBU+l3c8JQKBgQDXeD3A4/VzB+sXPYjmG7fLMM0+CN35HSkC
gJASvFyu++v74aM11RY+zhZ3H7DBGqkPQ4LH3WKrHn0yI/CauRwFB9MCEjDNznBK
6QUjj50Rr23zGjbogogUF/+0K9qzwdJLV1yiwv7wWRfeZGusGSushJ4Dr2BFLexa
hedVkLtwLwKBgGEjgJGVNWZoBb8JA2nbJKFXsAJltGx0kdaBozyOW5jaf/9sJ9ZS
SBdge2CHRB0vhnWD/Z6QMzzHIjectfRGSmgE7ok7J+Nts3FNyvDUAejUlv2w1U+c
ChOa0uyJo53l4Hm4FvPEgj8ylcrmv9pbPjpltmkCXdCKamILfWxx3CmxAoGAPqAM
EswuwshCY/bWm0rjGIOOo8EgAw+eo8OKHGfy6EkARa1HKpZMaOStUuI7FWUSTgVp
NX3695FdAf3AKLg0lKG5ipiO5sJhkOQ5QiSzmjhK1KWB4AJQWsa+4zb70dM7s/oo
SoYyYtkCPvkg8lw+fV3uL1QBvxmh4I2atxvh3rECgYAkCH779oHHxJ+mwCMnX+oA
dfwGTgvv1OO/ZW5KHYxfSAg9koj+gAqDl9PTEZf1lbh5CCNp2r3F4GF9W4+jnPlb
m09RmuyGfadxPqeouMgyysC9uSPnd2Inbw8HBbodRlkbOHeZtkLZiRX7+EhK3V52
716E4EMtYoMuIrRBEo11uw==
-----END PRIVATE KEY-----
From the curl log it seems you're not actually creating an HTTPS enabled server; it's not clear from your code how you're using the _Application
later on.
The SSL context needs to be passed to HTTPServer
not to Application
; using the example in Tornado's docs should work:
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
os.path.join(data_dir, "mydomain.key"))
HTTPServer(application, ssl_options=ssl_ctx)
Another issue is that you're trying to serve both HTTP and HTTPS content using the same port which is not supported by Tornado AFAIK.
Use separate ports (for example 8080 for HTTP and 8443 for HTTPS if you can't use 80 and 443); also for serving static content nginx
might be a better choice.