#python #python-3.x #ssl #cherrypy #pyopenssl
#python #python-3.x #ssl #cherrypy #pyopenssl
Вопрос:
Я защитил свой веб-сервис cherrypy несколько недель назад на своем старом компьютере. Затем у меня возникли проблемы, поэтому я экспортировал свои коды в новый. До этого все работало отлично. Теперь, когда я использую встроенный ssl, моя веб-страница перестает отвечать, потому что cherrypy не отвечает (даже в терминале, он снова работает только тогда, когда я изменяю код) после некоторых запросов. Если я использую pyopenssl, все отлично работает на моем ПК. Если я пытаюсь подключиться с другого компьютера или со своего смартфона / планшета, я получаю эту ошибку:
"/usr/local/lib/python3.8/dist-packages/OpenSSL/SSL.py", line 1540, in _raise_ssl_error
raise WantWriteError()
OpenSSL.SSL.WantWriteError
Это происходит после того, как я пытаюсь вернуть изображения, даже маленькие, как значок веб-сайта.
Вот мой код, я следовал документации cherrypy:
# MAIN
if __name__ == "__main__":
conf = {
'/':{
'request.dispatch':cherrypy.dispatch.MethodDispatcher(),
'tools.staticdir.root': os.path.abspath(os.getcwd()),
'tools.sessions.on':True,
'tools.sessions.secure' : True,
'tools.sessions.httponly' : True,
'tools.secureheaders.on' : True
},
'/favicon.ico':
{
'tools.staticfile.on': True,
'tools.staticfile.filename': os.path.abspath(os.getcwd()) '/favicon.ico'
},
'/js':{
'tools.staticdir.on': True,
'tools.staticdir.dir':'./js'
},
'/css':{
'tools.staticdir.on': True,
'tools.staticdir.dir':'./css'
},
'/css/Resources':{
'tools.staticdir.on': True,
'tools.staticdir.dir':'./css/Resources'
}
}
porta = 443 #porta usata
ip = get_ip() #funzione che prende l'ip del pc
#inizializzo cherrypy
cherrypy.tree.mount(SleepRepository(), '/', conf)
# if hasattr(app, 'toolboxes'):
# # CherryPy 3.1
# app.toolboxes['secureheaders'] = secureheaders.newauthtools
cherrypy.config.update({'server.socket_host': ip })
cherrypy.config.update({'server.socket_port': porta})
cherrypy.config.update({'server.max_request_body_size' : 35971520000}) #aumento il massimo in MB che posso ricevere
cherrypy.server.ssl_module = 'pyopenssl'
cherrypy.server.ssl_certificate = "cert.pem"
cherrypy.server.ssl_private_key = "privkey.pem"
cherrypy.engine.start()
cherrypy.engine.block()
Об ошибке я нахожу поток, который предлагает изменить строку библиотеки, но он не работает одинаково… У кого-нибудь есть идея?
Ответ №1:
Да! У меня была такая же проблема с изображениями, и я нашел ответ здесь: https://github.com/cherrypy/cheroot/issues/245
Это должно быть исправлено в более новых версиях cheroot, но предоставляется патч. В makefile.py замените метод BufferedWriter._flush_unlocked() на:
import OpenSSL
def _flush_unlocked(self):
self._checkClosed('flush of closed file')
while self._write_buf:
try:
# ssl sockets only except 'bytes', not bytearrays
# so perhaps we should conditionally wrap this for perf?
n = self.raw.write(self._write_buf)
except io.BlockingIOError as e:
n = e.characters_written
except (OpenSSL.SSL.WantReadError,OpenSSL.SSL.WantWriteError, OpenSSL.SSL.WantX509LookupError) as e:
n = 0
del self._write_buf[:n]
BufferedWriter._flush_unlocked = _flush_unlocked
В том же потоке было другое предложение, изменение одной строки, которое у меня не сработало. Возможно, вы нашли то же самое предложение, но это сработало для меня.
Комментарии:
1. Спасибо, но я перешел на flask, потому что мне нужно было завершить свой проект… Но я думаю, что это может быть полезно в любом случае 🙂