summaryrefslogtreecommitdiff
path: root/Lib/socketserver.py
diff options
context:
space:
mode:
authorEzio Melotti <ezio.melotti@gmail.com>2011-05-07 18:15:34 +0300
committerEzio Melotti <ezio.melotti@gmail.com>2011-05-07 18:15:34 +0300
commit17736f19671fe9e3a1d0965abf6e0d022c3c7b7f (patch)
tree53cdecfea95a81b6ef7326980cf5e81328b32b06 /Lib/socketserver.py
parent2c515bbdb8fc7fd4cc3d01151d0b8dd8d5adccfd (diff)
parent496564fe5be17057671a373f4a1126352823ece5 (diff)
downloadcpython-17736f19671fe9e3a1d0965abf6e0d022c3c7b7f.tar.gz
#12017: merge with 3.1.
Diffstat (limited to 'Lib/socketserver.py')
-rw-r--r--Lib/socketserver.py48
1 files changed, 42 insertions, 6 deletions
diff --git a/Lib/socketserver.py b/Lib/socketserver.py
index 3d32c3ea19..089b3bac11 100644
--- a/Lib/socketserver.py
+++ b/Lib/socketserver.py
@@ -168,6 +168,7 @@ class BaseServer:
- verify_request(request, client_address)
- server_close()
- process_request(request, client_address)
+ - shutdown_request(request)
- close_request(request)
- handle_error()
@@ -283,7 +284,7 @@ class BaseServer:
self.process_request(request, client_address)
except:
self.handle_error(request, client_address)
- self.close_request(request)
+ self.shutdown_request(request)
def handle_timeout(self):
"""Called if no new request arrives within self.timeout.
@@ -307,7 +308,7 @@ class BaseServer:
"""
self.finish_request(request, client_address)
- self.close_request(request)
+ self.shutdown_request(request)
def server_close(self):
"""Called to clean-up the server.
@@ -321,6 +322,10 @@ class BaseServer:
"""Finish one request by instantiating RequestHandlerClass."""
self.RequestHandlerClass(request, client_address, self)
+ def shutdown_request(self, request):
+ """Called to shutdown and close an individual request."""
+ self.close_request(request)
+
def close_request(self, request):
"""Called to clean up an individual request."""
pass
@@ -361,6 +366,7 @@ class TCPServer(BaseServer):
- handle_timeout()
- verify_request(request, client_address)
- process_request(request, client_address)
+ - shutdown_request(request)
- close_request(request)
- handle_error()
@@ -445,6 +451,16 @@ class TCPServer(BaseServer):
"""
return self.socket.accept()
+ def shutdown_request(self, request):
+ """Called to shutdown and close an individual request."""
+ try:
+ #explicitly shutdown. socket.close() merely releases
+ #the socket and waits for GC to perform the actual close.
+ request.shutdown(socket.SHUT_WR)
+ except socket.error:
+ pass #some platforms may raise ENOTCONN here
+ self.close_request(request)
+
def close_request(self, request):
"""Called to clean up an individual request."""
request.close()
@@ -468,6 +484,10 @@ class UDPServer(TCPServer):
# No need to call listen() for UDP.
pass
+ def shutdown_request(self, request):
+ # No need to shutdown anything.
+ self.close_request(request)
+
def close_request(self, request):
# No need to close anything.
pass
@@ -535,10 +555,12 @@ class ForkingMixIn:
# This must never return, hence os._exit()!
try:
self.finish_request(request, client_address)
+ self.shutdown_request(request)
os._exit(0)
except:
try:
self.handle_error(request, client_address)
+ self.shutdown_request(request)
finally:
os._exit(1)
@@ -558,10 +580,10 @@ class ThreadingMixIn:
"""
try:
self.finish_request(request, client_address)
- self.close_request(request)
+ self.shutdown_request(request)
except:
self.handle_error(request, client_address)
- self.close_request(request)
+ self.shutdown_request(request)
def process_request(self, request, client_address):
"""Start a new thread to process the request."""
@@ -613,8 +635,10 @@ class BaseRequestHandler:
self.client_address = client_address
self.server = server
self.setup()
- self.handle()
- self.finish()
+ try:
+ self.handle()
+ finally:
+ self.finish()
def setup(self):
pass
@@ -648,8 +672,20 @@ class StreamRequestHandler(BaseRequestHandler):
rbufsize = -1
wbufsize = 0
+ # A timeout to apply to the request socket, if not None.
+ timeout = None
+
+ # Disable nagle algorithm for this socket, if True.
+ # Use only when wbufsize != 0, to avoid small packets.
+ disable_nagle_algorithm = False
+
def setup(self):
self.connection = self.request
+ if self.timeout is not None:
+ self.connection.settimeout(self.timeout)
+ if self.disable_nagle_algorithm:
+ self.connection.setsockopt(socket.IPPROTO_TCP,
+ socket.TCP_NODELAY, True)
self.rfile = self.connection.makefile('rb', self.rbufsize)
self.wfile = self.connection.makefile('wb', self.wbufsize)