This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: socket leak in SocketServer
Type: Stage:
Components: Library (Lib) Versions: Python 2.5
process
Status: closed Resolution: works for me
Dependencies: Superseder:
Assigned To: Nosy List: irmen, jjinux, loewis
Priority: normal Keywords: patch

Created on 2004-12-30 20:57 by jjinux, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
patch jjinux, 2004-12-30 20:57 trivial patch to SocketServer
Messages (7)
msg47422 - (view) Author: Shannon -jj Behrens (jjinux) Date: 2004-12-30 20:57
Found in Python 2.3.4 but still present in 2.5.
FreeBSD 4.9

Summary:
Fixed a socket leak in
SocketServer.StreamRequestHandler that happens during
certain exceptions.

Longer version:
SocketServer.StreamRequestHandler.setup sets up
self.rfile and self.wfile.  The parent class,
SocketServer.BaseRequestHandler.__init__ does not call
self.finish() if there is an exception thrown in
self.handle().  Hence, such an exception leads to a
leaked socket, because
SocketServer.StreamRequestHandler.finish never gets
called.  This is a one line patch that fixes that.
msg47423 - (view) Author: Irmen de Jong (irmen) (Python triager) Date: 2005-01-16 15:55
Logged In: YES 
user_id=129426

Looks harmless enough but aren't the sockets just garbage
collected once the request has been handled?
Because the request handler class is instantiated for each
request and so it will be removed once done, taking the
sockets with it, right?
msg47424 - (view) Author: Shannon -jj Behrens (jjinux) Date: 2005-01-18 19:59
Logged In: YES 
user_id=30164

Unfortunately, that is not the case according to my testing.
 I can get it to leak sockets and never reclaim them. :-/
msg47425 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2005-02-24 20:14
Logged In: YES 
user_id=21627

jjinux, I find it hard to believe that the sockets don't get
closed. Normally, with an exception, local variables survive
in the traceback. Therefore, SocketServer.py sets
sys.exc_traceback to None.

It still might be that the SocketServer is part of a cyclic
object, in which case the socket won't be closed until the
GC actually runs. However, I believe the intention is that
the SocketServer normally isn't cyclic. 

Can you provide a test case showing the problem?
msg47426 - (view) Author: Shannon -jj Behrens (jjinux) Date: 2005-02-24 22:10
Logged In: YES 
user_id=30164

Edit SimpleHTTPServer.do_GET:
  Add "raise ValueError" at the top of the method.

python SimpleHTTPServer.py

Now, using a browser, go to http://localhost:8000, and
reload the page many times.

netstat -A inet --tcp | grep 8000

You will see many sockets open.  They do go away (so I was
wrong), but it may take a minute or two (literally).  Just
as a proof of concept, I tested to see whether I could bring
the box down via this.  Fortunately, it doesn't work :-/  
It hovers at around 9000 open sockets, with the GC fighting
to keep them down.  The GC will occassionally take 10-15
seconds trying to clear everything up.  

Despite the fact the my patch is very simple, I think I'm
going to lose this argument :-/
msg47427 - (view) Author: Shannon -jj Behrens (jjinux) Date: 2005-02-24 22:23
Logged In: YES 
user_id=30164

I guess the reason this bothers me so much is that if you
have a nasty exception in your subclass of SimpleHTTPServer,
because the server doesn't close the connection to the
browser, the browser will just sit and wait instead of
telling the user something bad happened.  My patch fixes that.
msg47428 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2006-12-11 05:02
I still cannot reproduce the problem, and close this report.

When I do the netstat, I don't see any sockets "open", instead, I see many sockets TIME_WAIT. Even after I apply the patch, this behaviour doesn't change: the sockets are still TIME_WAIT. That's actually because the operating system follows the RFCs here: it should keep entries in the socket table just in case additional packets are received after the connection shutdown.

I also cannot reproduce the problem with the browser. My browser behaves just fine when I break do_GET.
History
Date User Action Args
2022-04-11 14:56:08adminsetgithub: 41380
2004-12-30 20:57:31jjinuxcreate