Closed kulikjak closed 1 year ago
I did more digging and managed to extract this issue into a much smaller example:
# server.py
from cheroot import wsgi
def my_app(environ, start_response):
print(".")
status = '200 OK'
response_headers = [('Content-type','text/plain'), ('Content-length','12')]
start_response(status, response_headers)
return [b'Hello world!']
addr = ('0.0.0.0', 8088)
server = wsgi.Server(addr, my_app)
server.start()
# client.py
import http.client
def get_connection():
http.client.HTTPConnection._http_vsn_str = 'HTTP/1.0'
http_connection = http.client.HTTPConnection("localhost:8088")
http_connection.auto_open = False
http_connection.connect()
return http_connection
def request(conn, keepalive=True):
conn.request("GET", "/page3", headers={'Connection': 'Keep-Alive'})
r1 = conn.getresponse()
assert r1.status == 200
assert r1.reason == 'OK'
print(r1.read())
print("-------")
conn1 = get_connection()
request(conn1)
request(conn1)
conn2 = get_connection()
request(conn2)
request(conn1)
Running this results in http.client.RemoteDisconnected: Remote end closed connection without response
on Solaris (fails in the last request
call), but works as expected on Linux. I am still unsure what the cause is; ATM it seems like a platform difference...
I found an interesting thing - when I add a short delay (time.sleep(1)
) between the last request(conn1)
and conn2 = get_connection()
, it works every time. It might still fail later if I alternate between request(conn1)
and request(conn2)
quickly, but again, if I add delays in between those, it works. It seems that there might be some kind of
Similarly, when I add a delay into the test_keepalive_conn_management
, it fails much later (not sure why, but that is not important ATM).
So, the mystery is solved, and Cheroot is innocent. I've got all the way to _ThreadsafeSelector
and found out that the DefaultSelector
used on Solaris (DevpollSelector
) seems to be the issue; when I change to either SelectSelector
or PollSelector
, all tests and the above example pass.
I am yet to find what exactly is wrong with the DevpollSelector
, but that is not a cheroot issue. Sorry for the "false alarm".
ā I'm submitting a ...
š Describe the bug. What is the current behavior?
cheroot/test/test_conn.py::test_keepalive_conn_management
test fails on Oracle Solaris 11.4 when executed.š” To Reproduce
Clone this repo and run:
/usr/bin/python3.7 -m pytest cheroot/test/test_conn.py
in the root directory. The same thing happens when running tox and in multiple Python versions (I tested 3.7 and 3.9).š” Expected behavior The test suite is clean.
š Details
From what I can tell, the
c1
connection breaks right afterc2 = connection()
is called - specifically after thehttp_connection.connect()
call.š Environment
š Additional context
While not directly related, Cherrypy test suite is clean (tested with 18.8.0).
Our previous/current cheroot version (with clean test suite) is 6.3.2 and hence before https://github.com/cherrypy/cheroot/pull/199.
I am happy to dig deeper into this but at this point I am not sure what might be the issue or where to look or what to try