简体   繁体   English

在Python / Tornado中处理非SSL流量

[英]Handling Non-SSL Traffic in Python/Tornado

I have a webservice running in python 2.7.10 / Tornado that uses SSL. 我有一个在python 2.7.10 / Tornado中运行的使用SSL的web服务。 This service throws an error when a non-SSL call comes through ( http://.. .). 当非SSL调用通过时,此服务会引发错误( http:// .. )。

I don't want my service to be accessible when SSL is not used, but I'd like to handle it in a cleaner fashion. 我不希望在不使用SSL时可以访问我的服务,但我想以更清洁的方式处理它。

Here is my main code that works great over 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()

and here is the error when I hit that server with http://... instead of https://...: 当我用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) 

Any ideas how I should handle that exception? 任何想法我应该如何处理该异常?

And what the standard-conform return value would be when I catch a non-SSL call to an SSL-only API? 当我捕获对仅SSL的API的非SSL调用时,符合标准的返回值是什么?

UPDATE UPDATE

This API runs on a specific port eg https ://example.com:1234/. 此API在特定端口上运行,例如https://example.com:1234 /。 I want to inform a user who is trying to connect without SSL, eg http ://example.com:1234/ that what they are doing is incorrect by returning an error message or status code. 我想告诉谁是试图不使用SSL连接的用户,例如:http://示例.com:1234 /原来他们正在做的是通过返回的错误信息或状态码不正确。 As it is the uncaught exception returns a 500, which they could interpret as a programming error on my part. 由于未被捕获的异常返回500,他们可以将其解释为我的编程错误。 Any ideas? 有任何想法吗?

There's an excelent discussion in this Tornado issue about that, where Tornado maintainer says: 在这个龙卷风问题上有一个很好的讨论Tornado维护者说:

If you have both HTTP and HTTPS in the same tornado process, you must be running two separate HTTPServers (of course such a feature should not be tied to whether SSL is handled at the tornado level, since you could be terminating SSL in a proxy, but since your question stipulated that SSL was enabled in tornado let's focus on this case first). 如果在同一个龙卷风进程中同时拥有HTTP和HTTPS,则必须运行两个单独的HTTPServers(当然,这样的功能不应该与在tornado级别处理SSL是否相关,因为您可能在代理中终止SSL,但由于你的问题规定在龙卷风中启用了SSL,我们首先关注这个案例。 You could simply give the HTTP server a different Application, one that just does this redirect. 您可以简单地为HTTP服务器提供一个不同的应用程序,一个只执行此重定向的应用程序。

So, the best solution it's to HTTPServer that listens on port 80 and doesn't has the ssl_options parameter setted. 因此,最好的解决方案是HTTPServer侦听端口80并且没有设置ssl_options参数。

UPDATE UPDATE

A request to https ://example.com/some/path will go to port 443, where you must have an HTTPServer configured to handle https traffic; https://example.com/some/path的请求将转到端口443,您必须在其中配置HTTPServer以处理https流量; while a request to http ://example.com/some/path will go to port 80, where you must have another instance of HTTPServer without ssl options, and this is where you must return the custom response code you want. 同时请求到http://example.com/some/path会去端口80,在那里你必须拥有的HttpServer的另一个实例没有SSL选项,这就是你必须返回你想要的自定义响应代码。 That shouldn't raise any error. 这不应该引起任何错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM