Created on 2022-07-26 19:03 by rouilj, last changed 2022-07-26 19:03 by rouilj.
|msg7620||Author: [hidden] (rouilj)||Date: 2022-07-26 19:03|
The original report is at: https://sourceforge.net/p/roundup/mailman/message/37681135/ Tom ran into an issue where an IOError exception occurring while running under WSGI caused Apache to log: Exception occurred processing WSGI script '../wsgi.py'. RuntimeError: response has not been started (note the error "start_response() not called" is raised as a ValueError in wsgi_handler.py.) The exception handling causes wsgi_handler.py:RequestHandler::start_response to never get called. The exception handlers in client.py::inner_main() lines 810 or 879 (in v2.2.0) use: except IOError: pass which is intended to ignore a disconnected client. My initial attempt to reproduce was behind a proxy server. Since the proxy server handled the client disconnect and was always connected to the roundup-server processes, I never saw an IOError. Running python3 roundup/scripts/roundup_server (with python3.9 windows cygwin) locally and terminating the connection resulted in the expected traceback. (I added a sleep call inside the start of inner_main to make the connection long enough to cancel.) The reported exception (from roundup_server not wsgi) is: Traceback (most recent call last): File "/usr/lib/python3.9/socketserver.py", line 616, in process_request self.finish_request(request, client_address) File "/usr/lib/python3.9/socketserver.py", line 360, in finish_request self.RequestHandlerClass(request, client_address, self) File "/usr/lib/python3.9/socketserver.py", line 747, in __init__ self.handle() File "/usr/lib/python3.9/http/server.py", line 429, in handle self.handle_one_request() File "/usr/lib/python3.9/http/server.py", line 395, in handle_one_request self.raw_requestline = self.rfile.readline(65537) File "/usr/lib/python3.9/socket.py", line 706, in readinto return self._sock.recv_into(b) ConnectionAbortedError: [Errno 113] Software caused connection abort According to the manual (https://docs.python.org/3/library/exceptions.html#ConnectionAbortedError)the exception tree is: OSError (IOError is aliased to OSError in python 3.3+) ConnectionError ConnectionAbortedError Also we handle: except SysCallError: # OpenSSL.SSL.SysCallError is similar to IOError above similarly when using native SSL IIRC. So we have a few issues: 1. the IOError handler under python3 no longer gets triggered for a closed client socket that raises ConnectionAbortedError. However if I understand the exception hierarchy it should get triggered. So maybe I am not testing things correctly? 2. for the error case indicated by the comment, we could specifically target ConnectionAbortedError. But ConnectionAbortedError is not present under python2. OSError is present under python2, so we could in theory use that but I am not sure if it would capture more that it should. Also under python2 OSError and IOError are subclassed from EnvironmentError, so not replacements. 3. we could use the more specific 'socket.error' exception. This is a subclass of IOError as of python 2.6 or an alias of OSError as of python 3.3. My guess is this is what is thrown under python 2.7 and the IOError handler (if it worked) is really catching socket.error. 4. when modifying the code to implement #3, it looks like the exception is not even making it to inner_main or to the top level exception handler in roundup_server.py/RoundupRequestHandler::run_cgi(). So I am not sure where that traceback is being generated. 5. why does that traceback not have any references to a file in the roundup code tree? 6. handling IOError using a 'pass' may be what is needed. So Ralf any ideas? I know you run wsgi more than I do. To replicate Tom's issue, it looks like raising an IOError inside of determine_user should do the trick.