Mercurial > cpython-lru_cache-weakref
annotate Lib/SocketServer.py @ 16413:8819867f14ef legacy-trunk
Patch derived from Trent's 101162: a Python/C API testing framework.
STILL NEEDS UNIX BUILD CHANGES.
| author | Tim Peters <tim.peters@gmail.com> |
|---|---|
| date | Fri, 02 Feb 2001 05:57:15 +0000 |
| parents | b5345e99596b |
| children | 13857fb33017 |
| rev | line source |
|---|---|
| 2887 | 1 """Generic socket server classes. |
| 2 | |
| 3 This module tries to capture the various aspects of defining a server: | |
| 4 | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
5 For socket-based servers: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
6 |
| 2887 | 7 - address family: |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
8 - 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
|
9 - 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
|
10 - others, e.g. AF_DECNET are conceivable (see <socket.h> |
| 2887 | 11 - socket type: |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
12 - 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
|
13 - SOCK_DGRAM (datagrams, e.g. UDP) |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
14 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
15 For request-based servers (including socket-based): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
16 |
| 2887 | 17 - 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
|
18 (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
|
19 at the request before anything else, e.g. logging) |
| 2887 | 20 - 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
|
21 - 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
|
22 - 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
|
23 - threading (each request is handled by a new thread) |
| 2887 | 24 |
| 25 The classes in this module favor the server type that is simplest to | |
| 26 write: a synchronous TCP/IP server. This is bad class design, but | |
| 27 save some typing. (There's also the issue that a deep class hierarchy | |
| 28 slows down method lookups.) | |
| 29 | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
30 There are five classes in an inheritance diagram, four of which represent |
| 2887 | 31 synchronous servers of four types: |
| 32 | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
33 +------------+ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
34 | BaseServer | |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
35 +------------+ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
36 | |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
37 v |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
38 +-----------+ +------------------+ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
39 | TCPServer |------->| UnixStreamServer | |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
40 +-----------+ +------------------+ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
41 | |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
42 v |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
43 +-----------+ +--------------------+ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
44 | UDPServer |------->| UnixDatagramServer | |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
45 +-----------+ +--------------------+ |
| 2887 | 46 |
|
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
|
47 Note that UnixDatagramServer derives from UDPServer, not from |
| 2887 | 48 UnixStreamServer -- the only difference between an IP and a Unix |
| 49 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
|
50 unix server classes. |
| 2887 | 51 |
| 52 Forking and threading versions of each type of server can be created | |
| 53 using the ForkingServer and ThreadingServer mix-in classes. For | |
| 54 instance, a threading UDP server class is created as follows: | |
| 55 | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
56 class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass |
| 2887 | 57 |
|
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
|
58 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
|
59 in UDPServer! |
| 2887 | 60 |
| 61 To implement a service, you must derive a class from | |
| 62 BaseRequestHandler and redefine its handle() method. You can then run | |
| 63 various versions of the service by combining one of the server classes | |
| 64 with your request handler class. | |
| 65 | |
| 66 The request handler class must be different for datagram or stream | |
| 67 services. This can be hidden by using the mix-in request handler | |
| 68 classes StreamRequestHandler or DatagramRequestHandler. | |
| 69 | |
| 70 Of course, you still have to use your head! | |
| 71 | |
| 72 For instance, it makes no sense to use a forking server if the service | |
| 73 contains state in memory that can be modified by requests (since the | |
| 74 modifications in the child process would never reach the initial state | |
| 75 kept in the parent process and passed to each child). In this case, | |
| 76 you can use a threading server, but you will probably have to use | |
| 77 locks to avoid two requests that come in nearly simultaneous to apply | |
| 78 conflicting changes to the server state. | |
| 79 | |
| 80 On the other hand, if you are building e.g. an HTTP server, where all | |
| 81 data is stored externally (e.g. in the file system), a synchronous | |
| 82 class will essentially render the service "deaf" while one request is | |
| 83 being handled -- which may be for a very long time if a client is slow | |
| 84 to reqd all the data it has requested. Here a threading or forking | |
| 85 server is appropriate. | |
| 86 | |
| 87 In some cases, it may be appropriate to process part of a request | |
| 88 synchronously, but to finish processing in a forked child depending on | |
| 89 the request data. This can be implemented by using a synchronous | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
90 server and doing an explicit fork in the request handler class |
| 2887 | 91 handle() method. |
| 92 | |
| 93 Another approach to handling multiple simultaneous requests in an | |
| 94 environment that supports neither threads nor fork (or where these are | |
| 95 too expensive or inappropriate for the service) is to maintain an | |
| 96 explicit table of partially finished requests and to use select() to | |
| 97 decide which request to work on next (or whether to handle a new | |
| 98 incoming request). This is particularly important for stream services | |
| 99 where each client can potentially be connected for a long time (if | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
100 threads or subprocesses cannot be used). |
| 2887 | 101 |
| 102 Future work: | |
| 103 - Standard classes for Sun RPC (which uses either UDP or TCP) | |
| 104 - Standard mix-in classes to implement various authentication | |
| 105 and encryption schemes | |
| 106 - Standard framework for select-based multiplexing | |
| 107 | |
| 108 XXX Open problems: | |
| 109 - What to do with out-of-band data? | |
| 110 | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
111 BaseServer: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
112 - split generic "request" functionality out into BaseServer class. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
113 Copyright (C) 2000 Luke Kenneth Casson Leighton <lkcl@samba.org> |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
114 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
115 example: read entries from a SQL database (requires overriding |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
116 get_request() to return a table entry from the database). |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
117 entry is processed by a RequestHandlerClass. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
118 |
| 2887 | 119 """ |
| 120 | |
|
16037
ba295e2c73ea
Bump __version__; add authorship note for the BaseServer patch.
Guido van Rossum <guido@python.org>
parents:
16010
diff
changeset
|
121 # Author of the BaseServer patch: Luke Kenneth Casson Leighton |
| 2887 | 122 |
|
16037
ba295e2c73ea
Bump __version__; add authorship note for the BaseServer patch.
Guido van Rossum <guido@python.org>
parents:
16010
diff
changeset
|
123 __version__ = "0.3" |
| 2887 | 124 |
| 125 | |
| 126 import socket | |
| 127 import sys | |
| 128 import os | |
| 129 | |
|
16070
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
16037
diff
changeset
|
130 __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", |
|
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
16037
diff
changeset
|
131 "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", |
|
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
16037
diff
changeset
|
132 "StreamRequestHandler","DatagramRequestHandler"] |
|
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
16037
diff
changeset
|
133 if hasattr(socket, "AF_UNIX"): |
|
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
16037
diff
changeset
|
134 __all__.extend(["UnixStreamServer","UnixDatagramServer", |
|
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
16037
diff
changeset
|
135 "ThreadingUnixStreamServer", |
|
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
16037
diff
changeset
|
136 "ThreadingUnixDatagramServer"]) |
| 2887 | 137 |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
138 class BaseServer: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
139 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
140 """Base class for server classes. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
141 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
142 Methods for the caller: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
143 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
144 - __init__(server_address, RequestHandlerClass) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
145 - serve_forever() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
146 - handle_request() # if you do not use serve_forever() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
147 - fileno() -> int # for select() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
148 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
149 Methods that may be overridden: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
150 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
151 - server_bind() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
152 - server_activate() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
153 - get_request() -> request, client_address |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
154 - verify_request(request, client_address) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
155 - server_close() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
156 - process_request(request, client_address) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
157 - handle_error() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
158 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
159 Methods for derived classes: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
160 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
161 - finish_request(request, client_address) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
162 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
163 Class variables that may be overridden by derived classes or |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
164 instances: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
165 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
166 - address_family |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
167 - socket_type |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
168 - reuse_address |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
169 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
170 Instance variables: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
171 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
172 - RequestHandlerClass |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
173 - socket |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
174 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
175 """ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
176 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
177 def __init__(self, server_address, RequestHandlerClass): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
178 """Constructor. May be extended, do not override.""" |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
179 self.server_address = server_address |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
180 self.RequestHandlerClass = RequestHandlerClass |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
181 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
182 def server_activate(self): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
183 """Called by constructor to activate the server. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
184 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
185 May be overridden. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
186 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
187 """ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
188 pass |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
189 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
190 def serve_forever(self): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
191 """Handle one request at a time until doomsday.""" |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
192 while 1: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
193 self.handle_request() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
194 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
195 # The distinction between handling, getting, processing and |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
196 # finishing a request is fairly arbitrary. Remember: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
197 # |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
198 # - handle_request() is the top-level call. It calls |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
199 # get_request(), verify_request() and process_request() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
200 # - get_request() is different for stream or datagram sockets |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
201 # - process_request() is the place that may fork a new process |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
202 # or create a new thread to finish the request |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
203 # - finish_request() instantiates the request handler class; |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
204 # this constructor will handle the request all by itself |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
205 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
206 def handle_request(self): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
207 """Handle one request, possibly blocking.""" |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
208 try: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
209 request, client_address = self.get_request() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
210 except socket.error: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
211 return |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
212 if self.verify_request(request, client_address): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
213 try: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
214 self.process_request(request, client_address) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
215 except: |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
216 self.handle_error(request, client_address) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
217 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
218 def verify_request(self, request, client_address): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
219 """Verify the request. May be overridden. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
220 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
221 Return true if we should proceed with this request. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
222 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
223 """ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
224 return 1 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
225 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
226 def process_request(self, request, client_address): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
227 """Call finish_request. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
228 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
229 Overridden by ForkingMixIn and ThreadingMixIn. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
230 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
231 """ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
232 self.finish_request(request, client_address) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
233 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
234 def server_close(self): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
235 """Called to clean-up the server. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
236 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
237 May be overridden. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
238 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
239 """ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
240 pass |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
241 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
242 def finish_request(self, request, client_address): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
243 """Finish one request by instantiating RequestHandlerClass.""" |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
244 self.RequestHandlerClass(request, client_address, self) |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
245 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
246 def handle_error(self, request, client_address): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
247 """Handle an error gracefully. May be overridden. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
248 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
249 The default is to print a traceback and continue. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
250 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
251 """ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
252 print '-'*40 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
253 print 'Exception happened during processing of request from', |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
254 print client_address |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
255 import traceback |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
256 traceback.print_exc() # XXX But this goes to stderr! |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
257 print '-'*40 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
258 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
259 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
260 class TCPServer(BaseServer): |
| 2887 | 261 |
| 262 """Base class for various socket-based server classes. | |
| 263 | |
| 264 Defaults to synchronous IP stream (i.e., TCP). | |
| 265 | |
| 266 Methods for the caller: | |
| 267 | |
| 268 - __init__(server_address, RequestHandlerClass) | |
| 269 - serve_forever() | |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
270 - 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
|
271 - fileno() -> int # for select() |
| 2887 | 272 |
| 273 Methods that may be overridden: | |
| 274 | |
| 275 - server_bind() | |
| 276 - server_activate() | |
| 277 - get_request() -> request, client_address | |
| 278 - verify_request(request, client_address) | |
| 279 - process_request(request, client_address) | |
| 280 - handle_error() | |
| 281 | |
| 282 Methods for derived classes: | |
| 283 | |
| 284 - finish_request(request, client_address) | |
| 285 | |
| 286 Class variables that may be overridden by derived classes or | |
| 287 instances: | |
| 288 | |
| 289 - address_family | |
| 290 - socket_type | |
| 291 - request_queue_size (only for stream sockets) | |
|
12633
a56707b07b81
Add class variable allow_reuse_address in TCPServer -- if nonzero, the
Guido van Rossum <guido@python.org>
parents:
11382
diff
changeset
|
292 - reuse_address |
| 2887 | 293 |
| 294 Instance variables: | |
| 295 | |
| 296 - server_address | |
| 297 - RequestHandlerClass | |
| 298 - socket | |
| 299 | |
| 300 """ | |
| 301 | |
| 302 address_family = socket.AF_INET | |
| 303 | |
| 304 socket_type = socket.SOCK_STREAM | |
| 305 | |
| 306 request_queue_size = 5 | |
| 307 | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
308 allow_reuse_address = 0 |
|
12633
a56707b07b81
Add class variable allow_reuse_address in TCPServer -- if nonzero, the
Guido van Rossum <guido@python.org>
parents:
11382
diff
changeset
|
309 |
| 2887 | 310 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
|
311 """Constructor. May be extended, do not override.""" |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
312 BaseServer.__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
|
313 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
|
314 self.socket_type) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
315 self.server_bind() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
316 self.server_activate() |
| 2887 | 317 |
| 318 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
|
319 """Called by constructor to bind the socket. |
| 2887 | 320 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
321 May be overridden. |
| 2887 | 322 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
323 """ |
|
12633
a56707b07b81
Add class variable allow_reuse_address in TCPServer -- if nonzero, the
Guido van Rossum <guido@python.org>
parents:
11382
diff
changeset
|
324 if self.allow_reuse_address: |
|
a56707b07b81
Add class variable allow_reuse_address in TCPServer -- if nonzero, the
Guido van Rossum <guido@python.org>
parents:
11382
diff
changeset
|
325 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
326 self.socket.bind(self.server_address) |
| 2887 | 327 |
| 328 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
|
329 """Called by constructor to activate the server. |
| 2887 | 330 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
331 May be overridden. |
| 2887 | 332 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
333 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
334 self.socket.listen(self.request_queue_size) |
| 2887 | 335 |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
336 def server_close(self): |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
337 """Called to clean-up the server. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
338 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
339 May be overridden. |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
340 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
341 """ |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
342 self.socket.close() |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
343 |
| 2887 | 344 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
|
345 """Return socket file number. |
| 2887 | 346 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
347 Interface required by select(). |
| 2887 | 348 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
349 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
350 return self.socket.fileno() |
| 2887 | 351 |
| 352 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
|
353 """Get the request and client address from the socket. |
| 2887 | 354 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
355 May be overridden. |
| 2887 | 356 |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
357 """ |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
358 return self.socket.accept() |
| 2887 | 359 |
| 360 | |
| 361 class UDPServer(TCPServer): | |
| 362 | |
| 363 """UDP server class.""" | |
| 364 | |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
365 allow_reuse_address = 0 |
|
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
366 |
| 2887 | 367 socket_type = socket.SOCK_DGRAM |
| 368 | |
| 369 max_packet_size = 8192 | |
| 370 | |
| 371 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
|
372 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
|
373 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
|
374 |
|
de0f0c3ed424
Fixed the UDP server -- this never worked. Ray Loyzaga deserves
Guido van Rossum <guido@python.org>
parents:
7840
diff
changeset
|
375 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
|
376 # 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
|
377 pass |
| 2887 | 378 |
| 379 | |
| 380 class ForkingMixIn: | |
| 381 | |
| 382 """Mix-in class to handle each request in a new process.""" | |
| 383 | |
| 384 active_children = None | |
|
11145
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
385 max_children = 40 |
| 2887 | 386 |
| 387 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
|
388 """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
|
389 while self.active_children: |
|
11145
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
390 if len(self.active_children) < self.max_children: |
|
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
391 options = os.WNOHANG |
|
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
392 else: |
|
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
393 # If the maximum number of children are already |
|
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
394 # running, block while waiting for a child to exit |
|
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
395 options = 0 |
|
11001
926cb5a5ee30
In collect_children(), put a try-except around os.waitpid() because it
Guido van Rossum <guido@python.org>
parents:
10992
diff
changeset
|
396 try: |
|
11145
d997e27e3312
Another patch from Andy Dustman:
Guido van Rossum <guido@python.org>
parents:
11001
diff
changeset
|
397 pid, status = os.waitpid(0, options) |
|
11001
926cb5a5ee30
In collect_children(), put a try-except around os.waitpid() because it
Guido van Rossum <guido@python.org>
parents:
10992
diff
changeset
|
398 except os.error: |
|
926cb5a5ee30
In collect_children(), put a try-except around os.waitpid() because it
Guido van Rossum <guido@python.org>
parents:
10992
diff
changeset
|
399 pid = None |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
400 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
|
401 self.active_children.remove(pid) |
| 2887 | 402 |
| 403 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
|
404 """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
|
405 self.collect_children() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
406 pid = os.fork() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
407 if pid: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
408 # Parent process |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
409 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
|
410 self.active_children = [] |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
411 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
|
412 return |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
413 else: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
414 # Child process. |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
415 # 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
|
416 try: |
|
16010
33f5ee6a0ebe
SF Patch #102980, by Luke Kenneth Casson Leighton: BaseServer class
Guido van Rossum <guido@python.org>
parents:
15556
diff
changeset
|
417 self.server_close() |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
418 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
|
419 os._exit(0) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
420 except: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
421 try: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
422 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
|
423 client_address) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
424 finally: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
425 os._exit(1) |
| 2887 | 426 |
| 427 | |
| 428 class ThreadingMixIn: | |
| 429 """Mix-in class to handle each request in a new thread.""" | |
| 430 | |
| 431 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
|
432 """Start a new thread to process the request.""" |
|
11382
1ef1807377bf
update to use threading module instead of thread.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
11145
diff
changeset
|
433 import threading |
|
1ef1807377bf
update to use threading module instead of thread.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
11145
diff
changeset
|
434 t = threading.Thread(target = self.finish_request, |
|
1ef1807377bf
update to use threading module instead of thread.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
11145
diff
changeset
|
435 args = (request, client_address)) |
|
1ef1807377bf
update to use threading module instead of thread.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
11145
diff
changeset
|
436 t.start() |
| 2887 | 437 |
| 438 | |
| 439 class ForkingUDPServer(ForkingMixIn, UDPServer): pass | |
| 440 class ForkingTCPServer(ForkingMixIn, TCPServer): pass | |
| 441 | |
| 442 class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass | |
| 443 class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass | |
| 444 | |
|
9544
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
445 if hasattr(socket, 'AF_UNIX'): |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
446 |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
447 class UnixStreamServer(TCPServer): |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
448 address_family = socket.AF_UNIX |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
449 |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
450 class UnixDatagramServer(UDPServer): |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
451 address_family = socket.AF_UNIX |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
452 |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
453 class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
454 |
|
16af2582c964
Patch by Jeff Bauer: a minor change to declare two new
Guido van Rossum <guido@python.org>
parents:
9485
diff
changeset
|
455 class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass |
| 2887 | 456 |
| 457 class BaseRequestHandler: | |
| 458 | |
| 459 """Base class for request handler classes. | |
| 460 | |
| 461 This class is instantiated for each request to be handled. The | |
| 462 constructor sets the instance variables request, client_address | |
| 463 and server, and then calls the handle() method. To implement a | |
| 464 specific service, all you need to do is to derive a class which | |
| 465 defines a handle() method. | |
| 466 | |
| 467 The handle() method can find the request as self.request, the | |
|
9485
6e6be896ec46
Fix typo in docstring: client_request should be client_address.
Guido van Rossum <guido@python.org>
parents:
8510
diff
changeset
|
468 client address as self.client_address, and the server (in case it |
| 2887 | 469 needs access to per-server information) as self.server. Since a |
| 470 separate instance is created for each request, the handle() method | |
| 471 can define arbitrary other instance variariables. | |
| 472 | |
| 473 """ | |
| 474 | |
| 475 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
|
476 self.request = request |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
477 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
|
478 self.server = server |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
479 try: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
480 self.setup() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
481 self.handle() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
482 self.finish() |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
483 finally: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
484 sys.exc_traceback = None # Help garbage collection |
| 2887 | 485 |
| 486 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
|
487 pass |
| 2887 | 488 |
| 489 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
|
490 pass |
| 2887 | 491 |
| 492 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
|
493 pass |
| 2887 | 494 |
| 495 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
|
496 pass |
| 2887 | 497 |
| 498 | |
| 499 # The following two classes make it possible to use the same service | |
| 500 # class for stream or datagram servers. | |
| 501 # Each class sets up these instance variables: | |
| 502 # - rfile: a file object from which receives the request is read | |
| 503 # - wfile: a file object to which the reply is written | |
| 504 # When the handle() method returns, wfile is flushed properly | |
| 505 | |
| 506 | |
| 507 class StreamRequestHandler(BaseRequestHandler): | |
| 508 | |
| 509 """Define self.rfile and self.wfile for stream sockets.""" | |
| 510 | |
|
14331
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
511 # Default buffer sizes for rfile, wfile. |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
512 # We default rfile to buffered because otherwise it could be |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
513 # really slow for large data (a getc() call per byte); we make |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
514 # wfile unbuffered because (a) often after a write() we want to |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
515 # read and we need to flush the line; (b) big writes to unbuffered |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
516 # files are typically optimized by stdio even when big reads |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
517 # aren't. |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
518 rbufsize = -1 |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
519 wbufsize = 0 |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
520 |
| 2887 | 521 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
|
522 self.connection = self.request |
|
14331
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
523 self.rfile = self.connection.makefile('rb', self.rbufsize) |
|
cbe423b3ba3a
In class StreamRequestHandler, make the default buffering for rfile
Guido van Rossum <guido@python.org>
parents:
12633
diff
changeset
|
524 self.wfile = self.connection.makefile('wb', self.wbufsize) |
| 2887 | 525 |
| 526 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
|
527 self.wfile.flush() |
|
7840
aaa204a05f84
Explicitly close rfile and wfile in StreamRequestHandler.finish() --
Guido van Rossum <guido@python.org>
parents:
7755
diff
changeset
|
528 self.wfile.close() |
|
aaa204a05f84
Explicitly close rfile and wfile in StreamRequestHandler.finish() --
Guido van Rossum <guido@python.org>
parents:
7755
diff
changeset
|
529 self.rfile.close() |
| 2887 | 530 |
| 531 | |
| 532 class DatagramRequestHandler(BaseRequestHandler): | |
| 533 | |
| 534 """Define self.rfile and self.wfile for datagram sockets.""" | |
| 535 | |
| 536 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
|
537 import StringIO |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
6346
diff
changeset
|
538 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
|
539 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
|
540 self.wfile = StringIO.StringIO(self.packet) |
| 2887 | 541 |
| 542 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
|
543 self.socket.sendto(self.wfile.getvalue(), self.client_address) |
