3

如果 Tornado Python 对 HTTP 的请求可以自动重定向到 HTTPS,那就太好了。

有没有办法做到这一点?

  • 蟒蛇 3v
  • 龙卷风 3.1v

更新

新的解决方案,但是...我可以做错什么吗(

http:// IP_ADDRESS :4443/

警告:tornado.general:SSL 错误 8 ('IP_ADDRESS', 51453): [SSL: HTTP_REQUEST] http 请求 (_ssl.c:547)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import tornado.ioloop
import tornado.web
import tornado.httpserver
import http.server


class MainHandler(tornado.web.RequestHandler):
    def prepare(self):
        if self.request.protocol == "http":
            self.redirect("https://%s" % self.request.full_url()[len("http://"):], permanent=True)

    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r'/', MainHandler),
])

http_server = tornado.httpserver.HTTPServer(application,
    ssl_options = {
    "certfile": os.path.join("/var/pyTest/keys/", "cert.pem"),
    "keyfile": os.path.join("/var/pyTest/keys/", "key.pem"),
    }
)

if __name__ == '__main__':
    http_server.listen(4443)
    tornado.ioloop.IOLoop.instance().start()
4

5 回答 5

5

您的解决方案对于基本部署来说看起来不错。

如果您使用的是 AWS 负载均衡器,并且您的证书安装在负载均衡器上,则需要检查X-Forwarded-Proto标头。

def prepare(self):
    if ('X-Forwarded-Proto' in self.request.headers and
            self.request.headers['X-Forwarded-Proto'] != 'https'):
        self.redirect(re.sub(r'^([^:]+)', 'https', self.request.full_url()))
于 2015-10-30T01:16:34.470 回答
4

您需要创建另一个侦听端口 80 的服务器实例。这是您的代码的修改版本:

#!/usr/bin/env python

import os
import tornado.httpserver
import tornado.web
import tornado.ioloop


class MainHandler(tornado.web.RequestHandler):

    def prepare(self):
        if self.request.protocol == 'http':
            self.redirect('https://' + self.request.host, permanent=False)

    def get(self):
        self.write("Hello, world")


if __name__ == "__main__":
    application = tornado.web.Application([
        (r'/', MainHandler)
    ])
    application.listen(80)
    http_server = tornado.httpserver.HTTPServer(
        application, 
        ssl_options = {
            "certfile": os.path.join("/var/pyTest/keys/", "cert.pem"),
            "keyfile": os.path.join("/var/pyTest/keys/", "key.pem"),
        }
    )
    http_server.listen(443)
    tornado.ioloop.IOLoop.current().start()
于 2016-05-25T03:10:50.487 回答
1

您应该能够返回重定向代码(TODO:查找)或可能的重定向页面,JS,无论您认为是一个好主意。关键是,如果客户端(浏览器)通过 http 进入,您需要提供 http。然后说服客户端改为连接到 https (SSL) 端口。您不能自己在服务器上进行重定向。

您确实需要两个端口监听,一个带有 SSL (https) 用于您的内容,一个没有 (http) 用于重定向。我还没有尝试用 Tornado 来做这件事,所以我还不能评论细节。

到后半部分和错误信息:

使用 http:// 连接到需要 HTTPS 的端口会产生 SSL 错误。尝试在您的客户端中使用 https://。确保 http:// URL 指向不服务 https 的端口,反之亦然。

于 2015-01-01T22:10:34.027 回答
1

警告:tornado.general:SSL 错误 8 ('IP_ADDRESS', 51453): [SSL: HTTP_REQUEST] http 请求 (_ssl.c:547)

如果您尝试使用 http url 访问 http内容,您会得到什么,例如:htt p ://IP_ADDRESS:4443/

http s :// IP_ADDRESS :4443/ 将带您进入页面(或下一个错误:/)。其余的已经由我们的同事在线程中解释了。侦听没有 ssl 选项的其他端口,最好为 http 设置 80。然后像准备一样重定向。

例如...

def prepare(self):
    porthttp = "8889"
    porthttps = "8443"
    if self.request.protocol == 'http':
        self.redirect('https://' + self.request.host.replace(":"+porthttp,":"+porthttps))

if __name__ == "__main__":
ssl_opt = {
    'certfile': 'host.crt',
    'keyfile': 'host.key',
}
application.listen(8443,ssl_options= ssl_opt) 
application.listen(8889)
tornado.ioloop.IOLoop.instance().start()

最后的代码只是一个例子。在循环开始之前设置任何 application.listen(port) 。

于 2021-04-16T13:55:54.437 回答
0

你的路线应该是:(r'/.*',MainHandler)

于 2013-11-01T09:26:58.533 回答