在Tornado中将HTTP请求重定向到HTTPS

时间:2013-08-21 08:57:32

标签: python python-3.x tornado

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

有没有办法做到这一点?

  • Python 3v
  • Tornado 3.1v

更新

新的解决方案,但......我可能做错了(

http:// IP_ADDRESS:4443 /

警告:tornado.general:8上的SSL错误('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()

5 个答案:

答案 0 :(得分: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()))

答案 1 :(得分:2)

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

<?xml version="1.0" encoding="utf-8"?><PayPlatRequestParameter?<REQUEST_HEADER>.......

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

您确实需要两个端口侦听,一个用于内容的SSL(https),另一个用于提供重定向的(http)。我没有尝试过使用Tornado,所以我还不能对细节发表评论。

到后一部分和错误信息:

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

答案 4 :(得分:0)

WARNING:tornado.general:SSL Error on 8 ('IP_ADDRESS', 51453): [SSL: HTTP_REQUEST] http 请求 (_ssl.c:547)

是您尝试使用 http 网址访问 https 内容时得到的结果,例如: http:// IP_ADDRESS :4443/

https:// 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)。