xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/socketserver.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Generic socket server classes.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerThis module tries to capture the various aspects of defining a server:
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard WorkerFor socket-based servers:
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard Worker- address family:
8*cda5da8dSAndroid Build Coastguard Worker        - AF_INET{,6}: IP (Internet Protocol) sockets (default)
9*cda5da8dSAndroid Build Coastguard Worker        - AF_UNIX: Unix domain sockets
10*cda5da8dSAndroid Build Coastguard Worker        - others, e.g. AF_DECNET are conceivable (see <socket.h>
11*cda5da8dSAndroid Build Coastguard Worker- socket type:
12*cda5da8dSAndroid Build Coastguard Worker        - SOCK_STREAM (reliable stream, e.g. TCP)
13*cda5da8dSAndroid Build Coastguard Worker        - SOCK_DGRAM (datagrams, e.g. UDP)
14*cda5da8dSAndroid Build Coastguard Worker
15*cda5da8dSAndroid Build Coastguard WorkerFor request-based servers (including socket-based):
16*cda5da8dSAndroid Build Coastguard Worker
17*cda5da8dSAndroid Build Coastguard Worker- client address verification before further looking at the request
18*cda5da8dSAndroid Build Coastguard Worker        (This is actually a hook for any processing that needs to look
19*cda5da8dSAndroid Build Coastguard Worker         at the request before anything else, e.g. logging)
20*cda5da8dSAndroid Build Coastguard Worker- how to handle multiple requests:
21*cda5da8dSAndroid Build Coastguard Worker        - synchronous (one request is handled at a time)
22*cda5da8dSAndroid Build Coastguard Worker        - forking (each request is handled by a new process)
23*cda5da8dSAndroid Build Coastguard Worker        - threading (each request is handled by a new thread)
24*cda5da8dSAndroid Build Coastguard Worker
25*cda5da8dSAndroid Build Coastguard WorkerThe classes in this module favor the server type that is simplest to
26*cda5da8dSAndroid Build Coastguard Workerwrite: a synchronous TCP/IP server.  This is bad class design, but
27*cda5da8dSAndroid Build Coastguard Workersaves some typing.  (There's also the issue that a deep class hierarchy
28*cda5da8dSAndroid Build Coastguard Workerslows down method lookups.)
29*cda5da8dSAndroid Build Coastguard Worker
30*cda5da8dSAndroid Build Coastguard WorkerThere are five classes in an inheritance diagram, four of which represent
31*cda5da8dSAndroid Build Coastguard Workersynchronous servers of four types:
32*cda5da8dSAndroid Build Coastguard Worker
33*cda5da8dSAndroid Build Coastguard Worker        +------------+
34*cda5da8dSAndroid Build Coastguard Worker        | BaseServer |
35*cda5da8dSAndroid Build Coastguard Worker        +------------+
36*cda5da8dSAndroid Build Coastguard Worker              |
37*cda5da8dSAndroid Build Coastguard Worker              v
38*cda5da8dSAndroid Build Coastguard Worker        +-----------+        +------------------+
39*cda5da8dSAndroid Build Coastguard Worker        | TCPServer |------->| UnixStreamServer |
40*cda5da8dSAndroid Build Coastguard Worker        +-----------+        +------------------+
41*cda5da8dSAndroid Build Coastguard Worker              |
42*cda5da8dSAndroid Build Coastguard Worker              v
43*cda5da8dSAndroid Build Coastguard Worker        +-----------+        +--------------------+
44*cda5da8dSAndroid Build Coastguard Worker        | UDPServer |------->| UnixDatagramServer |
45*cda5da8dSAndroid Build Coastguard Worker        +-----------+        +--------------------+
46*cda5da8dSAndroid Build Coastguard Worker
47*cda5da8dSAndroid Build Coastguard WorkerNote that UnixDatagramServer derives from UDPServer, not from
48*cda5da8dSAndroid Build Coastguard WorkerUnixStreamServer -- the only difference between an IP and a Unix
49*cda5da8dSAndroid Build Coastguard Workerstream server is the address family, which is simply repeated in both
50*cda5da8dSAndroid Build Coastguard Workerunix server classes.
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard WorkerForking and threading versions of each type of server can be created
53*cda5da8dSAndroid Build Coastguard Workerusing the ForkingMixIn and ThreadingMixIn mix-in classes.  For
54*cda5da8dSAndroid Build Coastguard Workerinstance, a threading UDP server class is created as follows:
55*cda5da8dSAndroid Build Coastguard Worker
56*cda5da8dSAndroid Build Coastguard Worker        class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
57*cda5da8dSAndroid Build Coastguard Worker
58*cda5da8dSAndroid Build Coastguard WorkerThe Mix-in class must come first, since it overrides a method defined
59*cda5da8dSAndroid Build Coastguard Workerin UDPServer! Setting the various member variables also changes
60*cda5da8dSAndroid Build Coastguard Workerthe behavior of the underlying server mechanism.
61*cda5da8dSAndroid Build Coastguard Worker
62*cda5da8dSAndroid Build Coastguard WorkerTo implement a service, you must derive a class from
63*cda5da8dSAndroid Build Coastguard WorkerBaseRequestHandler and redefine its handle() method.  You can then run
64*cda5da8dSAndroid Build Coastguard Workervarious versions of the service by combining one of the server classes
65*cda5da8dSAndroid Build Coastguard Workerwith your request handler class.
66*cda5da8dSAndroid Build Coastguard Worker
67*cda5da8dSAndroid Build Coastguard WorkerThe request handler class must be different for datagram or stream
68*cda5da8dSAndroid Build Coastguard Workerservices.  This can be hidden by using the request handler
69*cda5da8dSAndroid Build Coastguard Workersubclasses StreamRequestHandler or DatagramRequestHandler.
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard WorkerOf course, you still have to use your head!
72*cda5da8dSAndroid Build Coastguard Worker
73*cda5da8dSAndroid Build Coastguard WorkerFor instance, it makes no sense to use a forking server if the service
74*cda5da8dSAndroid Build Coastguard Workercontains state in memory that can be modified by requests (since the
75*cda5da8dSAndroid Build Coastguard Workermodifications in the child process would never reach the initial state
76*cda5da8dSAndroid Build Coastguard Workerkept in the parent process and passed to each child).  In this case,
77*cda5da8dSAndroid Build Coastguard Workeryou can use a threading server, but you will probably have to use
78*cda5da8dSAndroid Build Coastguard Workerlocks to avoid two requests that come in nearly simultaneous to apply
79*cda5da8dSAndroid Build Coastguard Workerconflicting changes to the server state.
80*cda5da8dSAndroid Build Coastguard Worker
81*cda5da8dSAndroid Build Coastguard WorkerOn the other hand, if you are building e.g. an HTTP server, where all
82*cda5da8dSAndroid Build Coastguard Workerdata is stored externally (e.g. in the file system), a synchronous
83*cda5da8dSAndroid Build Coastguard Workerclass will essentially render the service "deaf" while one request is
84*cda5da8dSAndroid Build Coastguard Workerbeing handled -- which may be for a very long time if a client is slow
85*cda5da8dSAndroid Build Coastguard Workerto read all the data it has requested.  Here a threading or forking
86*cda5da8dSAndroid Build Coastguard Workerserver is appropriate.
87*cda5da8dSAndroid Build Coastguard Worker
88*cda5da8dSAndroid Build Coastguard WorkerIn some cases, it may be appropriate to process part of a request
89*cda5da8dSAndroid Build Coastguard Workersynchronously, but to finish processing in a forked child depending on
90*cda5da8dSAndroid Build Coastguard Workerthe request data.  This can be implemented by using a synchronous
91*cda5da8dSAndroid Build Coastguard Workerserver and doing an explicit fork in the request handler class
92*cda5da8dSAndroid Build Coastguard Workerhandle() method.
93*cda5da8dSAndroid Build Coastguard Worker
94*cda5da8dSAndroid Build Coastguard WorkerAnother approach to handling multiple simultaneous requests in an
95*cda5da8dSAndroid Build Coastguard Workerenvironment that supports neither threads nor fork (or where these are
96*cda5da8dSAndroid Build Coastguard Workertoo expensive or inappropriate for the service) is to maintain an
97*cda5da8dSAndroid Build Coastguard Workerexplicit table of partially finished requests and to use a selector to
98*cda5da8dSAndroid Build Coastguard Workerdecide which request to work on next (or whether to handle a new
99*cda5da8dSAndroid Build Coastguard Workerincoming request).  This is particularly important for stream services
100*cda5da8dSAndroid Build Coastguard Workerwhere each client can potentially be connected for a long time (if
101*cda5da8dSAndroid Build Coastguard Workerthreads or subprocesses cannot be used).
102*cda5da8dSAndroid Build Coastguard Worker
103*cda5da8dSAndroid Build Coastguard WorkerFuture work:
104*cda5da8dSAndroid Build Coastguard Worker- Standard classes for Sun RPC (which uses either UDP or TCP)
105*cda5da8dSAndroid Build Coastguard Worker- Standard mix-in classes to implement various authentication
106*cda5da8dSAndroid Build Coastguard Worker  and encryption schemes
107*cda5da8dSAndroid Build Coastguard Worker
108*cda5da8dSAndroid Build Coastguard WorkerXXX Open problems:
109*cda5da8dSAndroid Build Coastguard Worker- What to do with out-of-band data?
110*cda5da8dSAndroid Build Coastguard Worker
111*cda5da8dSAndroid Build Coastguard WorkerBaseServer:
112*cda5da8dSAndroid Build Coastguard Worker- split generic "request" functionality out into BaseServer class.
113*cda5da8dSAndroid Build Coastguard Worker  Copyright (C) 2000  Luke Kenneth Casson Leighton <[email protected]>
114*cda5da8dSAndroid Build Coastguard Worker
115*cda5da8dSAndroid Build Coastguard Worker  example: read entries from a SQL database (requires overriding
116*cda5da8dSAndroid Build Coastguard Worker  get_request() to return a table entry from the database).
117*cda5da8dSAndroid Build Coastguard Worker  entry is processed by a RequestHandlerClass.
118*cda5da8dSAndroid Build Coastguard Worker
119*cda5da8dSAndroid Build Coastguard Worker"""
120*cda5da8dSAndroid Build Coastguard Worker
121*cda5da8dSAndroid Build Coastguard Worker# Author of the BaseServer patch: Luke Kenneth Casson Leighton
122*cda5da8dSAndroid Build Coastguard Worker
123*cda5da8dSAndroid Build Coastguard Worker__version__ = "0.4"
124*cda5da8dSAndroid Build Coastguard Worker
125*cda5da8dSAndroid Build Coastguard Worker
126*cda5da8dSAndroid Build Coastguard Workerimport socket
127*cda5da8dSAndroid Build Coastguard Workerimport selectors
128*cda5da8dSAndroid Build Coastguard Workerimport os
129*cda5da8dSAndroid Build Coastguard Workerimport sys
130*cda5da8dSAndroid Build Coastguard Workerimport threading
131*cda5da8dSAndroid Build Coastguard Workerfrom io import BufferedIOBase
132*cda5da8dSAndroid Build Coastguard Workerfrom time import monotonic as time
133*cda5da8dSAndroid Build Coastguard Worker
134*cda5da8dSAndroid Build Coastguard Worker__all__ = ["BaseServer", "TCPServer", "UDPServer",
135*cda5da8dSAndroid Build Coastguard Worker           "ThreadingUDPServer", "ThreadingTCPServer",
136*cda5da8dSAndroid Build Coastguard Worker           "BaseRequestHandler", "StreamRequestHandler",
137*cda5da8dSAndroid Build Coastguard Worker           "DatagramRequestHandler", "ThreadingMixIn"]
138*cda5da8dSAndroid Build Coastguard Workerif hasattr(os, "fork"):
139*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(["ForkingUDPServer","ForkingTCPServer", "ForkingMixIn"])
140*cda5da8dSAndroid Build Coastguard Workerif hasattr(socket, "AF_UNIX"):
141*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(["UnixStreamServer","UnixDatagramServer",
142*cda5da8dSAndroid Build Coastguard Worker                    "ThreadingUnixStreamServer",
143*cda5da8dSAndroid Build Coastguard Worker                    "ThreadingUnixDatagramServer"])
144*cda5da8dSAndroid Build Coastguard Worker
145*cda5da8dSAndroid Build Coastguard Worker# poll/select have the advantage of not requiring any extra file descriptor,
146*cda5da8dSAndroid Build Coastguard Worker# contrarily to epoll/kqueue (also, they require a single syscall).
147*cda5da8dSAndroid Build Coastguard Workerif hasattr(selectors, 'PollSelector'):
148*cda5da8dSAndroid Build Coastguard Worker    _ServerSelector = selectors.PollSelector
149*cda5da8dSAndroid Build Coastguard Workerelse:
150*cda5da8dSAndroid Build Coastguard Worker    _ServerSelector = selectors.SelectSelector
151*cda5da8dSAndroid Build Coastguard Worker
152*cda5da8dSAndroid Build Coastguard Worker
153*cda5da8dSAndroid Build Coastguard Workerclass BaseServer:
154*cda5da8dSAndroid Build Coastguard Worker
155*cda5da8dSAndroid Build Coastguard Worker    """Base class for server classes.
156*cda5da8dSAndroid Build Coastguard Worker
157*cda5da8dSAndroid Build Coastguard Worker    Methods for the caller:
158*cda5da8dSAndroid Build Coastguard Worker
159*cda5da8dSAndroid Build Coastguard Worker    - __init__(server_address, RequestHandlerClass)
160*cda5da8dSAndroid Build Coastguard Worker    - serve_forever(poll_interval=0.5)
161*cda5da8dSAndroid Build Coastguard Worker    - shutdown()
162*cda5da8dSAndroid Build Coastguard Worker    - handle_request()  # if you do not use serve_forever()
163*cda5da8dSAndroid Build Coastguard Worker    - fileno() -> int   # for selector
164*cda5da8dSAndroid Build Coastguard Worker
165*cda5da8dSAndroid Build Coastguard Worker    Methods that may be overridden:
166*cda5da8dSAndroid Build Coastguard Worker
167*cda5da8dSAndroid Build Coastguard Worker    - server_bind()
168*cda5da8dSAndroid Build Coastguard Worker    - server_activate()
169*cda5da8dSAndroid Build Coastguard Worker    - get_request() -> request, client_address
170*cda5da8dSAndroid Build Coastguard Worker    - handle_timeout()
171*cda5da8dSAndroid Build Coastguard Worker    - verify_request(request, client_address)
172*cda5da8dSAndroid Build Coastguard Worker    - server_close()
173*cda5da8dSAndroid Build Coastguard Worker    - process_request(request, client_address)
174*cda5da8dSAndroid Build Coastguard Worker    - shutdown_request(request)
175*cda5da8dSAndroid Build Coastguard Worker    - close_request(request)
176*cda5da8dSAndroid Build Coastguard Worker    - service_actions()
177*cda5da8dSAndroid Build Coastguard Worker    - handle_error()
178*cda5da8dSAndroid Build Coastguard Worker
179*cda5da8dSAndroid Build Coastguard Worker    Methods for derived classes:
180*cda5da8dSAndroid Build Coastguard Worker
181*cda5da8dSAndroid Build Coastguard Worker    - finish_request(request, client_address)
182*cda5da8dSAndroid Build Coastguard Worker
183*cda5da8dSAndroid Build Coastguard Worker    Class variables that may be overridden by derived classes or
184*cda5da8dSAndroid Build Coastguard Worker    instances:
185*cda5da8dSAndroid Build Coastguard Worker
186*cda5da8dSAndroid Build Coastguard Worker    - timeout
187*cda5da8dSAndroid Build Coastguard Worker    - address_family
188*cda5da8dSAndroid Build Coastguard Worker    - socket_type
189*cda5da8dSAndroid Build Coastguard Worker    - allow_reuse_address
190*cda5da8dSAndroid Build Coastguard Worker    - allow_reuse_port
191*cda5da8dSAndroid Build Coastguard Worker
192*cda5da8dSAndroid Build Coastguard Worker    Instance variables:
193*cda5da8dSAndroid Build Coastguard Worker
194*cda5da8dSAndroid Build Coastguard Worker    - RequestHandlerClass
195*cda5da8dSAndroid Build Coastguard Worker    - socket
196*cda5da8dSAndroid Build Coastguard Worker
197*cda5da8dSAndroid Build Coastguard Worker    """
198*cda5da8dSAndroid Build Coastguard Worker
199*cda5da8dSAndroid Build Coastguard Worker    timeout = None
200*cda5da8dSAndroid Build Coastguard Worker
201*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, server_address, RequestHandlerClass):
202*cda5da8dSAndroid Build Coastguard Worker        """Constructor.  May be extended, do not override."""
203*cda5da8dSAndroid Build Coastguard Worker        self.server_address = server_address
204*cda5da8dSAndroid Build Coastguard Worker        self.RequestHandlerClass = RequestHandlerClass
205*cda5da8dSAndroid Build Coastguard Worker        self.__is_shut_down = threading.Event()
206*cda5da8dSAndroid Build Coastguard Worker        self.__shutdown_request = False
207*cda5da8dSAndroid Build Coastguard Worker
208*cda5da8dSAndroid Build Coastguard Worker    def server_activate(self):
209*cda5da8dSAndroid Build Coastguard Worker        """Called by constructor to activate the server.
210*cda5da8dSAndroid Build Coastguard Worker
211*cda5da8dSAndroid Build Coastguard Worker        May be overridden.
212*cda5da8dSAndroid Build Coastguard Worker
213*cda5da8dSAndroid Build Coastguard Worker        """
214*cda5da8dSAndroid Build Coastguard Worker        pass
215*cda5da8dSAndroid Build Coastguard Worker
216*cda5da8dSAndroid Build Coastguard Worker    def serve_forever(self, poll_interval=0.5):
217*cda5da8dSAndroid Build Coastguard Worker        """Handle one request at a time until shutdown.
218*cda5da8dSAndroid Build Coastguard Worker
219*cda5da8dSAndroid Build Coastguard Worker        Polls for shutdown every poll_interval seconds. Ignores
220*cda5da8dSAndroid Build Coastguard Worker        self.timeout. If you need to do periodic tasks, do them in
221*cda5da8dSAndroid Build Coastguard Worker        another thread.
222*cda5da8dSAndroid Build Coastguard Worker        """
223*cda5da8dSAndroid Build Coastguard Worker        self.__is_shut_down.clear()
224*cda5da8dSAndroid Build Coastguard Worker        try:
225*cda5da8dSAndroid Build Coastguard Worker            # XXX: Consider using another file descriptor or connecting to the
226*cda5da8dSAndroid Build Coastguard Worker            # socket to wake this up instead of polling. Polling reduces our
227*cda5da8dSAndroid Build Coastguard Worker            # responsiveness to a shutdown request and wastes cpu at all other
228*cda5da8dSAndroid Build Coastguard Worker            # times.
229*cda5da8dSAndroid Build Coastguard Worker            with _ServerSelector() as selector:
230*cda5da8dSAndroid Build Coastguard Worker                selector.register(self, selectors.EVENT_READ)
231*cda5da8dSAndroid Build Coastguard Worker
232*cda5da8dSAndroid Build Coastguard Worker                while not self.__shutdown_request:
233*cda5da8dSAndroid Build Coastguard Worker                    ready = selector.select(poll_interval)
234*cda5da8dSAndroid Build Coastguard Worker                    # bpo-35017: shutdown() called during select(), exit immediately.
235*cda5da8dSAndroid Build Coastguard Worker                    if self.__shutdown_request:
236*cda5da8dSAndroid Build Coastguard Worker                        break
237*cda5da8dSAndroid Build Coastguard Worker                    if ready:
238*cda5da8dSAndroid Build Coastguard Worker                        self._handle_request_noblock()
239*cda5da8dSAndroid Build Coastguard Worker
240*cda5da8dSAndroid Build Coastguard Worker                    self.service_actions()
241*cda5da8dSAndroid Build Coastguard Worker        finally:
242*cda5da8dSAndroid Build Coastguard Worker            self.__shutdown_request = False
243*cda5da8dSAndroid Build Coastguard Worker            self.__is_shut_down.set()
244*cda5da8dSAndroid Build Coastguard Worker
245*cda5da8dSAndroid Build Coastguard Worker    def shutdown(self):
246*cda5da8dSAndroid Build Coastguard Worker        """Stops the serve_forever loop.
247*cda5da8dSAndroid Build Coastguard Worker
248*cda5da8dSAndroid Build Coastguard Worker        Blocks until the loop has finished. This must be called while
249*cda5da8dSAndroid Build Coastguard Worker        serve_forever() is running in another thread, or it will
250*cda5da8dSAndroid Build Coastguard Worker        deadlock.
251*cda5da8dSAndroid Build Coastguard Worker        """
252*cda5da8dSAndroid Build Coastguard Worker        self.__shutdown_request = True
253*cda5da8dSAndroid Build Coastguard Worker        self.__is_shut_down.wait()
254*cda5da8dSAndroid Build Coastguard Worker
255*cda5da8dSAndroid Build Coastguard Worker    def service_actions(self):
256*cda5da8dSAndroid Build Coastguard Worker        """Called by the serve_forever() loop.
257*cda5da8dSAndroid Build Coastguard Worker
258*cda5da8dSAndroid Build Coastguard Worker        May be overridden by a subclass / Mixin to implement any code that
259*cda5da8dSAndroid Build Coastguard Worker        needs to be run during the loop.
260*cda5da8dSAndroid Build Coastguard Worker        """
261*cda5da8dSAndroid Build Coastguard Worker        pass
262*cda5da8dSAndroid Build Coastguard Worker
263*cda5da8dSAndroid Build Coastguard Worker    # The distinction between handling, getting, processing and finishing a
264*cda5da8dSAndroid Build Coastguard Worker    # request is fairly arbitrary.  Remember:
265*cda5da8dSAndroid Build Coastguard Worker    #
266*cda5da8dSAndroid Build Coastguard Worker    # - handle_request() is the top-level call.  It calls selector.select(),
267*cda5da8dSAndroid Build Coastguard Worker    #   get_request(), verify_request() and process_request()
268*cda5da8dSAndroid Build Coastguard Worker    # - get_request() is different for stream or datagram sockets
269*cda5da8dSAndroid Build Coastguard Worker    # - process_request() is the place that may fork a new process or create a
270*cda5da8dSAndroid Build Coastguard Worker    #   new thread to finish the request
271*cda5da8dSAndroid Build Coastguard Worker    # - finish_request() instantiates the request handler class; this
272*cda5da8dSAndroid Build Coastguard Worker    #   constructor will handle the request all by itself
273*cda5da8dSAndroid Build Coastguard Worker
274*cda5da8dSAndroid Build Coastguard Worker    def handle_request(self):
275*cda5da8dSAndroid Build Coastguard Worker        """Handle one request, possibly blocking.
276*cda5da8dSAndroid Build Coastguard Worker
277*cda5da8dSAndroid Build Coastguard Worker        Respects self.timeout.
278*cda5da8dSAndroid Build Coastguard Worker        """
279*cda5da8dSAndroid Build Coastguard Worker        # Support people who used socket.settimeout() to escape
280*cda5da8dSAndroid Build Coastguard Worker        # handle_request before self.timeout was available.
281*cda5da8dSAndroid Build Coastguard Worker        timeout = self.socket.gettimeout()
282*cda5da8dSAndroid Build Coastguard Worker        if timeout is None:
283*cda5da8dSAndroid Build Coastguard Worker            timeout = self.timeout
284*cda5da8dSAndroid Build Coastguard Worker        elif self.timeout is not None:
285*cda5da8dSAndroid Build Coastguard Worker            timeout = min(timeout, self.timeout)
286*cda5da8dSAndroid Build Coastguard Worker        if timeout is not None:
287*cda5da8dSAndroid Build Coastguard Worker            deadline = time() + timeout
288*cda5da8dSAndroid Build Coastguard Worker
289*cda5da8dSAndroid Build Coastguard Worker        # Wait until a request arrives or the timeout expires - the loop is
290*cda5da8dSAndroid Build Coastguard Worker        # necessary to accommodate early wakeups due to EINTR.
291*cda5da8dSAndroid Build Coastguard Worker        with _ServerSelector() as selector:
292*cda5da8dSAndroid Build Coastguard Worker            selector.register(self, selectors.EVENT_READ)
293*cda5da8dSAndroid Build Coastguard Worker
294*cda5da8dSAndroid Build Coastguard Worker            while True:
295*cda5da8dSAndroid Build Coastguard Worker                ready = selector.select(timeout)
296*cda5da8dSAndroid Build Coastguard Worker                if ready:
297*cda5da8dSAndroid Build Coastguard Worker                    return self._handle_request_noblock()
298*cda5da8dSAndroid Build Coastguard Worker                else:
299*cda5da8dSAndroid Build Coastguard Worker                    if timeout is not None:
300*cda5da8dSAndroid Build Coastguard Worker                        timeout = deadline - time()
301*cda5da8dSAndroid Build Coastguard Worker                        if timeout < 0:
302*cda5da8dSAndroid Build Coastguard Worker                            return self.handle_timeout()
303*cda5da8dSAndroid Build Coastguard Worker
304*cda5da8dSAndroid Build Coastguard Worker    def _handle_request_noblock(self):
305*cda5da8dSAndroid Build Coastguard Worker        """Handle one request, without blocking.
306*cda5da8dSAndroid Build Coastguard Worker
307*cda5da8dSAndroid Build Coastguard Worker        I assume that selector.select() has returned that the socket is
308*cda5da8dSAndroid Build Coastguard Worker        readable before this function was called, so there should be no risk of
309*cda5da8dSAndroid Build Coastguard Worker        blocking in get_request().
310*cda5da8dSAndroid Build Coastguard Worker        """
311*cda5da8dSAndroid Build Coastguard Worker        try:
312*cda5da8dSAndroid Build Coastguard Worker            request, client_address = self.get_request()
313*cda5da8dSAndroid Build Coastguard Worker        except OSError:
314*cda5da8dSAndroid Build Coastguard Worker            return
315*cda5da8dSAndroid Build Coastguard Worker        if self.verify_request(request, client_address):
316*cda5da8dSAndroid Build Coastguard Worker            try:
317*cda5da8dSAndroid Build Coastguard Worker                self.process_request(request, client_address)
318*cda5da8dSAndroid Build Coastguard Worker            except Exception:
319*cda5da8dSAndroid Build Coastguard Worker                self.handle_error(request, client_address)
320*cda5da8dSAndroid Build Coastguard Worker                self.shutdown_request(request)
321*cda5da8dSAndroid Build Coastguard Worker            except:
322*cda5da8dSAndroid Build Coastguard Worker                self.shutdown_request(request)
323*cda5da8dSAndroid Build Coastguard Worker                raise
324*cda5da8dSAndroid Build Coastguard Worker        else:
325*cda5da8dSAndroid Build Coastguard Worker            self.shutdown_request(request)
326*cda5da8dSAndroid Build Coastguard Worker
327*cda5da8dSAndroid Build Coastguard Worker    def handle_timeout(self):
328*cda5da8dSAndroid Build Coastguard Worker        """Called if no new request arrives within self.timeout.
329*cda5da8dSAndroid Build Coastguard Worker
330*cda5da8dSAndroid Build Coastguard Worker        Overridden by ForkingMixIn.
331*cda5da8dSAndroid Build Coastguard Worker        """
332*cda5da8dSAndroid Build Coastguard Worker        pass
333*cda5da8dSAndroid Build Coastguard Worker
334*cda5da8dSAndroid Build Coastguard Worker    def verify_request(self, request, client_address):
335*cda5da8dSAndroid Build Coastguard Worker        """Verify the request.  May be overridden.
336*cda5da8dSAndroid Build Coastguard Worker
337*cda5da8dSAndroid Build Coastguard Worker        Return True if we should proceed with this request.
338*cda5da8dSAndroid Build Coastguard Worker
339*cda5da8dSAndroid Build Coastguard Worker        """
340*cda5da8dSAndroid Build Coastguard Worker        return True
341*cda5da8dSAndroid Build Coastguard Worker
342*cda5da8dSAndroid Build Coastguard Worker    def process_request(self, request, client_address):
343*cda5da8dSAndroid Build Coastguard Worker        """Call finish_request.
344*cda5da8dSAndroid Build Coastguard Worker
345*cda5da8dSAndroid Build Coastguard Worker        Overridden by ForkingMixIn and ThreadingMixIn.
346*cda5da8dSAndroid Build Coastguard Worker
347*cda5da8dSAndroid Build Coastguard Worker        """
348*cda5da8dSAndroid Build Coastguard Worker        self.finish_request(request, client_address)
349*cda5da8dSAndroid Build Coastguard Worker        self.shutdown_request(request)
350*cda5da8dSAndroid Build Coastguard Worker
351*cda5da8dSAndroid Build Coastguard Worker    def server_close(self):
352*cda5da8dSAndroid Build Coastguard Worker        """Called to clean-up the server.
353*cda5da8dSAndroid Build Coastguard Worker
354*cda5da8dSAndroid Build Coastguard Worker        May be overridden.
355*cda5da8dSAndroid Build Coastguard Worker
356*cda5da8dSAndroid Build Coastguard Worker        """
357*cda5da8dSAndroid Build Coastguard Worker        pass
358*cda5da8dSAndroid Build Coastguard Worker
359*cda5da8dSAndroid Build Coastguard Worker    def finish_request(self, request, client_address):
360*cda5da8dSAndroid Build Coastguard Worker        """Finish one request by instantiating RequestHandlerClass."""
361*cda5da8dSAndroid Build Coastguard Worker        self.RequestHandlerClass(request, client_address, self)
362*cda5da8dSAndroid Build Coastguard Worker
363*cda5da8dSAndroid Build Coastguard Worker    def shutdown_request(self, request):
364*cda5da8dSAndroid Build Coastguard Worker        """Called to shutdown and close an individual request."""
365*cda5da8dSAndroid Build Coastguard Worker        self.close_request(request)
366*cda5da8dSAndroid Build Coastguard Worker
367*cda5da8dSAndroid Build Coastguard Worker    def close_request(self, request):
368*cda5da8dSAndroid Build Coastguard Worker        """Called to clean up an individual request."""
369*cda5da8dSAndroid Build Coastguard Worker        pass
370*cda5da8dSAndroid Build Coastguard Worker
371*cda5da8dSAndroid Build Coastguard Worker    def handle_error(self, request, client_address):
372*cda5da8dSAndroid Build Coastguard Worker        """Handle an error gracefully.  May be overridden.
373*cda5da8dSAndroid Build Coastguard Worker
374*cda5da8dSAndroid Build Coastguard Worker        The default is to print a traceback and continue.
375*cda5da8dSAndroid Build Coastguard Worker
376*cda5da8dSAndroid Build Coastguard Worker        """
377*cda5da8dSAndroid Build Coastguard Worker        print('-'*40, file=sys.stderr)
378*cda5da8dSAndroid Build Coastguard Worker        print('Exception occurred during processing of request from',
379*cda5da8dSAndroid Build Coastguard Worker            client_address, file=sys.stderr)
380*cda5da8dSAndroid Build Coastguard Worker        import traceback
381*cda5da8dSAndroid Build Coastguard Worker        traceback.print_exc()
382*cda5da8dSAndroid Build Coastguard Worker        print('-'*40, file=sys.stderr)
383*cda5da8dSAndroid Build Coastguard Worker
384*cda5da8dSAndroid Build Coastguard Worker    def __enter__(self):
385*cda5da8dSAndroid Build Coastguard Worker        return self
386*cda5da8dSAndroid Build Coastguard Worker
387*cda5da8dSAndroid Build Coastguard Worker    def __exit__(self, *args):
388*cda5da8dSAndroid Build Coastguard Worker        self.server_close()
389*cda5da8dSAndroid Build Coastguard Worker
390*cda5da8dSAndroid Build Coastguard Worker
391*cda5da8dSAndroid Build Coastguard Workerclass TCPServer(BaseServer):
392*cda5da8dSAndroid Build Coastguard Worker
393*cda5da8dSAndroid Build Coastguard Worker    """Base class for various socket-based server classes.
394*cda5da8dSAndroid Build Coastguard Worker
395*cda5da8dSAndroid Build Coastguard Worker    Defaults to synchronous IP stream (i.e., TCP).
396*cda5da8dSAndroid Build Coastguard Worker
397*cda5da8dSAndroid Build Coastguard Worker    Methods for the caller:
398*cda5da8dSAndroid Build Coastguard Worker
399*cda5da8dSAndroid Build Coastguard Worker    - __init__(server_address, RequestHandlerClass, bind_and_activate=True)
400*cda5da8dSAndroid Build Coastguard Worker    - serve_forever(poll_interval=0.5)
401*cda5da8dSAndroid Build Coastguard Worker    - shutdown()
402*cda5da8dSAndroid Build Coastguard Worker    - handle_request()  # if you don't use serve_forever()
403*cda5da8dSAndroid Build Coastguard Worker    - fileno() -> int   # for selector
404*cda5da8dSAndroid Build Coastguard Worker
405*cda5da8dSAndroid Build Coastguard Worker    Methods that may be overridden:
406*cda5da8dSAndroid Build Coastguard Worker
407*cda5da8dSAndroid Build Coastguard Worker    - server_bind()
408*cda5da8dSAndroid Build Coastguard Worker    - server_activate()
409*cda5da8dSAndroid Build Coastguard Worker    - get_request() -> request, client_address
410*cda5da8dSAndroid Build Coastguard Worker    - handle_timeout()
411*cda5da8dSAndroid Build Coastguard Worker    - verify_request(request, client_address)
412*cda5da8dSAndroid Build Coastguard Worker    - process_request(request, client_address)
413*cda5da8dSAndroid Build Coastguard Worker    - shutdown_request(request)
414*cda5da8dSAndroid Build Coastguard Worker    - close_request(request)
415*cda5da8dSAndroid Build Coastguard Worker    - handle_error()
416*cda5da8dSAndroid Build Coastguard Worker
417*cda5da8dSAndroid Build Coastguard Worker    Methods for derived classes:
418*cda5da8dSAndroid Build Coastguard Worker
419*cda5da8dSAndroid Build Coastguard Worker    - finish_request(request, client_address)
420*cda5da8dSAndroid Build Coastguard Worker
421*cda5da8dSAndroid Build Coastguard Worker    Class variables that may be overridden by derived classes or
422*cda5da8dSAndroid Build Coastguard Worker    instances:
423*cda5da8dSAndroid Build Coastguard Worker
424*cda5da8dSAndroid Build Coastguard Worker    - timeout
425*cda5da8dSAndroid Build Coastguard Worker    - address_family
426*cda5da8dSAndroid Build Coastguard Worker    - socket_type
427*cda5da8dSAndroid Build Coastguard Worker    - request_queue_size (only for stream sockets)
428*cda5da8dSAndroid Build Coastguard Worker    - allow_reuse_address
429*cda5da8dSAndroid Build Coastguard Worker    - allow_reuse_port
430*cda5da8dSAndroid Build Coastguard Worker
431*cda5da8dSAndroid Build Coastguard Worker    Instance variables:
432*cda5da8dSAndroid Build Coastguard Worker
433*cda5da8dSAndroid Build Coastguard Worker    - server_address
434*cda5da8dSAndroid Build Coastguard Worker    - RequestHandlerClass
435*cda5da8dSAndroid Build Coastguard Worker    - socket
436*cda5da8dSAndroid Build Coastguard Worker
437*cda5da8dSAndroid Build Coastguard Worker    """
438*cda5da8dSAndroid Build Coastguard Worker
439*cda5da8dSAndroid Build Coastguard Worker    address_family = socket.AF_INET
440*cda5da8dSAndroid Build Coastguard Worker
441*cda5da8dSAndroid Build Coastguard Worker    socket_type = socket.SOCK_STREAM
442*cda5da8dSAndroid Build Coastguard Worker
443*cda5da8dSAndroid Build Coastguard Worker    request_queue_size = 5
444*cda5da8dSAndroid Build Coastguard Worker
445*cda5da8dSAndroid Build Coastguard Worker    allow_reuse_address = False
446*cda5da8dSAndroid Build Coastguard Worker
447*cda5da8dSAndroid Build Coastguard Worker    allow_reuse_port = False
448*cda5da8dSAndroid Build Coastguard Worker
449*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
450*cda5da8dSAndroid Build Coastguard Worker        """Constructor.  May be extended, do not override."""
451*cda5da8dSAndroid Build Coastguard Worker        BaseServer.__init__(self, server_address, RequestHandlerClass)
452*cda5da8dSAndroid Build Coastguard Worker        self.socket = socket.socket(self.address_family,
453*cda5da8dSAndroid Build Coastguard Worker                                    self.socket_type)
454*cda5da8dSAndroid Build Coastguard Worker        if bind_and_activate:
455*cda5da8dSAndroid Build Coastguard Worker            try:
456*cda5da8dSAndroid Build Coastguard Worker                self.server_bind()
457*cda5da8dSAndroid Build Coastguard Worker                self.server_activate()
458*cda5da8dSAndroid Build Coastguard Worker            except:
459*cda5da8dSAndroid Build Coastguard Worker                self.server_close()
460*cda5da8dSAndroid Build Coastguard Worker                raise
461*cda5da8dSAndroid Build Coastguard Worker
462*cda5da8dSAndroid Build Coastguard Worker    def server_bind(self):
463*cda5da8dSAndroid Build Coastguard Worker        """Called by constructor to bind the socket.
464*cda5da8dSAndroid Build Coastguard Worker
465*cda5da8dSAndroid Build Coastguard Worker        May be overridden.
466*cda5da8dSAndroid Build Coastguard Worker
467*cda5da8dSAndroid Build Coastguard Worker        """
468*cda5da8dSAndroid Build Coastguard Worker        if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"):
469*cda5da8dSAndroid Build Coastguard Worker            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
470*cda5da8dSAndroid Build Coastguard Worker        if self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT"):
471*cda5da8dSAndroid Build Coastguard Worker            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
472*cda5da8dSAndroid Build Coastguard Worker        self.socket.bind(self.server_address)
473*cda5da8dSAndroid Build Coastguard Worker        self.server_address = self.socket.getsockname()
474*cda5da8dSAndroid Build Coastguard Worker
475*cda5da8dSAndroid Build Coastguard Worker    def server_activate(self):
476*cda5da8dSAndroid Build Coastguard Worker        """Called by constructor to activate the server.
477*cda5da8dSAndroid Build Coastguard Worker
478*cda5da8dSAndroid Build Coastguard Worker        May be overridden.
479*cda5da8dSAndroid Build Coastguard Worker
480*cda5da8dSAndroid Build Coastguard Worker        """
481*cda5da8dSAndroid Build Coastguard Worker        self.socket.listen(self.request_queue_size)
482*cda5da8dSAndroid Build Coastguard Worker
483*cda5da8dSAndroid Build Coastguard Worker    def server_close(self):
484*cda5da8dSAndroid Build Coastguard Worker        """Called to clean-up the server.
485*cda5da8dSAndroid Build Coastguard Worker
486*cda5da8dSAndroid Build Coastguard Worker        May be overridden.
487*cda5da8dSAndroid Build Coastguard Worker
488*cda5da8dSAndroid Build Coastguard Worker        """
489*cda5da8dSAndroid Build Coastguard Worker        self.socket.close()
490*cda5da8dSAndroid Build Coastguard Worker
491*cda5da8dSAndroid Build Coastguard Worker    def fileno(self):
492*cda5da8dSAndroid Build Coastguard Worker        """Return socket file number.
493*cda5da8dSAndroid Build Coastguard Worker
494*cda5da8dSAndroid Build Coastguard Worker        Interface required by selector.
495*cda5da8dSAndroid Build Coastguard Worker
496*cda5da8dSAndroid Build Coastguard Worker        """
497*cda5da8dSAndroid Build Coastguard Worker        return self.socket.fileno()
498*cda5da8dSAndroid Build Coastguard Worker
499*cda5da8dSAndroid Build Coastguard Worker    def get_request(self):
500*cda5da8dSAndroid Build Coastguard Worker        """Get the request and client address from the socket.
501*cda5da8dSAndroid Build Coastguard Worker
502*cda5da8dSAndroid Build Coastguard Worker        May be overridden.
503*cda5da8dSAndroid Build Coastguard Worker
504*cda5da8dSAndroid Build Coastguard Worker        """
505*cda5da8dSAndroid Build Coastguard Worker        return self.socket.accept()
506*cda5da8dSAndroid Build Coastguard Worker
507*cda5da8dSAndroid Build Coastguard Worker    def shutdown_request(self, request):
508*cda5da8dSAndroid Build Coastguard Worker        """Called to shutdown and close an individual request."""
509*cda5da8dSAndroid Build Coastguard Worker        try:
510*cda5da8dSAndroid Build Coastguard Worker            #explicitly shutdown.  socket.close() merely releases
511*cda5da8dSAndroid Build Coastguard Worker            #the socket and waits for GC to perform the actual close.
512*cda5da8dSAndroid Build Coastguard Worker            request.shutdown(socket.SHUT_WR)
513*cda5da8dSAndroid Build Coastguard Worker        except OSError:
514*cda5da8dSAndroid Build Coastguard Worker            pass #some platforms may raise ENOTCONN here
515*cda5da8dSAndroid Build Coastguard Worker        self.close_request(request)
516*cda5da8dSAndroid Build Coastguard Worker
517*cda5da8dSAndroid Build Coastguard Worker    def close_request(self, request):
518*cda5da8dSAndroid Build Coastguard Worker        """Called to clean up an individual request."""
519*cda5da8dSAndroid Build Coastguard Worker        request.close()
520*cda5da8dSAndroid Build Coastguard Worker
521*cda5da8dSAndroid Build Coastguard Worker
522*cda5da8dSAndroid Build Coastguard Workerclass UDPServer(TCPServer):
523*cda5da8dSAndroid Build Coastguard Worker
524*cda5da8dSAndroid Build Coastguard Worker    """UDP server class."""
525*cda5da8dSAndroid Build Coastguard Worker
526*cda5da8dSAndroid Build Coastguard Worker    allow_reuse_address = False
527*cda5da8dSAndroid Build Coastguard Worker
528*cda5da8dSAndroid Build Coastguard Worker    allow_reuse_port = False
529*cda5da8dSAndroid Build Coastguard Worker
530*cda5da8dSAndroid Build Coastguard Worker    socket_type = socket.SOCK_DGRAM
531*cda5da8dSAndroid Build Coastguard Worker
532*cda5da8dSAndroid Build Coastguard Worker    max_packet_size = 8192
533*cda5da8dSAndroid Build Coastguard Worker
534*cda5da8dSAndroid Build Coastguard Worker    def get_request(self):
535*cda5da8dSAndroid Build Coastguard Worker        data, client_addr = self.socket.recvfrom(self.max_packet_size)
536*cda5da8dSAndroid Build Coastguard Worker        return (data, self.socket), client_addr
537*cda5da8dSAndroid Build Coastguard Worker
538*cda5da8dSAndroid Build Coastguard Worker    def server_activate(self):
539*cda5da8dSAndroid Build Coastguard Worker        # No need to call listen() for UDP.
540*cda5da8dSAndroid Build Coastguard Worker        pass
541*cda5da8dSAndroid Build Coastguard Worker
542*cda5da8dSAndroid Build Coastguard Worker    def shutdown_request(self, request):
543*cda5da8dSAndroid Build Coastguard Worker        # No need to shutdown anything.
544*cda5da8dSAndroid Build Coastguard Worker        self.close_request(request)
545*cda5da8dSAndroid Build Coastguard Worker
546*cda5da8dSAndroid Build Coastguard Worker    def close_request(self, request):
547*cda5da8dSAndroid Build Coastguard Worker        # No need to close anything.
548*cda5da8dSAndroid Build Coastguard Worker        pass
549*cda5da8dSAndroid Build Coastguard Worker
550*cda5da8dSAndroid Build Coastguard Workerif hasattr(os, "fork"):
551*cda5da8dSAndroid Build Coastguard Worker    class ForkingMixIn:
552*cda5da8dSAndroid Build Coastguard Worker        """Mix-in class to handle each request in a new process."""
553*cda5da8dSAndroid Build Coastguard Worker
554*cda5da8dSAndroid Build Coastguard Worker        timeout = 300
555*cda5da8dSAndroid Build Coastguard Worker        active_children = None
556*cda5da8dSAndroid Build Coastguard Worker        max_children = 40
557*cda5da8dSAndroid Build Coastguard Worker        # If true, server_close() waits until all child processes complete.
558*cda5da8dSAndroid Build Coastguard Worker        block_on_close = True
559*cda5da8dSAndroid Build Coastguard Worker
560*cda5da8dSAndroid Build Coastguard Worker        def collect_children(self, *, blocking=False):
561*cda5da8dSAndroid Build Coastguard Worker            """Internal routine to wait for children that have exited."""
562*cda5da8dSAndroid Build Coastguard Worker            if self.active_children is None:
563*cda5da8dSAndroid Build Coastguard Worker                return
564*cda5da8dSAndroid Build Coastguard Worker
565*cda5da8dSAndroid Build Coastguard Worker            # If we're above the max number of children, wait and reap them until
566*cda5da8dSAndroid Build Coastguard Worker            # we go back below threshold. Note that we use waitpid(-1) below to be
567*cda5da8dSAndroid Build Coastguard Worker            # able to collect children in size(<defunct children>) syscalls instead
568*cda5da8dSAndroid Build Coastguard Worker            # of size(<children>): the downside is that this might reap children
569*cda5da8dSAndroid Build Coastguard Worker            # which we didn't spawn, which is why we only resort to this when we're
570*cda5da8dSAndroid Build Coastguard Worker            # above max_children.
571*cda5da8dSAndroid Build Coastguard Worker            while len(self.active_children) >= self.max_children:
572*cda5da8dSAndroid Build Coastguard Worker                try:
573*cda5da8dSAndroid Build Coastguard Worker                    pid, _ = os.waitpid(-1, 0)
574*cda5da8dSAndroid Build Coastguard Worker                    self.active_children.discard(pid)
575*cda5da8dSAndroid Build Coastguard Worker                except ChildProcessError:
576*cda5da8dSAndroid Build Coastguard Worker                    # we don't have any children, we're done
577*cda5da8dSAndroid Build Coastguard Worker                    self.active_children.clear()
578*cda5da8dSAndroid Build Coastguard Worker                except OSError:
579*cda5da8dSAndroid Build Coastguard Worker                    break
580*cda5da8dSAndroid Build Coastguard Worker
581*cda5da8dSAndroid Build Coastguard Worker            # Now reap all defunct children.
582*cda5da8dSAndroid Build Coastguard Worker            for pid in self.active_children.copy():
583*cda5da8dSAndroid Build Coastguard Worker                try:
584*cda5da8dSAndroid Build Coastguard Worker                    flags = 0 if blocking else os.WNOHANG
585*cda5da8dSAndroid Build Coastguard Worker                    pid, _ = os.waitpid(pid, flags)
586*cda5da8dSAndroid Build Coastguard Worker                    # if the child hasn't exited yet, pid will be 0 and ignored by
587*cda5da8dSAndroid Build Coastguard Worker                    # discard() below
588*cda5da8dSAndroid Build Coastguard Worker                    self.active_children.discard(pid)
589*cda5da8dSAndroid Build Coastguard Worker                except ChildProcessError:
590*cda5da8dSAndroid Build Coastguard Worker                    # someone else reaped it
591*cda5da8dSAndroid Build Coastguard Worker                    self.active_children.discard(pid)
592*cda5da8dSAndroid Build Coastguard Worker                except OSError:
593*cda5da8dSAndroid Build Coastguard Worker                    pass
594*cda5da8dSAndroid Build Coastguard Worker
595*cda5da8dSAndroid Build Coastguard Worker        def handle_timeout(self):
596*cda5da8dSAndroid Build Coastguard Worker            """Wait for zombies after self.timeout seconds of inactivity.
597*cda5da8dSAndroid Build Coastguard Worker
598*cda5da8dSAndroid Build Coastguard Worker            May be extended, do not override.
599*cda5da8dSAndroid Build Coastguard Worker            """
600*cda5da8dSAndroid Build Coastguard Worker            self.collect_children()
601*cda5da8dSAndroid Build Coastguard Worker
602*cda5da8dSAndroid Build Coastguard Worker        def service_actions(self):
603*cda5da8dSAndroid Build Coastguard Worker            """Collect the zombie child processes regularly in the ForkingMixIn.
604*cda5da8dSAndroid Build Coastguard Worker
605*cda5da8dSAndroid Build Coastguard Worker            service_actions is called in the BaseServer's serve_forever loop.
606*cda5da8dSAndroid Build Coastguard Worker            """
607*cda5da8dSAndroid Build Coastguard Worker            self.collect_children()
608*cda5da8dSAndroid Build Coastguard Worker
609*cda5da8dSAndroid Build Coastguard Worker        def process_request(self, request, client_address):
610*cda5da8dSAndroid Build Coastguard Worker            """Fork a new subprocess to process the request."""
611*cda5da8dSAndroid Build Coastguard Worker            pid = os.fork()
612*cda5da8dSAndroid Build Coastguard Worker            if pid:
613*cda5da8dSAndroid Build Coastguard Worker                # Parent process
614*cda5da8dSAndroid Build Coastguard Worker                if self.active_children is None:
615*cda5da8dSAndroid Build Coastguard Worker                    self.active_children = set()
616*cda5da8dSAndroid Build Coastguard Worker                self.active_children.add(pid)
617*cda5da8dSAndroid Build Coastguard Worker                self.close_request(request)
618*cda5da8dSAndroid Build Coastguard Worker                return
619*cda5da8dSAndroid Build Coastguard Worker            else:
620*cda5da8dSAndroid Build Coastguard Worker                # Child process.
621*cda5da8dSAndroid Build Coastguard Worker                # This must never return, hence os._exit()!
622*cda5da8dSAndroid Build Coastguard Worker                status = 1
623*cda5da8dSAndroid Build Coastguard Worker                try:
624*cda5da8dSAndroid Build Coastguard Worker                    self.finish_request(request, client_address)
625*cda5da8dSAndroid Build Coastguard Worker                    status = 0
626*cda5da8dSAndroid Build Coastguard Worker                except Exception:
627*cda5da8dSAndroid Build Coastguard Worker                    self.handle_error(request, client_address)
628*cda5da8dSAndroid Build Coastguard Worker                finally:
629*cda5da8dSAndroid Build Coastguard Worker                    try:
630*cda5da8dSAndroid Build Coastguard Worker                        self.shutdown_request(request)
631*cda5da8dSAndroid Build Coastguard Worker                    finally:
632*cda5da8dSAndroid Build Coastguard Worker                        os._exit(status)
633*cda5da8dSAndroid Build Coastguard Worker
634*cda5da8dSAndroid Build Coastguard Worker        def server_close(self):
635*cda5da8dSAndroid Build Coastguard Worker            super().server_close()
636*cda5da8dSAndroid Build Coastguard Worker            self.collect_children(blocking=self.block_on_close)
637*cda5da8dSAndroid Build Coastguard Worker
638*cda5da8dSAndroid Build Coastguard Worker
639*cda5da8dSAndroid Build Coastguard Workerclass _Threads(list):
640*cda5da8dSAndroid Build Coastguard Worker    """
641*cda5da8dSAndroid Build Coastguard Worker    Joinable list of all non-daemon threads.
642*cda5da8dSAndroid Build Coastguard Worker    """
643*cda5da8dSAndroid Build Coastguard Worker    def append(self, thread):
644*cda5da8dSAndroid Build Coastguard Worker        self.reap()
645*cda5da8dSAndroid Build Coastguard Worker        if thread.daemon:
646*cda5da8dSAndroid Build Coastguard Worker            return
647*cda5da8dSAndroid Build Coastguard Worker        super().append(thread)
648*cda5da8dSAndroid Build Coastguard Worker
649*cda5da8dSAndroid Build Coastguard Worker    def pop_all(self):
650*cda5da8dSAndroid Build Coastguard Worker        self[:], result = [], self[:]
651*cda5da8dSAndroid Build Coastguard Worker        return result
652*cda5da8dSAndroid Build Coastguard Worker
653*cda5da8dSAndroid Build Coastguard Worker    def join(self):
654*cda5da8dSAndroid Build Coastguard Worker        for thread in self.pop_all():
655*cda5da8dSAndroid Build Coastguard Worker            thread.join()
656*cda5da8dSAndroid Build Coastguard Worker
657*cda5da8dSAndroid Build Coastguard Worker    def reap(self):
658*cda5da8dSAndroid Build Coastguard Worker        self[:] = (thread for thread in self if thread.is_alive())
659*cda5da8dSAndroid Build Coastguard Worker
660*cda5da8dSAndroid Build Coastguard Worker
661*cda5da8dSAndroid Build Coastguard Workerclass _NoThreads:
662*cda5da8dSAndroid Build Coastguard Worker    """
663*cda5da8dSAndroid Build Coastguard Worker    Degenerate version of _Threads.
664*cda5da8dSAndroid Build Coastguard Worker    """
665*cda5da8dSAndroid Build Coastguard Worker    def append(self, thread):
666*cda5da8dSAndroid Build Coastguard Worker        pass
667*cda5da8dSAndroid Build Coastguard Worker
668*cda5da8dSAndroid Build Coastguard Worker    def join(self):
669*cda5da8dSAndroid Build Coastguard Worker        pass
670*cda5da8dSAndroid Build Coastguard Worker
671*cda5da8dSAndroid Build Coastguard Worker
672*cda5da8dSAndroid Build Coastguard Workerclass ThreadingMixIn:
673*cda5da8dSAndroid Build Coastguard Worker    """Mix-in class to handle each request in a new thread."""
674*cda5da8dSAndroid Build Coastguard Worker
675*cda5da8dSAndroid Build Coastguard Worker    # Decides how threads will act upon termination of the
676*cda5da8dSAndroid Build Coastguard Worker    # main process
677*cda5da8dSAndroid Build Coastguard Worker    daemon_threads = False
678*cda5da8dSAndroid Build Coastguard Worker    # If true, server_close() waits until all non-daemonic threads terminate.
679*cda5da8dSAndroid Build Coastguard Worker    block_on_close = True
680*cda5da8dSAndroid Build Coastguard Worker    # Threads object
681*cda5da8dSAndroid Build Coastguard Worker    # used by server_close() to wait for all threads completion.
682*cda5da8dSAndroid Build Coastguard Worker    _threads = _NoThreads()
683*cda5da8dSAndroid Build Coastguard Worker
684*cda5da8dSAndroid Build Coastguard Worker    def process_request_thread(self, request, client_address):
685*cda5da8dSAndroid Build Coastguard Worker        """Same as in BaseServer but as a thread.
686*cda5da8dSAndroid Build Coastguard Worker
687*cda5da8dSAndroid Build Coastguard Worker        In addition, exception handling is done here.
688*cda5da8dSAndroid Build Coastguard Worker
689*cda5da8dSAndroid Build Coastguard Worker        """
690*cda5da8dSAndroid Build Coastguard Worker        try:
691*cda5da8dSAndroid Build Coastguard Worker            self.finish_request(request, client_address)
692*cda5da8dSAndroid Build Coastguard Worker        except Exception:
693*cda5da8dSAndroid Build Coastguard Worker            self.handle_error(request, client_address)
694*cda5da8dSAndroid Build Coastguard Worker        finally:
695*cda5da8dSAndroid Build Coastguard Worker            self.shutdown_request(request)
696*cda5da8dSAndroid Build Coastguard Worker
697*cda5da8dSAndroid Build Coastguard Worker    def process_request(self, request, client_address):
698*cda5da8dSAndroid Build Coastguard Worker        """Start a new thread to process the request."""
699*cda5da8dSAndroid Build Coastguard Worker        if self.block_on_close:
700*cda5da8dSAndroid Build Coastguard Worker            vars(self).setdefault('_threads', _Threads())
701*cda5da8dSAndroid Build Coastguard Worker        t = threading.Thread(target = self.process_request_thread,
702*cda5da8dSAndroid Build Coastguard Worker                             args = (request, client_address))
703*cda5da8dSAndroid Build Coastguard Worker        t.daemon = self.daemon_threads
704*cda5da8dSAndroid Build Coastguard Worker        self._threads.append(t)
705*cda5da8dSAndroid Build Coastguard Worker        t.start()
706*cda5da8dSAndroid Build Coastguard Worker
707*cda5da8dSAndroid Build Coastguard Worker    def server_close(self):
708*cda5da8dSAndroid Build Coastguard Worker        super().server_close()
709*cda5da8dSAndroid Build Coastguard Worker        self._threads.join()
710*cda5da8dSAndroid Build Coastguard Worker
711*cda5da8dSAndroid Build Coastguard Worker
712*cda5da8dSAndroid Build Coastguard Workerif hasattr(os, "fork"):
713*cda5da8dSAndroid Build Coastguard Worker    class ForkingUDPServer(ForkingMixIn, UDPServer): pass
714*cda5da8dSAndroid Build Coastguard Worker    class ForkingTCPServer(ForkingMixIn, TCPServer): pass
715*cda5da8dSAndroid Build Coastguard Worker
716*cda5da8dSAndroid Build Coastguard Workerclass ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
717*cda5da8dSAndroid Build Coastguard Workerclass ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
718*cda5da8dSAndroid Build Coastguard Worker
719*cda5da8dSAndroid Build Coastguard Workerif hasattr(socket, 'AF_UNIX'):
720*cda5da8dSAndroid Build Coastguard Worker
721*cda5da8dSAndroid Build Coastguard Worker    class UnixStreamServer(TCPServer):
722*cda5da8dSAndroid Build Coastguard Worker        address_family = socket.AF_UNIX
723*cda5da8dSAndroid Build Coastguard Worker
724*cda5da8dSAndroid Build Coastguard Worker    class UnixDatagramServer(UDPServer):
725*cda5da8dSAndroid Build Coastguard Worker        address_family = socket.AF_UNIX
726*cda5da8dSAndroid Build Coastguard Worker
727*cda5da8dSAndroid Build Coastguard Worker    class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass
728*cda5da8dSAndroid Build Coastguard Worker
729*cda5da8dSAndroid Build Coastguard Worker    class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass
730*cda5da8dSAndroid Build Coastguard Worker
731*cda5da8dSAndroid Build Coastguard Workerclass BaseRequestHandler:
732*cda5da8dSAndroid Build Coastguard Worker
733*cda5da8dSAndroid Build Coastguard Worker    """Base class for request handler classes.
734*cda5da8dSAndroid Build Coastguard Worker
735*cda5da8dSAndroid Build Coastguard Worker    This class is instantiated for each request to be handled.  The
736*cda5da8dSAndroid Build Coastguard Worker    constructor sets the instance variables request, client_address
737*cda5da8dSAndroid Build Coastguard Worker    and server, and then calls the handle() method.  To implement a
738*cda5da8dSAndroid Build Coastguard Worker    specific service, all you need to do is to derive a class which
739*cda5da8dSAndroid Build Coastguard Worker    defines a handle() method.
740*cda5da8dSAndroid Build Coastguard Worker
741*cda5da8dSAndroid Build Coastguard Worker    The handle() method can find the request as self.request, the
742*cda5da8dSAndroid Build Coastguard Worker    client address as self.client_address, and the server (in case it
743*cda5da8dSAndroid Build Coastguard Worker    needs access to per-server information) as self.server.  Since a
744*cda5da8dSAndroid Build Coastguard Worker    separate instance is created for each request, the handle() method
745*cda5da8dSAndroid Build Coastguard Worker    can define other arbitrary instance variables.
746*cda5da8dSAndroid Build Coastguard Worker
747*cda5da8dSAndroid Build Coastguard Worker    """
748*cda5da8dSAndroid Build Coastguard Worker
749*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, request, client_address, server):
750*cda5da8dSAndroid Build Coastguard Worker        self.request = request
751*cda5da8dSAndroid Build Coastguard Worker        self.client_address = client_address
752*cda5da8dSAndroid Build Coastguard Worker        self.server = server
753*cda5da8dSAndroid Build Coastguard Worker        self.setup()
754*cda5da8dSAndroid Build Coastguard Worker        try:
755*cda5da8dSAndroid Build Coastguard Worker            self.handle()
756*cda5da8dSAndroid Build Coastguard Worker        finally:
757*cda5da8dSAndroid Build Coastguard Worker            self.finish()
758*cda5da8dSAndroid Build Coastguard Worker
759*cda5da8dSAndroid Build Coastguard Worker    def setup(self):
760*cda5da8dSAndroid Build Coastguard Worker        pass
761*cda5da8dSAndroid Build Coastguard Worker
762*cda5da8dSAndroid Build Coastguard Worker    def handle(self):
763*cda5da8dSAndroid Build Coastguard Worker        pass
764*cda5da8dSAndroid Build Coastguard Worker
765*cda5da8dSAndroid Build Coastguard Worker    def finish(self):
766*cda5da8dSAndroid Build Coastguard Worker        pass
767*cda5da8dSAndroid Build Coastguard Worker
768*cda5da8dSAndroid Build Coastguard Worker
769*cda5da8dSAndroid Build Coastguard Worker# The following two classes make it possible to use the same service
770*cda5da8dSAndroid Build Coastguard Worker# class for stream or datagram servers.
771*cda5da8dSAndroid Build Coastguard Worker# Each class sets up these instance variables:
772*cda5da8dSAndroid Build Coastguard Worker# - rfile: a file object from which receives the request is read
773*cda5da8dSAndroid Build Coastguard Worker# - wfile: a file object to which the reply is written
774*cda5da8dSAndroid Build Coastguard Worker# When the handle() method returns, wfile is flushed properly
775*cda5da8dSAndroid Build Coastguard Worker
776*cda5da8dSAndroid Build Coastguard Worker
777*cda5da8dSAndroid Build Coastguard Workerclass StreamRequestHandler(BaseRequestHandler):
778*cda5da8dSAndroid Build Coastguard Worker
779*cda5da8dSAndroid Build Coastguard Worker    """Define self.rfile and self.wfile for stream sockets."""
780*cda5da8dSAndroid Build Coastguard Worker
781*cda5da8dSAndroid Build Coastguard Worker    # Default buffer sizes for rfile, wfile.
782*cda5da8dSAndroid Build Coastguard Worker    # We default rfile to buffered because otherwise it could be
783*cda5da8dSAndroid Build Coastguard Worker    # really slow for large data (a getc() call per byte); we make
784*cda5da8dSAndroid Build Coastguard Worker    # wfile unbuffered because (a) often after a write() we want to
785*cda5da8dSAndroid Build Coastguard Worker    # read and we need to flush the line; (b) big writes to unbuffered
786*cda5da8dSAndroid Build Coastguard Worker    # files are typically optimized by stdio even when big reads
787*cda5da8dSAndroid Build Coastguard Worker    # aren't.
788*cda5da8dSAndroid Build Coastguard Worker    rbufsize = -1
789*cda5da8dSAndroid Build Coastguard Worker    wbufsize = 0
790*cda5da8dSAndroid Build Coastguard Worker
791*cda5da8dSAndroid Build Coastguard Worker    # A timeout to apply to the request socket, if not None.
792*cda5da8dSAndroid Build Coastguard Worker    timeout = None
793*cda5da8dSAndroid Build Coastguard Worker
794*cda5da8dSAndroid Build Coastguard Worker    # Disable nagle algorithm for this socket, if True.
795*cda5da8dSAndroid Build Coastguard Worker    # Use only when wbufsize != 0, to avoid small packets.
796*cda5da8dSAndroid Build Coastguard Worker    disable_nagle_algorithm = False
797*cda5da8dSAndroid Build Coastguard Worker
798*cda5da8dSAndroid Build Coastguard Worker    def setup(self):
799*cda5da8dSAndroid Build Coastguard Worker        self.connection = self.request
800*cda5da8dSAndroid Build Coastguard Worker        if self.timeout is not None:
801*cda5da8dSAndroid Build Coastguard Worker            self.connection.settimeout(self.timeout)
802*cda5da8dSAndroid Build Coastguard Worker        if self.disable_nagle_algorithm:
803*cda5da8dSAndroid Build Coastguard Worker            self.connection.setsockopt(socket.IPPROTO_TCP,
804*cda5da8dSAndroid Build Coastguard Worker                                       socket.TCP_NODELAY, True)
805*cda5da8dSAndroid Build Coastguard Worker        self.rfile = self.connection.makefile('rb', self.rbufsize)
806*cda5da8dSAndroid Build Coastguard Worker        if self.wbufsize == 0:
807*cda5da8dSAndroid Build Coastguard Worker            self.wfile = _SocketWriter(self.connection)
808*cda5da8dSAndroid Build Coastguard Worker        else:
809*cda5da8dSAndroid Build Coastguard Worker            self.wfile = self.connection.makefile('wb', self.wbufsize)
810*cda5da8dSAndroid Build Coastguard Worker
811*cda5da8dSAndroid Build Coastguard Worker    def finish(self):
812*cda5da8dSAndroid Build Coastguard Worker        if not self.wfile.closed:
813*cda5da8dSAndroid Build Coastguard Worker            try:
814*cda5da8dSAndroid Build Coastguard Worker                self.wfile.flush()
815*cda5da8dSAndroid Build Coastguard Worker            except socket.error:
816*cda5da8dSAndroid Build Coastguard Worker                # A final socket error may have occurred here, such as
817*cda5da8dSAndroid Build Coastguard Worker                # the local error ECONNABORTED.
818*cda5da8dSAndroid Build Coastguard Worker                pass
819*cda5da8dSAndroid Build Coastguard Worker        self.wfile.close()
820*cda5da8dSAndroid Build Coastguard Worker        self.rfile.close()
821*cda5da8dSAndroid Build Coastguard Worker
822*cda5da8dSAndroid Build Coastguard Workerclass _SocketWriter(BufferedIOBase):
823*cda5da8dSAndroid Build Coastguard Worker    """Simple writable BufferedIOBase implementation for a socket
824*cda5da8dSAndroid Build Coastguard Worker
825*cda5da8dSAndroid Build Coastguard Worker    Does not hold data in a buffer, avoiding any need to call flush()."""
826*cda5da8dSAndroid Build Coastguard Worker
827*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, sock):
828*cda5da8dSAndroid Build Coastguard Worker        self._sock = sock
829*cda5da8dSAndroid Build Coastguard Worker
830*cda5da8dSAndroid Build Coastguard Worker    def writable(self):
831*cda5da8dSAndroid Build Coastguard Worker        return True
832*cda5da8dSAndroid Build Coastguard Worker
833*cda5da8dSAndroid Build Coastguard Worker    def write(self, b):
834*cda5da8dSAndroid Build Coastguard Worker        self._sock.sendall(b)
835*cda5da8dSAndroid Build Coastguard Worker        with memoryview(b) as view:
836*cda5da8dSAndroid Build Coastguard Worker            return view.nbytes
837*cda5da8dSAndroid Build Coastguard Worker
838*cda5da8dSAndroid Build Coastguard Worker    def fileno(self):
839*cda5da8dSAndroid Build Coastguard Worker        return self._sock.fileno()
840*cda5da8dSAndroid Build Coastguard Worker
841*cda5da8dSAndroid Build Coastguard Workerclass DatagramRequestHandler(BaseRequestHandler):
842*cda5da8dSAndroid Build Coastguard Worker
843*cda5da8dSAndroid Build Coastguard Worker    """Define self.rfile and self.wfile for datagram sockets."""
844*cda5da8dSAndroid Build Coastguard Worker
845*cda5da8dSAndroid Build Coastguard Worker    def setup(self):
846*cda5da8dSAndroid Build Coastguard Worker        from io import BytesIO
847*cda5da8dSAndroid Build Coastguard Worker        self.packet, self.socket = self.request
848*cda5da8dSAndroid Build Coastguard Worker        self.rfile = BytesIO(self.packet)
849*cda5da8dSAndroid Build Coastguard Worker        self.wfile = BytesIO()
850*cda5da8dSAndroid Build Coastguard Worker
851*cda5da8dSAndroid Build Coastguard Worker    def finish(self):
852*cda5da8dSAndroid Build Coastguard Worker        self.socket.sendto(self.wfile.getvalue(), self.client_address)
853