在Python / Tornado中处理非SSL流量

时间:2015-10-27 21:14:16

标签: python ssl tornado

我在python 2.7.10 / Tornado中运行使用SSL的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 ://示例.com:1234 /。我想通知尝试在没有SSL的情况下进行连接的用户,例如 http ://example.com:1234 /通过返回错误消息或状态代码,他们所做的事情是不正确的。由于未被捕获的异常返回500,他们可以将其解释为我的编程错误。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

有一个excelent discussion in this Tornado issueTornado maintainer说:

  

如果在同一个龙卷风进程中同时拥有HTTP和HTTPS,则必须运行两个单独的HTTPServers(当然,这样的功能不应该与SSL是否在龙卷风级别处理有关,因为您可能正在终止SSL一个代理,但由于你的问题规定在龙卷风中启用了SSL,我们首先关注这个案例)。您可以简单地为HTTP服务器提供一个不同的应用程序,只需执行此重定向。

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

<强>更新

https ://example.com/some/path的请求将转到端口443,您必须在其中配置HTTPServer以处理https流量;对 http ://example.com/some/path的请求将转到端口80,您必须拥有另一个没有ssl选项的HTTPServer实例,这是您必须返回自定义响应的位置你想要的代码。这不应该引起任何错误。