为什么我的 Tornado HTTPServer 不响应 HTTPS 请求?

Why is my Tornado HTTPServer not responding to HTTPS requests?

我有一个 HTTPServing 提供静态文件来测试我的一些其他代码。我需要一个响应 HTTPS 请求的服务器才能正确测试它。 HTTP 请求工作正常,但是,HTTPS 请求对我来说只是超时:


[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

但是,HTTP 请求工作得很好:

[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

这是我的代码的相关部分:

    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)

我在一个相关问题上发现了这个 random comment,该问题表明不可能在同一端口上使用 HTTP 和 HTTPS,但是我不确定它是否仍然适用,以及当我尝试监听超过一个端口还是不行。

这是我的cert.pem(别担心,这是测试证书):

-----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-----

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-----

从 curl 日志看来,您实际上并未创建启用 HTTPS 的服务器;从您的代码中不清楚您稍后如何使用 _Application
SSL 上下文需要传递给 HTTPServer 而不是 Application;使用 Tornado 的 docs 中的示例应该有效:

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)

另一个问题是您尝试使用 Tornado AFAIK 不支持的同一端口同时提供 HTTP 和 HTTPS 内容。
使用单独的端口(例如 8080 用于 HTTP,8443 用于 HTTPS,如果您不能使用 80 和 443);也用于提供静态内容 nginx 可能是更好的选择。