如果Tornado Python对HTTP的请求可以自动重定向到HTTPS,那就太好了。
有没有办法做到这一点?
更新
新的解决方案,但......我可能做错了(
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()
答案 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)。