简体   繁体   English

使用带有 https 的 cherrypy 时加载大文件时抛出异常的原因是什么?

[英]What is the reason for exception thrown on loading large files when using cherrypy with https?

System Info系统信息

$ cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)

$ uname -a
Linux lb-cam-11 3.10.0-1160.36.2.el7.x86_64 #1 SMP Wed Jul 21 11:57:15 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

$ python --version
Python 3.7.1

$ openssl version
OpenSSL 1.0.1h 5 Jun 2014

>>> cherrypy.__version__
'18.1.0'

>>> import ssl
>>> [(ele, sys.modules[ele]) for ele in sys.modules if 'ssl' in ele]
[('ssl',
  <module 'ssl' from '/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/ssl.py'>),
 ('_ssl',
  <module '_ssl' from '/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/lib-dynload/_ssl.cpython-37m-x86_64-linux-gnu.so'>)]
>>>

>>> cheroot.__version__
'6.5.4'

Hi你好

I am attempting to set up a cherrypy server that uses https.我正在尝试设置一个使用 https 的 cherrypy 服务器。

The ssl related cherrypy configuration I am using looks like:我正在使用的 ssl 相关的 cherrypy 配置如下所示:

server_config={
    'server.socket_host': chrysocketserver,
    'server.socket_port':int(chrysocketport),
    'server.ssl_module':'pyopenssl',
    'server.ssl_certificate':sslcertificate,
    'server.ssl_private_key':privatekey,
    'server.ssl_certificate_chain':certificatechain,
}
cherrypy.config.update(server_config)

With small pages this looks like it works fine, but when I try to load a large page (I have not yet worked out at what point the problem starts occurring) the cheroot back-end (I know nothing about this) throws an exception that looks like:对于小页面,这看起来工作正常,但是当我尝试加载大页面时(我还没有弄清楚问题是从什么时候开始出现的)cheroot 后端(我对此一无所知)抛出一个异常好像:

Traceback (most recent call last):
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/cheroot/server.py", line 1252, in communicate
    req.respond()
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/cheroot/server.py", line 1056, in respond
    self.server.gateway(self).respond()
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/cheroot/wsgi.py", line 147, in respond
    self.write(chunk)
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/cheroot/wsgi.py", line 228, in write
    self.req.write(chunk)
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/cheroot/server.py", line 1112, in write
    self.conn.wfile.write(chunk)
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/cheroot/makefile.py", line 36, in write
    self._flush_unlocked()
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/cheroot/makefile.py", line 45, in _flush_unlocked
    n = self.raw.write(bytes(self._write_buf))
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/socket.py", line 607, in write
    return self._sock.send(b)
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1729, in send
    self._raise_ssl_error(self._ssl, result)
  File "/tools/oss/packages/x86_64-centos7/python/3.7.1/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1616, in _raise_ssl_error
    raise WantWriteError()
OpenSSL.SSL.WantWriteError

(Some of the page is loaded, but not all) (部分页面已加载,但不是全部)

Has anyone seen this issue before?有没有人见过这个问题? and know what might be causing it?知道是什么原因造成的吗? On the surface it looks like the socket being written to becomes unwritable (because the buffer is full?) and when it encounters the SSL.WantWriteError it simply raises an exception (rather than waiting and trying again).从表面上看,似乎正在写入的套接字变得不可写(因为缓冲区已满?),当它遇到 SSL.WantWriteError 时,它只是引发异常(而不是等待并再次尝试)。 But I am probably being naive in my reading of it.但我可能在阅读它时太天真了。

Does anyone know I how I might get round this problem?有谁知道我如何解决这个问题?

You're incorrectly assuming that the stdlib ssl您错误地假设标准库 ssl

Yes post-posting I noticed this and replied as an Answer (repeated below) which got deleted (probably because it wasn't actually an answer) - the actual version used is 1.0.2m:是的,发帖后我注意到了这一点并作为答案(在下面重复)回复,但被删除了(可能因为它实际上不是答案)——实际使用的版本是 1.0.2m:

Apologies - the ssl version I posted was simply the output of which openssl, however it the python is using a later version (1.0.2m):抱歉 - 我发布的 ssl 版本只是 output 其中 openssl,但是 python 使用的是更高版本 (1.0.2m):

>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2m  2 Nov 2017'

Is that also too old?是不是也太老了? (I believe it supports TLS 1.2, but I do not know what cyphers it supports or otherwise) (我相信它支持 TLS 1.2,但我不知道它支持什么密码或其他方式)

I did think it unlikely to be an ssl issue since small pages are loaded fine.我确实认为这不太可能是 ssl 问题,因为小页面加载正常。

Either way in this environment my hands are tied regarding the ssl version being used.无论哪种方式,在这种环境中,我都无法确定所使用的 ssl 版本。 In order to test I need to build python + openssl (plus any other dependencies) on a local machine, so it may be a while before I find time to test it.为了测试我需要在本地机器上构建 python + openssl(加上任何其他依赖项),所以我可能需要一段时间才能找到时间来测试它。

Apologies - the ssl version I posted was simply the output of which openssl, however it the python is using a later version (1.0.2m): Apologies - the ssl version I posted was simply the output of which openssl, however it the python is using a later version (1.0.2m):

>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2m  2 Nov 2017'

Is that also too old?这也太老了吧? (I believe it supports TLS 1.2, but I do not know what cyphers it supports or otherwise) (我相信它支持 TLS 1.2,但我不知道它支持什么密码或其他)

I did think it unlikely to be an ssl issue since small pages are loaded fine.我确实认为这不太可能是 ssl 问题,因为小页面可以正常加载。

Either way in this environment my hands are tied regarding the ssl version being used.无论哪种方式,在这种环境中,我都对正在使用的 ssl 版本束手无策。 In order to test I need to build python + openssl (plus any other dependencies) on a local machine, so it may be a while before I find time to test it.为了测试,我需要在本地机器上构建 python + openssl (以及任何其他依赖项),所以我可能需要一段时间才能找到时间来测试它。

To wrap up and give an answer to my question.总结并回答我的问题。

There appears to be a bug in pyopenssl ssl_module related to the way OpenSSL.SSL.WantReadError and OpenSSL.SSL.WantWriteError are handled as documented here: https://github.com/cherrypy/cheroot/issues/245 pyopenssl ssl_module 中似乎存在与 OpenSSL.SSL.WantReadError 和 OpenSSL.SSL.WantWriteError 的处理方式相关的错误,如此处所述: https://github.com/cherryspy/2cheroot/4cheroot

If I configure cherrypy using the 'builtin' module as below:如果我使用“内置”模块配置 cherrypy,如下所示:

server_config={
    'server.socket_host': chrysocketserver,
    'server.socket_port':int(chrysocketport),
    'server.ssl_module':'builtin',
    'server.ssl_certificate':sslcertificate,
    'server.ssl_private_key':privatekey,
    'server.ssl_certificate_chain':certificatechain,
}
cherrypy.config.update(server_config)

it works fine (at least in my environment)它工作正常(至少在我的环境中)

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

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