Skip to content

Socket is not closed after client leftΒ #119

@vzarutskiy

Description

@vzarutskiy

Python-dbg detected warning during websocket server working:

[INFO 2023.04.12 21:14:58 Thread-2:warnings.py:30][_showwarnmsg_impl]: ****:164: ResourceWarning: unclosed <socket.socket [closed] fd=11, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
if check_str in list(self.check_pattern_callbacks.keys()):
Object allocated at (most recent call last):
File "/usr/lib/python3.8/threading.py", lineno 890
self._bootstrap_inner()
File "/usr/lib/python3.8/threading.py", lineno 932
self.run()
File "/home/user/.local/lib/python3.8/site-packages/websocket_server/thread.py", lineno 27
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.8/socketserver.py", lineno 237
self._handle_request_noblock()
File "/usr/lib/python3.8/socketserver.py", lineno 311
request, client_address = self.get_request()
File "/usr/lib/python3.8/socketserver.py", lineno 502
return self.socket.accept()
File "/usr/lib/python3.8/socket.py", lineno 293
sock = socket(self.family, self.type, self.proto, fileno=fd)

Real socket closing happens in case where self._io_refs = 0 (socket.py):

    def close(self):
        # This function should not reference any globals. See issue #808164.
        self._closed = True
        if self._io_refs <= 0:
            self._real_close()

self._io_refs is used in makefile (socket.py):

def makefile(self, mode="r", buffering=None, *,
             encoding=None, errors=None, newline=None):
    ...
    self._io_refs += 1
    ...
    return text

makefile is used in "setup" from StreamRequestHandler (socketserver.py):

class StreamRequestHandler(BaseRequestHandler):
    ...
    def setup(self):
        ...
        self.rfile = self.connection.makefile('rb', self.rbufsize)
        if self.wbufsize == 0:
            self.wfile = _SocketWriter(self.connection)
        else:
            self.wfile = self.connection.makefile('wb', self.wbufsize)

    def finish(self):
        ...
        self.wfile.close()
        self.rfile.close()

Stream closing, which was opened by makefile happens in "finish" method of StreamRequestHandler, but this method does not execute in WebSocketHandler, only StreamRequestHandler.setup(self):

class WebSocketHandler(StreamRequestHandler):
    ...
    def setup(self):
        StreamRequestHandler.setup(self)
        self.keep_alive = True
        self.handshake_done = False
        self.valid_client = False
    ...
    def finish(self):
        self.server._client_left_(self)

Possible fix:

def finish(self):
    StreamRequestHandler.finish(self)
    self.server._client_left_(self)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions