benoitc / gunicorn

gunicorn 'Green Unicorn' is a WSGI HTTP Server for UNIX, fast clients and sleepy applications.
http://www.gunicorn.org
Other
9.86k stars 1.75k forks source link

Worker restart due to OSError: [Errno 107] Transport endpoint is not connected when using https #3306

Open ddzialak opened 1 month ago

ddzialak commented 1 month ago

Looks like something related to https://github.com/benoitc/gunicorn/issues/1913 and may happen with gthread worker only when using with ssl. Previously it happened during executing parse_headers and/or accept functions, and was fixed by catching ENOTCONN error: https://github.com/benoitc/gunicorn/pull/2277/files

However, when using with ssl worker may crash in similar way:

ERR 2024-09-22 16:05:50,184 gunicorn_app_server 51616 'MainThread' : Exception in worker process [glogging.py:284]
Traceback (most recent call last):
  File "ssl.py", line 993, in _create
OSError: [Errno 107] Transport endpoint is not connected

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "gunicorn/arbiter.py", line 609, in spawn_worker
  File "sfutils/service/gunicorn_sfthread.py", line 96, in init_process
  File "gunicorn/workers/base.py", line 142, in init_process
  File "gunicorn/workers/gthread.py", line 214, in run
  File "gunicorn/workers/gthread.py", line 150, in on_client_socket_readable
  File "gunicorn/workers/gthread.py", line 115, in enqueue_req
  File "gunicorn/workers/gthread.py", line 56, in init
  File "gunicorn/sock.py", line 249, in ssl_wrap_socket
  File "ssl.py", line 455, in wrap_socket
  File "ssl.py", line 1022, in _create
ssl.SSLError: Closed before TLS handshake with data in recv buffer.

And gthread.py line 56 is:

    def init(self):
        self.initialized = True
        self.sock.setblocking(True)

        if self.parser is None:
            # wrap the socket if needed
            if self.cfg.is_ssl:
                self.sock = sock.ssl_wrap_socket(self.sock, self.cfg)   #  <-- line 56

            # initialize the parser
            self.parser = http.RequestParser(self.cfg, self.sock, self.client)

So, these exceptions if appeared in accept or parse_headers (exactly in handle function) are ignored and worker works properly but in case it happens in TConn.init cause that worker process crash.

ddzialak commented 1 month ago

Is there any reason, why TConn().init() is called by MainThread? Maybe the easiest solution is to move that to ThreadWorker().handle() function?

ddzialak commented 3 weeks ago

@sgmustafi could you verify your link? That link https://www.calvarywhangarei.co.nz/captha/index.html points to some captha

wdormann commented 3 weeks ago

That's a malicious link. I wouldn't leave that around for anybody to click on.