Mercurial > cpython-lru_cache-weakref
annotate Lib/SocketServer.py @ 8831:00a6bb65ff29 legacy-trunk
Getting rid of this ancient stuff.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Wed, 05 Aug 1998 21:10:09 +0000 |
| parents | de0f0c3ed424 |
| children | 6e6be896ec46 |
| rev | line source |
|---|---|
| 2887 | 1 """Generic socket server classes. |
| 2 | |
| 3 This module tries to capture the various aspects of defining a server: | |
| 4 | |
| 5 - address family: | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
6 - AF_INET: IP (Internet Protocol) sockets (default) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
7 - AF_UNIX: Unix domain sockets |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
8 - others, e.g. AF_DECNET are conceivable (see <socket.h> |
| 2887 | 9 - socket type: |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
10 - SOCK_STREAM (reliable stream, e.g. TCP) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
11 - SOCK_DGRAM (datagrams, e.g. UDP) |
| 2887 | 12 - client address verification before further looking at the request |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
13 (This is actually a hook for any processing that needs to look |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
14 at the request before anything else, e.g. logging) |
| 2887 | 15 - how to handle multiple requests: |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
16 - synchronous (one request is handled at a time) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
17 - forking (each request is handled by a new process) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
18 - threading (each request is handled by a new thread) |
| 2887 | 19 |
| 20 The classes in this module favor the server type that is simplest to | |
| 21 write: a synchronous TCP/IP server. This is bad class design, but | |
| 22 save some typing. (There's also the issue that a deep class hierarchy | |
| 23 slows down method lookups.) | |
| 24 | |
| 25 There are four classes in an inheritance diagram that represent | |
| 26 synchronous servers of four types: | |
| 27 | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
28 +-----------+ +------------------+ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
29 | TCPServer |------->| UnixStreamServer | |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
30 +-----------+ +------------------+ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
31 | |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
32 v |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
33 +-----------+ +--------------------+ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
34 | UDPServer |------->| UnixDatagramServer | |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
35 +-----------+ +--------------------+ |
| 2887 | 36 |
|
5803
b56d527a433f
Fix bug found by kjpylint; change doc string to avoid "(" in column 1.
Guido van Rossum <guido@python.org>
parents:
4459
diff
changeset
|
37 Note that UnixDatagramServer derives from UDPServer, not from |
| 2887 | 38 UnixStreamServer -- the only difference between an IP and a Unix |
| 39 stream server is the address family, which is simply repeated in both | |
|
5803
b56d527a433f
Fix bug found by kjpylint; change doc string to avoid "(" in column 1.
Guido van Rossum <guido@python.org>
parents:
4459
diff
changeset
|
40 unix server classes. |
| 2887 | 41 |
| 42 Forking and threading versions of each type of server can be created | |
| 43 using the ForkingServer and ThreadingServer mix-in classes. For | |
| 44 instance, a threading UDP server class is created as follows: | |
| 45 | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
46 class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass |
| 2887 | 47 |
|
5803
b56d527a433f
Fix bug found by kjpylint; change doc string to avoid "(" in column 1.
Guido van Rossum <guido@python.org>
parents:
4459
diff
changeset
|
48 The Mix-in class must come first, since it overrides a method defined |
|
b56d527a433f
Fix bug found by kjpylint; change doc string to avoid "(" in column 1.
Guido van Rossum <guido@python.org>
parents:
4459
diff
changeset
|
49 in UDPServer! |
| 2887 | 50 |
| 51 To implement a service, you must derive a class from | |
| 52 BaseRequestHandler and redefine its handle() method. You can then run | |
| 53 various versions of the service by combining one of the server classes | |
| 54 with your request handler class. | |
| 55 | |
| 56 The request handler class must be different for datagram or stream | |
| 57 services. This can be hidden by using the mix-in request handler | |
| 58 classes StreamRequestHandler or DatagramRequestHandler. | |
| 59 | |
| 60 Of course, you still have to use your head! | |
| 61 | |
| 62 For instance, it makes no sense to use a forking server if the service | |
| 63 contains state in memory that can be modified by requests (since the | |
| 64 modifications in the child process would never reach the initial state | |
| 65 kept in the parent process and passed to each child). In this case, | |
| 66 you can use a threading server, but you will probably have to use | |
| 67 locks to avoid two requests that come in nearly simultaneous to apply | |
| 68 conflicting changes to the server state. | |
| 69 | |
| 70 On the other hand, if you are building e.g. an HTTP server, where all | |
| 71 data is stored externally (e.g. in the file system), a synchronous | |
| 72 class will essentially render the service "deaf" while one request is | |
| 73 being handled -- which may be for a very long time if a client is slow | |
| 74 to reqd all the data it has requested. Here a threading or forking | |
| 75 server is appropriate. | |
| 76 | |
| 77 In some cases, it may be appropriate to process part of a request | |
| 78 synchronously, but to finish processing in a forked child depending on | |
| 79 the request data. This can be implemented by using a synchronous | |
| 80 server and doing an explicit fork in the request handler class's | |
| 81 handle() method. | |
| 82 | |
| 83 Another approach to handling multiple simultaneous requests in an | |
| 84 environment that supports neither threads nor fork (or where these are | |
| 85 too expensive or inappropriate for the service) is to maintain an | |
| 86 explicit table of partially finished requests and to use select() to | |
| 87 decide which request to work on next (or whether to handle a new | |
| 88 incoming request). This is particularly important for stream services | |
| 89 where each client can potentially be connected for a long time (if | |
| 90 threads or subprocesses can't be used). | |
| 91 | |
| 92 Future work: | |
| 93 - Standard classes for Sun RPC (which uses either UDP or TCP) | |
| 94 - Standard mix-in classes to implement various authentication | |
| 95 and encryption schemes | |
| 96 - Standard framework for select-based multiplexing | |
| 97 | |
| 98 XXX Open problems: | |
| 99 - What to do with out-of-band data? | |
| 100 | |
| 101 """ | |
| 102 | |
| 103 | |
| 104 __version__ = "0.2" | |
| 105 | |
| 106 | |
| 107 import socket | |
| 108 import sys | |
| 109 import os | |
| 110 | |
| 111 | |
| 112 class TCPServer: | |
| 113 | |
| 114 """Base class for various socket-based server classes. | |
| 115 | |
| 116 Defaults to synchronous IP stream (i.e., TCP). | |
| 117 | |
| 118 Methods for the caller: | |
| 119 | |
| 120 - __init__(server_address, RequestHandlerClass) | |
| 121 - serve_forever() | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
122 - handle_request() # if you don't use serve_forever() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
123 - fileno() -> int # for select() |
| 2887 | 124 |
| 125 Methods that may be overridden: | |
| 126 | |
| 127 - server_bind() | |
| 128 - server_activate() | |
| 129 - get_request() -> request, client_address | |
| 130 - verify_request(request, client_address) | |
| 131 - process_request(request, client_address) | |
| 132 - handle_error() | |
| 133 | |
| 134 Methods for derived classes: | |
| 135 | |
| 136 - finish_request(request, client_address) | |
| 137 | |
| 138 Class variables that may be overridden by derived classes or | |
| 139 instances: | |
| 140 | |
| 141 - address_family | |
| 142 - socket_type | |
| 143 - request_queue_size (only for stream sockets) | |
| 144 | |
| 145 Instance variables: | |
| 146 | |
| 147 - server_address | |
| 148 - RequestHandlerClass | |
| 149 - socket | |
| 150 | |
| 151 """ | |
| 152 | |
| 153 address_family = socket.AF_INET | |
| 154 | |
| 155 socket_type = socket.SOCK_STREAM | |
| 156 | |
| 157 request_queue_size = 5 | |
| 158 | |
| 159 def __init__(self, server_address, RequestHandlerClass): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
160 """Constructor. May be extended, do not override.""" |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
161 self.server_address = server_address |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
162 self.RequestHandlerClass = RequestHandlerClass |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
163 self.socket = socket.socket(self.address_family, |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
164 self.socket_type) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
165 self.server_bind() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
166 self.server_activate() |
| 2887 | 167 |
| 168 def server_bind(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
169 """Called by constructor to bind the socket. |
| 2887 | 170 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
171 May be overridden. |
| 2887 | 172 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
173 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
174 self.socket.bind(self.server_address) |
| 2887 | 175 |
| 176 def server_activate(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
177 """Called by constructor to activate the server. |
| 2887 | 178 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
179 May be overridden. |
| 2887 | 180 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
181 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
182 self.socket.listen(self.request_queue_size) |
| 2887 | 183 |
| 184 def fileno(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
185 """Return socket file number. |
| 2887 | 186 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
187 Interface required by select(). |
| 2887 | 188 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
189 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
190 return self.socket.fileno() |
| 2887 | 191 |
| 192 def serve_forever(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
193 """Handle one request at a time until doomsday.""" |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
194 while 1: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
195 self.handle_request() |
| 2887 | 196 |
| 197 # The distinction between handling, getting, processing and | |
| 198 # finishing a request is fairly arbitrary. Remember: | |
| 199 # | |
| 200 # - handle_request() is the top-level call. It calls | |
| 201 # get_request(), verify_request() and process_request() | |
| 202 # - get_request() is different for stream or datagram sockets | |
| 203 # - process_request() is the place that may fork a new process | |
| 204 # or create a new thread to finish the request | |
| 205 # - finish_request() instantiates the request handler class; | |
| 206 # this constructor will handle the request all by itself | |
| 207 | |
| 208 def handle_request(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
209 """Handle one request, possibly blocking.""" |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
210 request, client_address = self.get_request() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
211 if self.verify_request(request, client_address): |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
212 try: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
213 self.process_request(request, client_address) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
214 except: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
215 self.handle_error(request, client_address) |
| 2887 | 216 |
| 217 def get_request(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
218 """Get the request and client address from the socket. |
| 2887 | 219 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
220 May be overridden. |
| 2887 | 221 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
222 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
223 return self.socket.accept() |
| 2887 | 224 |
| 225 def verify_request(self, request, client_address): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
226 """Verify the request. May be overridden. |
| 2887 | 227 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
228 Return true if we should proceed with this request. |
| 2887 | 229 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
230 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
231 return 1 |
| 2887 | 232 |
| 233 def process_request(self, request, client_address): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
234 """Call finish_request. |
| 2887 | 235 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
236 Overridden by ForkingMixIn and ThreadingMixIn. |
| 2887 | 237 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
238 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
239 self.finish_request(request, client_address) |
| 2887 | 240 |
| 241 def finish_request(self, request, client_address): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
242 """Finish one request by instantiating RequestHandlerClass.""" |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
243 self.RequestHandlerClass(request, client_address, self) |
| 2887 | 244 |
| 245 def handle_error(self, request, client_address): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
246 """Handle an error gracefully. May be overridden. |
| 2887 | 247 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
248 The default is to print a traceback and continue. |
| 2887 | 249 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
250 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
251 print '-'*40 |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
252 print 'Exception happened during processing of request from', |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
253 print client_address |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
254 import traceback |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
255 traceback.print_exc() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
256 print '-'*40 |
| 2887 | 257 |
| 258 | |
| 259 class UDPServer(TCPServer): | |
| 260 | |
| 261 """UDP server class.""" | |
| 262 | |
| 263 socket_type = socket.SOCK_DGRAM | |
| 264 | |
| 265 max_packet_size = 8192 | |
| 266 | |
| 267 def get_request(self): | |
|
8510
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
268 data, client_addr = self.socket.recvfrom(self.max_packet_size) |
|
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
269 return (data, self.socket), client_addr |
|
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
270 |
|
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
271 def server_activate(self): |
|
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
272 # No need to call listen() for UDP. |
|
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
273 pass |
| 2887 | 274 |
| 275 | |
| 276 if hasattr(socket, 'AF_UNIX'): | |
| 277 | |
| 278 class UnixStreamServer(TCPServer): | |
| 279 | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
280 address_family = socket.AF_UNIX |
| 2887 | 281 |
| 282 | |
| 283 class UnixDatagramServer(UDPServer): | |
| 284 | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
285 address_family = socket.AF_UNIX |
| 2887 | 286 |
| 287 | |
| 288 class ForkingMixIn: | |
| 289 | |
| 290 """Mix-in class to handle each request in a new process.""" | |
| 291 | |
| 292 active_children = None | |
| 293 | |
| 294 def collect_children(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
295 """Internal routine to wait for died children.""" |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
296 while self.active_children: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
297 pid, status = os.waitpid(0, os.WNOHANG) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
298 if not pid: break |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
299 self.active_children.remove(pid) |
| 2887 | 300 |
| 301 def process_request(self, request, client_address): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
302 """Fork a new subprocess to process the request.""" |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
303 self.collect_children() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
304 pid = os.fork() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
305 if pid: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
306 # Parent process |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
307 if self.active_children is None: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
308 self.active_children = [] |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
309 self.active_children.append(pid) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
310 return |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
311 else: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
312 # Child process. |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
313 # This must never return, hence os._exit()! |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
314 try: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
315 self.finish_request(request, client_address) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
316 os._exit(0) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
317 except: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
318 try: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
319 self.handle_error(request, |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
320 client_address) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
321 finally: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
322 os._exit(1) |
| 2887 | 323 |
| 324 | |
| 325 class ThreadingMixIn: | |
| 326 | |
| 327 """Mix-in class to handle each request in a new thread.""" | |
| 328 | |
| 329 def process_request(self, request, client_address): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
330 """Start a new thread to process the request.""" |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
331 import thread |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
332 thread.start_new_thread(self.finish_request, |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
333 (request, client_address)) |
| 2887 | 334 |
| 335 | |
| 336 class ForkingUDPServer(ForkingMixIn, UDPServer): pass | |
| 337 class ForkingTCPServer(ForkingMixIn, TCPServer): pass | |
| 338 | |
| 339 class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass | |
| 340 class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass | |
| 341 | |
| 342 | |
| 343 class BaseRequestHandler: | |
| 344 | |
| 345 """Base class for request handler classes. | |
| 346 | |
| 347 This class is instantiated for each request to be handled. The | |
| 348 constructor sets the instance variables request, client_address | |
| 349 and server, and then calls the handle() method. To implement a | |
| 350 specific service, all you need to do is to derive a class which | |
| 351 defines a handle() method. | |
| 352 | |
| 353 The handle() method can find the request as self.request, the | |
| 354 client address as self.client_request, and the server (in case it | |
| 355 needs access to per-server information) as self.server. Since a | |
| 356 separate instance is created for each request, the handle() method | |
| 357 can define arbitrary other instance variariables. | |
| 358 | |
| 359 """ | |
| 360 | |
| 361 def __init__(self, request, client_address, server): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
362 self.request = request |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
363 self.client_address = client_address |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
364 self.server = server |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
365 try: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
366 self.setup() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
367 self.handle() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
368 self.finish() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
369 finally: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
370 sys.exc_traceback = None # Help garbage collection |
| 2887 | 371 |
| 372 def setup(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
373 pass |
| 2887 | 374 |
| 375 def __del__(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
376 pass |
| 2887 | 377 |
| 378 def handle(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
379 pass |
| 2887 | 380 |
| 381 def finish(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
382 pass |
| 2887 | 383 |
| 384 | |
| 385 # The following two classes make it possible to use the same service | |
| 386 # class for stream or datagram servers. | |
| 387 # Each class sets up these instance variables: | |
| 388 # - rfile: a file object from which receives the request is read | |
| 389 # - wfile: a file object to which the reply is written | |
| 390 # When the handle() method returns, wfile is flushed properly | |
| 391 | |
| 392 | |
| 393 class StreamRequestHandler(BaseRequestHandler): | |
| 394 | |
| 395 """Define self.rfile and self.wfile for stream sockets.""" | |
| 396 | |
| 397 def setup(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
398 self.connection = self.request |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
399 self.rfile = self.connection.makefile('rb', 0) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
400 self.wfile = self.connection.makefile('wb', 0) |
| 2887 | 401 |
| 402 def finish(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
403 self.wfile.flush() |
|
7840
aaa204a05f84
Explicitly close rfile and wfile in StreamRequestHandler.finish() --
Guido van Rossum <guido@python.org>
parents:
7755
diff
changeset
|
404 self.wfile.close() |
|
aaa204a05f84
Explicitly close rfile and wfile in StreamRequestHandler.finish() --
Guido van Rossum <guido@python.org>
parents:
7755
diff
changeset
|
405 self.rfile.close() |
| 2887 | 406 |
| 407 | |
| 408 class DatagramRequestHandler(BaseRequestHandler): | |
| 409 | |
| 410 """Define self.rfile and self.wfile for datagram sockets.""" | |
| 411 | |
| 412 def setup(self): | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
413 import StringIO |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
414 self.packet, self.socket = self.request |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
415 self.rfile = StringIO.StringIO(self.packet) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
416 self.wfile = StringIO.StringIO(self.packet) |
| 2887 | 417 |
| 418 def finish(self): | |
|
8510
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
419 self.socket.sendto(self.wfile.getvalue(), self.client_address) |
