blob: 03fe9ea3c66e51286ec6d0abea72b5be3b5c93cb [file] [log] [blame]
Steve Holdenb1af86a2002-07-03 18:36:39 +00001\section{\module{asynchat} ---
2 Asynchronous socket command/response handler}
3
4\declaremodule{standard}{asynchat}
5\modulesynopsis{Support for asynchronous command/response protocols.}
6\moduleauthor{Sam Rushing}{rushing@nightmare.com}
7\sectionauthor{Steve Holden}{sholden@holdenweb.com}
8
9This module builds on the \refmodule{asyncore} infrastructure,
10simplifying asynchronous clients and servers and making it easier to
11handle protocols whose elements are terminated by arbitrary strings, or
12are of variable length. \refmodule{asynchat} defines the abstract class
13\class{async_chat} that you subclass, providing implementations of the
14\method{collect_incoming_data()} and \method{found_terminator()}
15methods. It uses the same asynchronous loop as \refmodule{asyncore}, and
Thomas Hellerc6874012002-09-17 15:19:12 +000016the two types of channel, \class{asyncore.dispatcher} and
Steve Holdenb1af86a2002-07-03 18:36:39 +000017\class{asynchat.async_chat}, can freely be mixed in the channel map.
Thomas Hellerc6874012002-09-17 15:19:12 +000018Typically an \class{asyncore.dispatcher} server channel generates new
Steve Holdenb1af86a2002-07-03 18:36:39 +000019\class{asynchat.async_chat} channel objects as it receives incoming
20connection requests.
21
22\begin{classdesc}{async_chat}{}
Thomas Hellerc6874012002-09-17 15:19:12 +000023 This class is an abstract subclass of \class{asyncore.dispatcher}. To make
Steve Holdenb1af86a2002-07-03 18:36:39 +000024 practical use of the code you must subclass \class{async_chat}, providing
25 meaningful \method{collect_incoming_data()} and \method{found_terminator()}
Thomas Hellerc6874012002-09-17 15:19:12 +000026 methods. The \class{asyncore.dispatcher} methods can be
Steve Holdenb1af86a2002-07-03 18:36:39 +000027 used, although not all make sense in a message/response context.
28
Thomas Hellerc6874012002-09-17 15:19:12 +000029 Like \class{asyncore.dispatcher}, \class{async_chat} defines a set of events
Steve Holdenb1af86a2002-07-03 18:36:39 +000030 that are generated by an analysis of socket conditions after a
31 \cfunction{select()} call. Once the polling loop has been started the
32 \class{async_chat} object's methods are called by the event-processing
33 framework with no action on the part of the programmer.
34
Fred Drake0ac4b272007-10-05 03:12:00 +000035 Two class attributes can be modified, to improve performance,
36 or possibly even to conserve memory.
37
38 \begin{datadesc}{ac_in_buffer_size}
39 The asynchronous input buffer size (default \code{4096}).
40 \end{datadesc}
41
42 \begin{datadesc}{ac_out_buffer_size}
43 The asynchronous output buffer size (default \code{4096}).
44 \end{datadesc}
45
Thomas Hellerc6874012002-09-17 15:19:12 +000046 Unlike \class{asyncore.dispatcher}, \class{async_chat} allows you to define
Steve Holdenb1af86a2002-07-03 18:36:39 +000047 a first-in-first-out queue (fifo) of \emph{producers}. A producer need have
48 only one method, \method{more()}, which should return data to be transmitted
49 on the channel. The producer indicates exhaustion (\emph{i.e.} that it contains
50 no more data) by having its \method{more()} method return the empty string. At
51 this point the \class{async_chat} object removes the producer from the fifo
52 and starts using the next producer, if any. When the producer fifo is empty
53 the \method{handle_write()} method does nothing. You use the channel object's
54 \method{set_terminator()} method to describe how to recognize the end
55 of, or an important breakpoint in, an incoming transmission from the
56 remote endpoint.
57
58 To build a functioning \class{async_chat} subclass your
59 input methods \method{collect_incoming_data()} and
60 \method{found_terminator()} must handle the data that the channel receives
61 asynchronously. The methods are described below.
62\end{classdesc}
63
64\begin{methoddesc}{close_when_done}{}
65 Pushes a \code{None} on to the producer fifo. When this producer is
66 popped off the fifo it causes the channel to be closed.
67\end{methoddesc}
68
69\begin{methoddesc}{collect_incoming_data}{data}
70 Called with \var{data} holding an arbitrary amount of received data.
71 The default method, which must be overridden, raises a \exception{NotImplementedError} exception.
72\end{methoddesc}
73
74\begin{methoddesc}{discard_buffers}{}
75 In emergencies this method will discard any data held in the input and/or
76 output buffers and the producer fifo.
77\end{methoddesc}
78
79\begin{methoddesc}{found_terminator}{}
80 Called when the incoming data stream matches the termination condition
81 set by \method{set_terminator}. The default method, which must be overridden,
82 raises a \exception{NotImplementedError} exception. The buffered input data should
83 be available via an instance attribute.
84\end{methoddesc}
85
86\begin{methoddesc}{get_terminator}{}
87 Returns the current terminator for the channel.
88\end{methoddesc}
89
90\begin{methoddesc}{handle_close}{}
91 Called when the channel is closed. The default method silently closes
92 the channel's socket.
93\end{methoddesc}
94
95\begin{methoddesc}{handle_read}{}
96 Called when a read event fires on the channel's socket in the
97 asynchronous loop. The default method checks for the termination
98 condition established by \method{set_terminator()}, which can be either
99 the appearance of a particular string in the input stream or the receipt
100 of a particular number of characters. When the terminator is found,
101 \method{handle_read} calls the \method{found_terminator()} method after
102 calling \method{collect_incoming_data()} with any data preceding the
103 terminating condition.
104\end{methoddesc}
105
106\begin{methoddesc}{handle_write}{}
107 Called when the application may write data to the channel.
108 The default method calls the \method{initiate_send()} method, which in turn
109 will call \method{refill_buffer()} to collect data from the producer
110 fifo associated with the channel.
111\end{methoddesc}
112
113\begin{methoddesc}{push}{data}
114 Creates a \class{simple_producer} object (\emph{see below}) containing the data and
115 pushes it on to the channel's \code{producer_fifo} to ensure its
116 transmission. This is all you need to do to have the channel write
117 the data out to the network, although it is possible to use your
118 own producers in more complex schemes to implement encryption and
119 chunking, for example.
120\end{methoddesc}
121
122\begin{methoddesc}{push_with_producer}{producer}
123 Takes a producer object and adds it to the producer fifo associated with
124 the channel. When all currently-pushed producers have been exhausted
125 the channel will consume this producer's data by calling its
126 \method{more()} method and send the data to the remote endpoint.
127\end{methoddesc}
128
129\begin{methoddesc}{readable}{}
130 Should return \code{True} for the channel to be included in the set of
131 channels tested by the \cfunction{select()} loop for readability.
132\end{methoddesc}
133
134\begin{methoddesc}{refill_buffer}{}
135 Refills the output buffer by calling the \method{more()} method of the
136 producer at the head of the fifo. If it is exhausted then the
137 producer is popped off the fifo and the next producer is activated.
138 If the current producer is, or becomes, \code{None} then the channel
139 is closed.
140\end{methoddesc}
141
142\begin{methoddesc}{set_terminator}{term}
143 Sets the terminating condition to be recognised on the channel. \code{term}
144 may be any of three types of value, corresponding to three different ways
145 to handle incoming protocol data.
146
147 \begin{tableii}{l|l}{}{term}{Description}
148 \lineii{\emph{string}}{Will call \method{found_terminator()} when the
149 string is found in the input stream}
150 \lineii{\emph{integer}}{Will call \method{found_terminator()} when the
151 indicated number of characters have been received}
152 \lineii{\code{None}}{The channel continues to collect data forever}
153 \end{tableii}
154
155 Note that any data following the terminator will be available for reading by
156 the channel after \method{found_terminator()} is called.
157\end{methoddesc}
158
159\begin{methoddesc}{writable}{}
160 Should return \code{True} as long as items remain on the producer fifo,
161 or the channel is connected and the channel's output buffer is non-empty.
162\end{methoddesc}
163
164\subsection{asynchat - Auxiliary Classes and Functions}
165
166\begin{classdesc}{simple_producer}{data\optional{, buffer_size=512}}
167 A \class{simple_producer} takes a chunk of data and an optional buffer size.
168 Repeated calls to its \method{more()} method yield successive chunks of the
169 data no larger than \var{buffer_size}.
170\end{classdesc}
171
172\begin{methoddesc}{more}{}
173 Produces the next chunk of information from the producer, or returns the empty string.
174\end{methoddesc}
175
176\begin{classdesc}{fifo}{\optional{list=None}}
177 Each channel maintains a \class{fifo} holding data which has been pushed by the
178 application but not yet popped for writing to the channel.
179 A \class{fifo} is a list used to hold data and/or producers until they are required.
180 If the \var{list} argument is provided then it should contain producers or
181 data items to be written to the channel.
182\end{classdesc}
183
184\begin{methoddesc}{is_empty}{}
185 Returns \code{True} iff the fifo is empty.
186\end{methoddesc}
187
188\begin{methoddesc}{first}{}
189 Returns the least-recently \method{push()}ed item from the fifo.
190\end{methoddesc}
191
192\begin{methoddesc}{push}{data}
193 Adds the given data (which may be a string or a producer object) to the
194 producer fifo.
195\end{methoddesc}
196
197\begin{methoddesc}{pop}{}
198 If the fifo is not empty, returns \code{True, first()}, deleting the popped
199 item. Returns \code{False, None} for an empty fifo.
200\end{methoddesc}
201
202The \module{asynchat} module also defines one utility function, which may be
203of use in network and textual analysis operations.
204
205\begin{funcdesc}{find_prefix_at_end}{haystack, needle}
206 Returns \code{True} if string \var{haystack} ends with any non-empty
207 prefix of string \var{needle}.
208\end{funcdesc}
209
210\subsection{asynchat Example \label{asynchat-example}}
211
212The following partial example shows how HTTP requests can be read with
213\class{async_chat}. A web server might create an \class{http_request_handler} object for
214each incoming client connection. Notice that initially the
215channel terminator is set to match the blank line at the end of the HTTP
216headers, and a flag indicates that the headers are being read.
217
218Once the headers have been read, if the request is of type POST
219(indicating that further data are present in the input stream) then the
220\code{Content-Length:} header is used to set a numeric terminator to
221read the right amount of data from the channel.
222
223The \method{handle_request()} method is called once all relevant input
224has been marshalled, after setting the channel terminator to \code{None}
225to ensure that any extraneous data sent by the web client are ignored.
226
227\begin{verbatim}
228class http_request_handler(asynchat.async_chat):
229
230 def __init__(self, conn, addr, sessions, log):
231 asynchat.async_chat.__init__(self, conn=conn)
232 self.addr = addr
233 self.sessions = sessions
234 self.ibuffer = []
235 self.obuffer = ""
236 self.set_terminator("\r\n\r\n")
237 self.reading_headers = True
238 self.handling = False
239 self.cgi_data = None
240 self.log = log
241
242 def collect_incoming_data(self, data):
243 """Buffer the data"""
244 self.ibuffer.append(data)
245
246 def found_terminator(self):
247 if self.reading_headers:
248 self.reading_headers = False
Steve Holdenc8389c92002-08-04 15:27:25 +0000249 self.parse_headers("".join(self.ibuffer))
Steve Holdenb1af86a2002-07-03 18:36:39 +0000250 self.ibuffer = []
251 if self.op.upper() == "POST":
252 clen = self.headers.getheader("content-length")
253 self.set_terminator(int(clen))
254 else:
255 self.handling = True
256 self.set_terminator(None)
257 self.handle_request()
258 elif not self.handling:
259 self.set_terminator(None) # browsers sometimes over-send
260 self.cgi_data = parse(self.headers, "".join(self.ibuffer))
261 self.handling = True
262 self.ibuffer = []
263 self.handle_request()
264\end{verbatim}
265