Martin Panter added the comment: I have been experimenting with a patch that changes the default to suppress_ragged_eofs=False.
One disadvantage of this change is it could make servers less robust. E.g. in the tests, I explicitly enabled suppress_ragged_eofs=True in a server, because otherwise I would have to add extra cleanup if an exception is raised on the server side. In another test server, based on socketserver, I added special code to silence logging an SSLEOFError exception (a side effect of a particular test case). But ideally, real-world servers should already handle other exceptions that are triggered outside the server’s control like, ECONNRESET and TLSV1_ALERT_UNKNOWN_CA. Socketserver already logs all these kinds of errors. Plus I think SSLEOFError has always been possible in the handshake phase. With HTTP I didn’t have to go further than Google to find a server that terminates the response with a non-SSL shutdown (although because truncated JSON is invalid, it is not a big deal). For the record, here is a stripped-down demo. The same problem also happens for a more complete request with valid parameters. >>> import socket, ssl >>> s = socket.create_connection(("accounts.google.com", 443)) >>> ss = ssl.wrap_socket(s, suppress_ragged_eofs=False) >>> ss.sendall(b"POST /o/oauth2/token HTTP/1.1\r\n" ... b"Host: accounts.google.com\r\n" ... b"Content-Length: 0\r\n" ... b"Connection: close\r\n" ... b"\r\n") >>> print("\n".join(map(repr, ss.recv(3000).splitlines(keepends=True)))) b'HTTP/1.1 400 Bad Request\r\n' b'Content-Type: application/json; charset=utf-8\r\n' b'Cache-Control: no-cache, no-store, max-age=0, must-revalidate\r\n' b'Pragma: no-cache\r\n' b'Expires: Mon, 01 Jan 1990 00:00:00 GMT\r\n' b'Date: Thu, 22 Sep 2016 03:10:20 GMT\r\n' b'X-Content-Type-Options: nosniff\r\n' b'X-Frame-Options: SAMEORIGIN\r\n' b'X-XSS-Protection: 1; mode=block\r\n' b'Server: GSE\r\n' b'Alt-Svc: quic=":443"; ma=2592000; v="36,35,34,33,32"\r\n' b'Accept-Ranges: none\r\n' b'Vary: Accept-Encoding\r\n' b'Connection: close\r\n' b'\r\n' b'{\n' b' "error" : "invalid_request",\n' b' "error_description" : "Required parameter is missing: grant_type"\n' b'}' >>> ss.recv(3000) # HTTP-level client does not know that this is the EOF yet Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/proj/python/cpython/Lib/ssl.py", line 987, in recv return self.read(buflen) File "/home/proj/python/cpython/Lib/ssl.py", line 865, in read return self._sslobj.read(len, buffer) File "/home/proj/python/cpython/Lib/ssl.py", line 627, in read v = self._sslobj.read(len) ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2176) In this case, if the client does not send “Connection: close”, the server uses chunked encoding and there is no problem. So this is another instance of Issue 12849 (Python’s unusual request triggering a server bug). I wonder if a solution would be to use suppress_ragged_eofs=False by default, but add a way to let the user of the http.client module explicitly allow SSLEOFError to signal a proper EOF. ---------- keywords: +patch versions: +Python 3.7 -Python 3.6 Added file: http://bugs.python.org/file44784/ragged-eofs.patch _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue27815> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com