在Python/Tornado中处理非SSL流量



我有一个使用SSL的python 2.7.10/Tornado中运行的Web服务。当非SSL调用通过时,此服务抛出错误(http://...)。

我不希望在不使用SSL时可以访问我的服务,但我希望以更干净的方式处理它。

以下是我在SSL上运行良好的主要代码:

if __name__ == "__main__":
    tornado.options.parse_command_line()
    #does not work on 2.7.6
    ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    ssl_ctx.load_cert_chain("...crt.pem","...key.pem")
    ssl_ctx.load_verify_locations("...CA.crt.pem")
    http_server = tornado.httpserver.HTTPServer(application, ssl_options=ssl_ctx, decompress_request=True)
    http_server.listen(options.port)
    mainloop = tornado.ioloop.IOLoop.instance()
    print("Main Server started on port XXXX")
    mainloop.start()

这是我用http://...而不是https://...:

[E 151027 20:45:57 http1connection:700] Uncaught exception
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/http1connection.py", line 691, in _server_request_loop
    ret = yield conn.read_response(request_delegate)
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 807, in run
    value = future.result()
  File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 209, in result
    raise_exc_info(self._exc_info)
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 810, in run
    yielded = self.gen.throw(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/tornado/http1connection.py", line 166, in _read_message
    quiet_exceptions=iostream.StreamClosedError)
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 807, in run
    value = future.result()
  File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 209, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
SSLError: [SSL: HTTP_REQUEST] http request (_ssl.c:590) 

你知道我该如何处理这个例外吗?

当我捕捉到对仅SSL-的API的非SSL调用时,标准格式的返回值是多少?

更新

此API运行在特定端口上,例如https://example.com:124/。我想通过返回错误消息或状态代码来通知试图在没有SSL的情况下连接的用户,例如https://example.com:1234/他们所做的操作不正确。事实上,未捕获的异常返回500,他们可能会将其解释为我的编程错误。有什么想法吗?

在这个龙卷风问题上有一个非常好的讨论,龙卷风维护人员说:

如果您在同一个龙卷风进程中同时拥有HTTP和HTTPS,那么您必须运行两个独立的HTTPServer(当然,这一功能不应与SSL是否在龙卷风级别处理挂钩,因为您可以在代理中终止SSL,但由于您的问题规定SSL在龙卷风中启用,因此让我们首先关注这种情况)。您可以简单地给HTTP服务器一个不同的应用程序,一个只执行重定向的应用程序。

因此,最好的解决方案是HTTPServer在端口80上侦听,并且不设置ssl_options参数。

更新

https://example.com/some/path的请求将转到端口443,您必须在端口443配置HTTPServer以处理https流量;而对http://example.com/some/path的请求将转到端口80,在那里您必须有另一个不带ssl选项的HTTPServer实例,并且您必须在这里返回所需的自定义响应代码。这不应该引起任何错误。

最新更新