generic socket server classes this module tries to capture the various aspects of defining a server for socketbased servers address family afinet 6 ip internet protocol sockets default afunix unix domain sockets others e g afdecnet are conceivable see socket h socket type sockstream reliable stream e g tcp sockdgram datagrams e g udp for requestbased servers including socketbased client address verification before further looking at the request this is actually a hook for any processing that needs to look at the request before anything else e g logging how to handle multiple requests synchronous one request is handled at a time forking each request is handled by a new process threading each request is handled by a new thread the classes in this module favor the server type that is simplest to write a synchronous tcpip server this is bad class design but saves some typing there s also the issue that a deep class hierarchy slows down method lookups there are five classes in an inheritance diagram four of which represent synchronous servers of four types baseserver v tcpserver unixstreamserver v udpserver unixdatagramserver note that unixdatagramserver derives from udpserver not from unixstreamserver the only difference between an ip and a unix stream server is the address family which is simply repeated in both unix server classes forking and threading versions of each type of server can be created using the forkingmixin and threadingmixin mixin classes for instance a threading udp server class is created as follows class threadingudpserverthreadingmixin udpserver pass the mixin class must come first since it overrides a method defined in udpserver setting the various member variables also changes the behavior of the underlying server mechanism to implement a service you must derive a class from baserequesthandler and redefine its handle method you can then run various versions of the service by combining one of the server classes with your request handler class the request handler class must be different for datagram or stream services this can be hidden by using the request handler subclasses streamrequesthandler or datagramrequesthandler of course you still have to use your head for instance it makes no sense to use a forking server if the service contains state in memory that can be modified by requests since the modifications in the child process would never reach the initial state kept in the parent process and passed to each child in this case you can use a threading server but you will probably have to use locks to avoid two requests that come in nearly simultaneous to apply conflicting changes to the server state on the other hand if you are building e g an http server where all data is stored externally e g in the file system a synchronous class will essentially render the service deaf while one request is being handled which may be for a very long time if a client is slow to read all the data it has requested here a threading or forking server is appropriate in some cases it may be appropriate to process part of a request synchronously but to finish processing in a forked child depending on the request data this can be implemented by using a synchronous server and doing an explicit fork in the request handler class handle method another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork or where these are too expensive or inappropriate for the service is to maintain an explicit table of partially finished requests and to use a selector to decide which request to work on next or whether to handle a new incoming request this is particularly important for stream services where each client can potentially be connected for a long time if threads or subprocesses cannot be used future work standard classes for sun rpc which uses either udp or tcp standard mixin classes to implement various authentication and encryption schemes xxx open problems what to do with outofband data baseserver split generic request functionality out into baseserver class c 2000 luke kenneth casson leighton lkclsamba org example read entries from a sql database requires overriding getrequest to return a table entry from the database entry is processed by a requesthandlerclass of the baseserver patch luke kenneth casson leighton pollselect have the advantage of not requiring any extra file descriptor contrarily to epollkqueue also they require a single syscall base class for server classes methods for the caller initserveraddress requesthandlerclass serveforeverpollinterval0 5 shutdown handlerequest if you do not use serveforever fileno int for selector methods that may be overridden serverbind serveractivate getrequest request clientaddress handletimeout verifyrequestrequest clientaddress serverclose processrequestrequest clientaddress shutdownrequestrequest closerequestrequest serviceactions handleerror methods for derived classes finishrequestrequest clientaddress class variables that may be overridden by derived classes or instances timeout addressfamily sockettype allowreuseaddress allowreuseport instance variables requesthandlerclass socket constructor may be extended do not override self serveraddress serveraddress self requesthandlerclass requesthandlerclass self isshutdown threading event self shutdownrequest false def serveractivateself pass def serveforeverself pollinterval0 5 self isshutdown clear try xxx consider using another file descriptor or connecting to the socket to wake this up instead of polling polling reduces our responsiveness to a shutdown request and wastes cpu at all other times with serverselector as selector selector registerself selectors eventread while not self shutdownrequest ready selector selectpollinterval bpo35017 shutdown called during select exit immediately if self shutdownrequest break if ready self handlerequestnoblock self serviceactions finally self shutdownrequest false self isshutdown set def shutdownself self shutdownrequest true self isshutdown wait def serviceactionsself pass the distinction between handling getting processing and finishing a request is fairly arbitrary remember handlerequest is the toplevel call it calls selector select getrequest verifyrequest and processrequest getrequest is different for stream or datagram sockets processrequest is the place that may fork a new process or create a new thread to finish the request finishrequest instantiates the request handler class this constructor will handle the request all by itself def handlerequestself support people who used socket settimeout to escape handlerequest before self timeout was available timeout self socket gettimeout if timeout is none timeout self timeout elif self timeout is not none timeout mintimeout self timeout if timeout is not none deadline time timeout wait until a request arrives or the timeout expires the loop is necessary to accommodate early wakeups due to eintr with serverselector as selector selector registerself selectors eventread while true if selector selecttimeout return self handlerequestnoblock else if timeout is not none timeout deadline time if timeout 0 return self handletimeout def handlerequestnoblockself try request clientaddress self getrequest except oserror return if self verifyrequestrequest clientaddress try self processrequestrequest clientaddress except exception self handleerrorrequest clientaddress self shutdownrequestrequest except self shutdownrequestrequest raise else self shutdownrequestrequest def handletimeoutself pass def verifyrequestself request clientaddress return true def processrequestself request clientaddress self finishrequestrequest clientaddress self shutdownrequestrequest def servercloseself pass def finishrequestself request clientaddress called to shutdown and close an individual request self closerequestrequest def closerequestself request handle an error gracefully may be overridden the default is to print a traceback and continue base class for various socketbased server classes defaults to synchronous ip stream i e tcp methods for the caller initserveraddress requesthandlerclass bindandactivatetrue serveforeverpollinterval0 5 shutdown handlerequest if you don t use serveforever fileno int for selector methods that may be overridden serverbind serveractivate getrequest request clientaddress handletimeout verifyrequestrequest clientaddress processrequestrequest clientaddress shutdownrequestrequest closerequestrequest handleerror methods for derived classes finishrequestrequest clientaddress class variables that may be overridden by derived classes or instances timeout addressfamily sockettype requestqueuesize only for stream sockets allowreuseaddress allowreuseport instance variables serveraddress requesthandlerclass socket constructor may be extended do not override baseserver initself serveraddress requesthandlerclass self socket socket socketself addressfamily self sockettype if bindandactivate try self serverbind self serveractivate except self serverclose raise def serverbindself if self allowreuseaddress and hasattrsocket soreuseaddr self socket setsockoptsocket solsocket socket soreuseaddr 1 if self allowreuseport and hasattrsocket soreuseport self socket setsockoptsocket solsocket socket soreuseport 1 self socket bindself serveraddress self serveraddress self socket getsockname def serveractivateself self socket listenself requestqueuesize def servercloseself self socket close def filenoself return self socket fileno def getrequestself return self socket accept def shutdownrequestself request explicitly shutdown socket close merely releases the socket and waits for gc to perform the actual close called to clean up an individual request request close class udpservertcpserver no need to call listen for udp no need to shutdown anything no need to close anything mixin class to handle each request in a new process timeout 300 activechildren none maxchildren 40 if true serverclose waits until all child processes complete blockonclose true def collectchildrenself blockingfalse if we re above the max number of children wait and reap them until we go back below threshold note that we use waitpid1 below to be able to collect children in sizedefunct children syscalls instead of sizechildren the downside is that this might reap children which we didn t spawn which is why we only resort to this when we re above maxchildren we don t have any children we re done now reap all defunct children if the child hasn t exited yet pid will be 0 and ignored by discard below someone else reaped it wait for zombies after self timeout seconds of inactivity may be extended do not override collect the zombie child processes regularly in the forkingmixin serviceactions is called in the baseserver s serveforever loop fork a new subprocess to process the request pid os fork if pid parent process if self activechildren is none self activechildren set self activechildren addpid self closerequestrequest return else child process this must never return hence os exit status 1 try self finishrequestrequest clientaddress status 0 except exception self handleerrorrequest clientaddress finally try self shutdownrequestrequest finally os exitstatus def servercloseself super serverclose self collectchildrenblockingself blockonclose class threadslist def appendself thread self reap if thread daemon return super appendthread def popallself self result self return result def joinself for thread in self popall thread join def reapself self thread for thread in self if thread isalive class nothreads def appendself thread pass def joinself pass class threadingmixin decides how threads will act upon termination of the main process if true serverclose waits until all nondaemonic threads terminate threads object used by serverclose to wait for all threads completion same as in baseserver but as a thread in addition exception handling is done here start a new thread to process the request if self blockonclose varsself setdefault threads threads t threading threadtarget self processrequestthread args request clientaddress t daemon self daemonthreads self threads appendt t start def servercloseself super serverclose self threads join if hasattros fork class forkingudpserverforkingmixin udpserver pass class forkingtcpserverforkingmixin tcpserver pass class threadingudpserverthreadingmixin udpserver pass class threadingtcpserverthreadingmixin tcpserver pass if hasattrsocket afunix class unixstreamservertcpserver addressfamily socket afunix class unixdatagramserverudpserver addressfamily socket afunix class threadingunixstreamserverthreadingmixin unixstreamserver pass class threadingunixdatagramserverthreadingmixin unixdatagramserver pass if hasattros fork class forkingunixstreamserverforkingmixin unixstreamserver pass class forkingunixdatagramserverforkingmixin unixdatagramserver pass class baserequesthandler def initself request clientaddress server self request request self clientaddress clientaddress self server server self setup try self handle finally self finish def setupself pass def handleself pass def finishself pass the following two classes make it possible to use the same service class for stream or datagram servers each class sets up these instance variables rfile a file object from which receives the request is read wfile a file object to which the reply is written when the handle method returns wfile is flushed properly class streamrequesthandlerbaserequesthandler default buffer sizes for rfile wfile we default rfile to buffered because otherwise it could be really slow for large data a getc call per byte we make wfile unbuffered because a often after a write we want to read and we need to flush the line b big writes to unbuffered files are typically optimized by stdio even when big reads aren t a timeout to apply to the request socket if not none disable nagle algorithm for this socket if true use only when wbufsize 0 to avoid small packets a final socket error may have occurred here such as the local error econnaborted simple writable bufferediobase implementation for a socket does not hold data in a buffer avoiding any need to call flush def initself sock self sock sock def writableself return true def writeself b self sock sendallb with memoryviewb as view return view nbytes def filenoself return self sock fileno class datagramrequesthandlerbaserequesthandler of the baseserver patch luke kenneth casson leighton poll select have the advantage of not requiring any extra file descriptor contrarily to epoll kqueue also they require a single syscall base class for server classes methods for the caller __init__ server_address requesthandlerclass serve_forever poll_interval 0 5 shutdown handle_request if you do not use serve_forever fileno int for selector methods that may be overridden server_bind server_activate get_request request client_address handle_timeout verify_request request client_address server_close process_request request client_address shutdown_request request close_request request service_actions handle_error methods for derived classes finish_request request client_address class variables that may be overridden by derived classes or instances timeout address_family socket_type allow_reuse_address allow_reuse_port instance variables requesthandlerclass socket constructor may be extended do not override called by constructor to activate the server may be overridden handle one request at a time until shutdown polls for shutdown every poll_interval seconds ignores self timeout if you need to do periodic tasks do them in another thread xxx consider using another file descriptor or connecting to the socket to wake this up instead of polling polling reduces our responsiveness to a shutdown request and wastes cpu at all other times bpo 35017 shutdown called during select exit immediately stops the serve_forever loop blocks until the loop has finished this must be called while serve_forever is running in another thread or it will deadlock called by the serve_forever loop may be overridden by a subclass mixin to implement any code that needs to be run during the loop the distinction between handling getting processing and finishing a request is fairly arbitrary remember handle_request is the top level call it calls selector select get_request verify_request and process_request get_request is different for stream or datagram sockets process_request is the place that may fork a new process or create a new thread to finish the request finish_request instantiates the request handler class this constructor will handle the request all by itself handle one request possibly blocking respects self timeout support people who used socket settimeout to escape handle_request before self timeout was available wait until a request arrives or the timeout expires the loop is necessary to accommodate early wakeups due to eintr handle one request without blocking i assume that selector select has returned that the socket is readable before this function was called so there should be no risk of blocking in get_request called if no new request arrives within self timeout overridden by forkingmixin verify the request may be overridden return true if we should proceed with this request call finish_request overridden by forkingmixin and threadingmixin called to clean up the server may be overridden finish one request by instantiating requesthandlerclass called to shutdown and close an individual request called to clean up an individual request handle an error gracefully may be overridden the default is to print a traceback and continue base class for various socket based server classes defaults to synchronous ip stream i e tcp methods for the caller __init__ server_address requesthandlerclass bind_and_activate true serve_forever poll_interval 0 5 shutdown handle_request if you don t use serve_forever fileno int for selector methods that may be overridden server_bind server_activate get_request request client_address handle_timeout verify_request request client_address process_request request client_address shutdown_request request close_request request handle_error methods for derived classes finish_request request client_address class variables that may be overridden by derived classes or instances timeout address_family socket_type request_queue_size only for stream sockets allow_reuse_address allow_reuse_port instance variables server_address requesthandlerclass socket constructor may be extended do not override called by constructor to bind the socket may be overridden called by constructor to activate the server may be overridden called to clean up the server may be overridden return socket file number interface required by selector get the request and client address from the socket may be overridden called to shutdown and close an individual request explicitly shutdown socket close merely releases the socket and waits for gc to perform the actual close some platforms may raise enotconn here called to clean up an individual request udp server class no need to call listen for udp no need to shutdown anything no need to close anything mix in class to handle each request in a new process if true server_close waits until all child processes complete internal routine to wait for children that have exited if we re above the max number of children wait and reap them until we go back below threshold note that we use waitpid 1 below to be able to collect children in size defunct children syscalls instead of size children the downside is that this might reap children which we didn t spawn which is why we only resort to this when we re above max_children we don t have any children we re done now reap all defunct children if the child hasn t exited yet pid will be 0 and ignored by discard below someone else reaped it wait for zombies after self timeout seconds of inactivity may be extended do not override collect the zombie child processes regularly in the forkingmixin service_actions is called in the baseserver s serve_forever loop fork a new subprocess to process the request parent process child process this must never return hence os _exit joinable list of all non daemon threads degenerate version of _threads mix in class to handle each request in a new thread decides how threads will act upon termination of the main process if true server_close waits until all non daemonic threads terminate threads object used by server_close to wait for all threads completion same as in baseserver but as a thread in addition exception handling is done here start a new thread to process the request base class for request handler classes this class is instantiated for each request to be handled the constructor sets the instance variables request client_address and server and then calls the handle method to implement a specific service all you need to do is to derive a class which defines a handle method the handle method can find the request as self request the client address as self client_address and the server in case it needs access to per server information as self server since a separate instance is created for each request the handle method can define other arbitrary instance variables the following two classes make it possible to use the same service class for stream or datagram servers each class sets up these instance variables rfile a file object from which receives the request is read wfile a file object to which the reply is written when the handle method returns wfile is flushed properly define self rfile and self wfile for stream sockets default buffer sizes for rfile wfile we default rfile to buffered because otherwise it could be really slow for large data a getc call per byte we make wfile unbuffered because a often after a write we want to read and we need to flush the line b big writes to unbuffered files are typically optimized by stdio even when big reads aren t a timeout to apply to the request socket if not none disable nagle algorithm for this socket if true use only when wbufsize 0 to avoid small packets a final socket error may have occurred here such as the local error econnaborted simple writable bufferediobase implementation for a socket does not hold data in a buffer avoiding any need to call flush define self rfile and self wfile for datagram sockets
__version__ = "0.4"


import socket
import selectors
import os
import sys
import threading
from io import BufferedIOBase
from time import monotonic as time

__all__ = ["BaseServer", "TCPServer", "UDPServer",
           "ThreadingUDPServer", "ThreadingTCPServer",
           "BaseRequestHandler", "StreamRequestHandler",
           "DatagramRequestHandler", "ThreadingMixIn"]
if hasattr(os, "fork"):
    __all__.extend(["ForkingUDPServer","ForkingTCPServer", "ForkingMixIn"])
if hasattr(socket, "AF_UNIX"):
    __all__.extend(["UnixStreamServer","UnixDatagramServer",
                    "ThreadingUnixStreamServer",
                    "ThreadingUnixDatagramServer"])
    if hasattr(os, "fork"):
        __all__.extend(["ForkingUnixStreamServer", "ForkingUnixDatagramServer"])



if hasattr(selectors, 'PollSelector'):
    _ServerSelector = selectors.PollSelector
else:
    _ServerSelector = selectors.SelectSelector


class BaseServer:

    

    timeout = None

    def __init__(self, server_address, RequestHandlerClass):
        
        self.server_address = server_address
        self.RequestHandlerClass = RequestHandlerClass
        self.__is_shut_down = threading.Event()
        self.__shutdown_request = False

    def server_activate(self):
        
        pass

    def serve_forever(self, poll_interval=0.5):
        
        self.__is_shut_down.clear()
        try:
            
            
            
            
            with _ServerSelector() as selector:
                selector.register(self, selectors.EVENT_READ)

                while not self.__shutdown_request:
                    ready = selector.select(poll_interval)
                    
                    if self.__shutdown_request:
                        break
                    if ready:
                        self._handle_request_noblock()

                    self.service_actions()
        finally:
            self.__shutdown_request = False
            self.__is_shut_down.set()

    def shutdown(self):
        
        self.__shutdown_request = True
        self.__is_shut_down.wait()

    def service_actions(self):
        
        pass

    
    
    
    
    
    
    
    
    
    

    def handle_request(self):
        
        
        
        timeout = self.socket.gettimeout()
        if timeout is None:
            timeout = self.timeout
        elif self.timeout is not None:
            timeout = min(timeout, self.timeout)
        if timeout is not None:
            deadline = time() + timeout

        
        
        with _ServerSelector() as selector:
            selector.register(self, selectors.EVENT_READ)

            while True:
                if selector.select(timeout):
                    return self._handle_request_noblock()
                else:
                    if timeout is not None:
                        timeout = deadline - time()
                        if timeout < 0:
                            return self.handle_timeout()

    def _handle_request_noblock(self):
        
        try:
            request, client_address = self.get_request()
        except OSError:
            return
        if self.verify_request(request, client_address):
            try:
                self.process_request(request, client_address)
            except Exception:
                self.handle_error(request, client_address)
                self.shutdown_request(request)
            except:
                self.shutdown_request(request)
                raise
        else:
            self.shutdown_request(request)

    def handle_timeout(self):
        
        pass

    def verify_request(self, request, client_address):
        
        return True

    def process_request(self, request, client_address):
        
        self.finish_request(request, client_address)
        self.shutdown_request(request)

    def server_close(self):
        
        pass

    def finish_request(self, request, client_address):
        
        self.RequestHandlerClass(request, client_address, self)

    def shutdown_request(self, request):
        
        self.close_request(request)

    def close_request(self, request):
        
        pass

    def handle_error(self, request, client_address):
        
        print('-'*40, file=sys.stderr)
        print('Exception occurred during processing of request from',
            client_address, file=sys.stderr)
        import traceback
        traceback.print_exc()
        print('-'*40, file=sys.stderr)

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.server_close()


class TCPServer(BaseServer):

    

    address_family = socket.AF_INET

    socket_type = socket.SOCK_STREAM

    request_queue_size = 5

    allow_reuse_address = False

    allow_reuse_port = False

    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
        
        BaseServer.__init__(self, server_address, RequestHandlerClass)
        self.socket = socket.socket(self.address_family,
                                    self.socket_type)
        if bind_and_activate:
            try:
                self.server_bind()
                self.server_activate()
            except:
                self.server_close()
                raise

    def server_bind(self):
        
        if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"):
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        if self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT"):
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
        self.socket.bind(self.server_address)
        self.server_address = self.socket.getsockname()

    def server_activate(self):
        
        self.socket.listen(self.request_queue_size)

    def server_close(self):
        
        self.socket.close()

    def fileno(self):
        
        return self.socket.fileno()

    def get_request(self):
        
        return self.socket.accept()

    def shutdown_request(self, request):
        
        try:
            
            
            request.shutdown(socket.SHUT_WR)
        except OSError:
            pass 
        self.close_request(request)

    def close_request(self, request):
        
        request.close()


class UDPServer(TCPServer):

    

    allow_reuse_address = False

    allow_reuse_port = False

    socket_type = socket.SOCK_DGRAM

    max_packet_size = 8192

    def get_request(self):
        data, client_addr = self.socket.recvfrom(self.max_packet_size)
        return (data, self.socket), client_addr

    def server_activate(self):
        
        pass

    def shutdown_request(self, request):
        
        self.close_request(request)

    def close_request(self, request):
        
        pass

if hasattr(os, "fork"):
    class ForkingMixIn:
        

        timeout = 300
        active_children = None
        max_children = 40
        
        block_on_close = True

        def collect_children(self, *, blocking=False):
            
            if self.active_children is None:
                return

            
            
            
            
            
            
            while len(self.active_children) >= self.max_children:
                try:
                    pid, _ = os.waitpid(-1, 0)
                    self.active_children.discard(pid)
                except ChildProcessError:
                    
                    self.active_children.clear()
                except OSError:
                    break

            
            for pid in self.active_children.copy():
                try:
                    flags = 0 if blocking else os.WNOHANG
                    pid, _ = os.waitpid(pid, flags)
                    
                    
                    self.active_children.discard(pid)
                except ChildProcessError:
                    
                    self.active_children.discard(pid)
                except OSError:
                    pass

        def handle_timeout(self):
            
            self.collect_children()

        def service_actions(self):
            
            self.collect_children()

        def process_request(self, request, client_address):
            
            pid = os.fork()
            if pid:
                
                if self.active_children is None:
                    self.active_children = set()
                self.active_children.add(pid)
                self.close_request(request)
                return
            else:
                
                
                status = 1
                try:
                    self.finish_request(request, client_address)
                    status = 0
                except Exception:
                    self.handle_error(request, client_address)
                finally:
                    try:
                        self.shutdown_request(request)
                    finally:
                        os._exit(status)

        def server_close(self):
            super().server_close()
            self.collect_children(blocking=self.block_on_close)


class _Threads(list):
    
    def append(self, thread):
        self.reap()
        if thread.daemon:
            return
        super().append(thread)

    def pop_all(self):
        self[:], result = [], self[:]
        return result

    def join(self):
        for thread in self.pop_all():
            thread.join()

    def reap(self):
        self[:] = (thread for thread in self if thread.is_alive())


class _NoThreads:
    
    def append(self, thread):
        pass

    def join(self):
        pass


class ThreadingMixIn:
    

    
    
    daemon_threads = False
    
    block_on_close = True
    
    
    _threads = _NoThreads()

    def process_request_thread(self, request, client_address):
        
        try:
            self.finish_request(request, client_address)
        except Exception:
            self.handle_error(request, client_address)
        finally:
            self.shutdown_request(request)

    def process_request(self, request, client_address):
        
        if self.block_on_close:
            vars(self).setdefault('_threads', _Threads())
        t = threading.Thread(target = self.process_request_thread,
                             args = (request, client_address))
        t.daemon = self.daemon_threads
        self._threads.append(t)
        t.start()

    def server_close(self):
        super().server_close()
        self._threads.join()


if hasattr(os, "fork"):
    class ForkingUDPServer(ForkingMixIn, UDPServer): pass
    class ForkingTCPServer(ForkingMixIn, TCPServer): pass

class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

if hasattr(socket, 'AF_UNIX'):

    class UnixStreamServer(TCPServer):
        address_family = socket.AF_UNIX

    class UnixDatagramServer(UDPServer):
        address_family = socket.AF_UNIX

    class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass

    class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass

    if hasattr(os, "fork"):
        class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass

        class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass

class BaseRequestHandler:

    

    def __init__(self, request, client_address, server):
        self.request = request
        self.client_address = client_address
        self.server = server
        self.setup()
        try:
            self.handle()
        finally:
            self.finish()

    def setup(self):
        pass

    def handle(self):
        pass

    def finish(self):
        pass










class StreamRequestHandler(BaseRequestHandler):

    

    
    
    
    
    
    
    
    rbufsize = -1
    wbufsize = 0

    
    timeout = None

    
    
    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)
        if self.wbufsize == 0:
            self.wfile = _SocketWriter(self.connection)
        else:
            self.wfile = self.connection.makefile('wb', self.wbufsize)

    def finish(self):
        if not self.wfile.closed:
            try:
                self.wfile.flush()
            except socket.error:
                
                
                pass
        self.wfile.close()
        self.rfile.close()

class _SocketWriter(BufferedIOBase):
    

    def __init__(self, sock):
        self._sock = sock

    def writable(self):
        return True

    def write(self, b):
        self._sock.sendall(b)
        with memoryview(b) as view:
            return view.nbytes

    def fileno(self):
        return self._sock.fileno()

class DatagramRequestHandler(BaseRequestHandler):

    

    def setup(self):
        from io import BytesIO
        self.packet, self.socket = self.request
        self.rfile = BytesIO(self.packet)
        self.wfile = BytesIO()

    def finish(self):
        self.socket.sendto(self.wfile.getvalue(), self.client_address)