You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since Python 3.10.0, I can reproduce a crash in ssl handling when serving static MP4 video files using werkzeug, a popular wsgi server that is a basic wrapper around python's http.server and ssl. I originally reported this against the werkzeug repo, but the owner suggested I report here instead.
When serving static MP4 video files greater than a certain size in some browsers using Python >= 3.10.0 with SSL enabled, an SSLEOFError occurs:
ERROR:werkzeug:Error on request:
Traceback (most recent call last):
File "C:\Users\phorsley.conda\envs\ssl-eof-3.10.0\lib\site-packages\werkzeug\serving.py", line 365, in run_wsgi
execute(self.server.app)
File "C:\Users\phorsley.conda\envs\ssl-eof-3.10.0\lib\site-packages\werkzeug\serving.py", line 329, in execute
write(data)
File "C:\Users\phorsley.conda\envs\ssl-eof-3.10.0\lib\site-packages\werkzeug\serving.py", line 304, in write
self.wfile.write(data)
File "C:\Users\phorsley.conda\envs\ssl-eof-3.10.0\lib\socketserver.py", line 826, in write
self._sock.sendall(b)
File "C:\Users\phorsley.conda\envs\ssl-eof-3.10.0\lib\ssl.py", line 1236, in sendall
v = self.send(byte_view[count:])
File "C:\Users\phorsley.conda\envs\ssl-eof-3.10.0\lib\ssl.py", line 1205, in send
return self._sslobj.write(data)
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2384)
I'm providing a tiny cut-down example app (including MP4 files) that reproduces the problem, along with additional debug logs, to help narrow down root cause (which I originally thought likely to be in werkzeug's handling of 206 PARTIAL RESPONSEs, however the repo owner believes otherwise).
Here's a screen capture of the example app demonstrating the problem:
ssl-eof-chrome-python-3.12.4.mp4
A 1Mb MP4 file does not trigger the error, but an 8Mb MP4 file does.
It reproduces on Windows using Chrome, Brave and Edge, but not Firefox. I believe it does not reproduce on MacOS using Safari or Vivaldi, but does reproduce on Linux, although I have personally only tested on Windows.
Using Flask 3.0.3, Werkzeug 3.0.3 and pyOpenSSL 24.2.1 on Windows 10, I tested the example app with following versions of python and discovered the problem started with Python 3.10.0:
Using Python 3.8.10 (uses OpenSSL 1.1.1w): no error
Using Python 3.9.19 (uses OpenSSL 3.0.14): no error Using Python 3.10.0 (uses OpenSSL 1.1.1w): error
Using Python 3.10.14 (uses OpenSSL 3.0.14): error
Using Python 3.12.4 (uses OpenSSL 3.0.14): error
I added this log line before the call to self.wfile.write(data) on line 304 of werkzeug's serving.py:
logging.warning(f'writing {len(data)} bytes with status {status_sent} {headers_sent}')
Attached are the console outputs for both Python 3.9.19 and 3.10.0. The only difference is
the presence of the call stack (twice) in 3.10.0.
From these logs it does appear the problem is related to 206 partial response / range request handling, however I am not sure where to start to identify root cause as I am not an expert on these types of HTTP responses.
I did check the python 3.10.0 release notes and it does appear that something related to ssl was changed, as they mention 'PEP 644 -- Require OpenSSL 1.1.1 or newer'.
Tip - I used miniconda and the following commands to test different versions of python:
It seems relative with #115627 ,
It could be able to fix after 3.13 version.
In my expectation, that issue works follow like this
client connect to video page
receive "200 OK" resonse, server is still sending a video files
client wanted to receive a video with partial content
client close first connection and request it again, but server still sending video files
4.1. maybe server will finished to sending 1mb media file in this time
server get broken pipe error
but this python version cannot handle that error
server throw the "ssleof" error
Unless this causes other serious errors, it probably seems okay to ignore.
Bug report
Bug description:
Since Python 3.10.0, I can reproduce a crash in ssl handling when serving static MP4 video files using werkzeug, a popular wsgi server that is a basic wrapper around python's
http.server
andssl
. I originally reported this against the werkzeug repo, but the owner suggested I report here instead.When serving static MP4 video files greater than a certain size in some browsers using Python >= 3.10.0 with SSL enabled, an SSLEOFError occurs:
I'm providing a tiny cut-down example app (including MP4 files) that reproduces the problem, along with additional debug logs, to help narrow down root cause (which I originally thought likely to be in werkzeug's handling of 206 PARTIAL RESPONSEs, however the repo owner believes otherwise).
Example app: ssl-eof.zip
This is the example app code for reference.
Here's a screen capture of the example app demonstrating the problem:
ssl-eof-chrome-python-3.12.4.mp4
A 1Mb MP4 file does not trigger the error, but an 8Mb MP4 file does.
It reproduces on Windows using Chrome, Brave and Edge, but not Firefox. I believe it does not reproduce on MacOS using Safari or Vivaldi, but does reproduce on Linux, although I have personally only tested on Windows.
Using Flask 3.0.3, Werkzeug 3.0.3 and pyOpenSSL 24.2.1 on Windows 10, I tested the example app with following versions of python and discovered the problem started with Python 3.10.0:
Using Python 3.8.10 (uses OpenSSL 1.1.1w): no error
Using Python 3.9.19 (uses OpenSSL 3.0.14): no error
Using Python 3.10.0 (uses OpenSSL 1.1.1w): error
Using Python 3.10.14 (uses OpenSSL 3.0.14): error
Using Python 3.12.4 (uses OpenSSL 3.0.14): error
I added this log line before the call to self.wfile.write(data) on line 304 of werkzeug's serving.py:
logging.warning(f'writing {len(data)} bytes with status {status_sent} {headers_sent}')
Attached are the console outputs for both Python 3.9.19 and 3.10.0. The only difference is
the presence of the call stack (twice) in 3.10.0.
python-3.10.0-logs.txt
python-3.9.19-logs.txt
From these logs it does appear the problem is related to 206 partial response / range request handling, however I am not sure where to start to identify root cause as I am not an expert on these types of HTTP responses.
I did check the python 3.10.0 release notes and it does appear that something related to ssl was changed, as they mention 'PEP 644 -- Require OpenSSL 1.1.1 or newer'.
Tip - I used miniconda and the following commands to test different versions of python:
Then load https://127.0.0.1:5000/ in a webkit browser (ignore security warning).
Happy to do any further testing / debugging to help narrow this down!
CPython versions tested on:
3.8, 3.9, 3.10, 3.12
Operating systems tested on:
Windows
The text was updated successfully, but these errors were encountered: