~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/web/howto/client.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: 
 
4
      Using the Twisted Web Client
 
5
    </title>
 
6
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
7
  </head>
 
8
 
 
9
  <body bgcolor="white">
 
10
    <h1 class="title">
 
11
      Using the Twisted Web Client
 
12
    </h1>
 
13
    <div class="toc"><ol><li><a href="#auto0">
 
14
      Overview
 
15
    </a></li><ul><li><a href="#auto1">
 
16
      Prerequisites
 
17
    </a></li></ul><li><a href="#auto2">
 
18
      The Agent
 
19
    </a></li><ul><li><a href="#auto3">Issuing Requests</a></li><li><a href="#auto4">
 
20
      Receiving Responses
 
21
    </a></li></ul><li><a href="#auto5">
 
22
      Conclusion
 
23
    </a></li></ol></div>
 
24
    <div class="content">
 
25
    <span/>
 
26
 
 
27
    <h2>
 
28
      Overview
 
29
    <a name="auto0"/></h2>
 
30
 
 
31
    <p>
 
32
      This document describes how to use the HTTP client included in Twisted
 
33
      Web.  After reading it, you should be able to make HTTP requests using
 
34
      Twisted Web.  You will be able to specify the request method, headers,
 
35
      and body and you will be able to retrieve the response code, headers, and
 
36
      body.
 
37
    </p>
 
38
 
 
39
    <h3>
 
40
      Prerequisites
 
41
    <a name="auto1"/></h3>
 
42
 
 
43
    <p>
 
44
      This document assumes that you are familiar with <a href="../../core/howto/defer.html" shape="rect">Deferreds and Failures</a>, and <a href="../../core/howto/producers.html" shape="rect">producers and consumers</a>. 
 
45
      It also assumes you are familiar with the basic concepts of HTTP, such
 
46
      as requests and responses, methods, headers, and message bodies.
 
47
    </p>
 
48
 
 
49
    <h2>
 
50
      The Agent
 
51
    <a name="auto2"/></h2>
 
52
 
 
53
    <h3>Issuing Requests<a name="auto3"/></h3>
 
54
 
 
55
    <p>
 
56
      The <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.client.Agent.html" title="twisted.web.client.Agent">twisted.web.client.Agent</a></code> class is the entry
 
57
      point into the client API.  Requests are issued using the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.client.Agent.request.html" title="twisted.web.client.Agent.request">request</a></code> method, which
 
58
      takes as parameters a request method, a request URI, the request headers,
 
59
      and an object which can produce the request body (if there is to be one).
 
60
      The agent is responsible for connection setup.  Because of this, it
 
61
      requires a reactor as an argument to its initializer.  An example of
 
62
      creating an agent and issuing a request using it might look like this:
 
63
    </p>
 
64
 
 
65
    <div class="py-listing"><pre><p class="py-linenumber"> 1
 
66
 2
 
67
 3
 
68
 4
 
69
 5
 
70
 6
 
71
 7
 
72
 8
 
73
 9
 
74
10
 
75
11
 
76
12
 
77
13
 
78
14
 
79
15
 
80
16
 
81
17
 
82
18
 
83
19
 
84
20
 
85
21
 
86
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
87
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">client</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Agent</span>
 
88
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">http_headers</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Headers</span>
 
89
 
 
90
<span class="py-src-variable">agent</span> = <span class="py-src-variable">Agent</span>(<span class="py-src-variable">reactor</span>)
 
91
 
 
92
<span class="py-src-variable">d</span> = <span class="py-src-variable">agent</span>.<span class="py-src-variable">request</span>(
 
93
    <span class="py-src-string">'GET'</span>,
 
94
    <span class="py-src-string">'http://example.com/'</span>,
 
95
    <span class="py-src-variable">Headers</span>({<span class="py-src-string">'User-Agent'</span>: [<span class="py-src-string">'Twisted Web Client Example'</span>]}),
 
96
    <span class="py-src-variable">None</span>)
 
97
 
 
98
<span class="py-src-keyword">def</span> <span class="py-src-identifier">cbResponse</span>(<span class="py-src-parameter">ignored</span>):
 
99
    <span class="py-src-keyword">print</span> <span class="py-src-string">'Response received'</span>
 
100
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cbResponse</span>)
 
101
 
 
102
<span class="py-src-keyword">def</span> <span class="py-src-identifier">cbShutdown</span>(<span class="py-src-parameter">ignored</span>):
 
103
    <span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>()
 
104
<span class="py-src-variable">d</span>.<span class="py-src-variable">addBoth</span>(<span class="py-src-variable">cbShutdown</span>)
 
105
 
 
106
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
107
</pre><div class="caption">
 
108
      Issue a request with an Agent
 
109
     - <a href="listings/client/request.py"><span class="filename">listings/client/request.py</span></a></div></div>
 
110
 
 
111
    <p>
 
112
      As may be obvious, this issues a new <em>GET</em> request for <em>/</em>
 
113
      to the web server on <code>example.com</code>.  <code>Agent</code> is
 
114
      responsible for resolving the hostname into an IP address and connecting
 
115
      to it on port 80.  It is also responsible for cleaning up the connection
 
116
      afterwards.  This code sends a request which includes one custom header,
 
117
      <em>User-Agent</em>.  The last argument passed to <code>Agent.request</code> is
 
118
      <code>None</code>, though, so the request has no body.
 
119
    </p>
 
120
 
 
121
    <p>
 
122
      Sending a request which does include a body requires passing an object
 
123
      providing <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.iweb.IBodyProducer.html" title="twisted.web.iweb.IBodyProducer">twisted.web.iweb.IBodyProducer</a></code>
 
124
      to <code>Agent.request</code>.  This interface extends the more general
 
125
      <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IPushProducer.html" title="twisted.internet.interfaces.IPushProducer">IPushProducer</a></code>
 
126
      by adding a new <code>length</code> attribute and adding several
 
127
      constraints to the way the producer and consumer interact.
 
128
    </p>
 
129
 
 
130
    <ul>
 
131
      <li>
 
132
        The length attribute must be a non-negative integer or the constant
 
133
        <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.iweb.UNKNOWN_LENGTH.html" title="twisted.web.iweb.UNKNOWN_LENGTH">twisted.web.iweb.UNKNOWN_LENGTH</a></code>.  If the
 
134
        length is known, it will be used to specify the value for the
 
135
        <em>Content-Length</em> header in the request.  If the length is
 
136
        unknown the attribute should be set to <code>UNKNOWN_LENGTH</code>.
 
137
        Since more servers support <em>Content-Length</em>, if a length can be
 
138
        provided it should be.
 
139
      </li>
 
140
 
 
141
      <li>
 
142
        An additional method is required on <code>IEntityBodyProvider</code>
 
143
        implementations: <code>startProducing</code>.  This method is used to
 
144
        associate a consumer with the producer.  It should return a
 
145
        <code>Deferred</code> which fires when all data has been produced.
 
146
      </li>
 
147
 
 
148
      <li>
 
149
        <code>IEntityBodyProvider</code> implementations should never call the
 
150
        consumer's <code>unregisterProducer</code> method.  Instead, when it
 
151
        has produced all of the data it is going to produce, it should only
 
152
        fire the <code>Deferred</code> returned by <code>startProducing</code>.
 
153
      </li>
 
154
    </ul>
 
155
 
 
156
    <p>
 
157
      For additional details about the requirements of <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.iweb.IBodyProducer.html" title="twisted.web.iweb.IBodyProducer">IBodyProducer</a></code> implementations, see
 
158
      the API documentation.
 
159
    </p>
 
160
 
 
161
    <p>
 
162
      Here's a simple <code>IEntityBodyProvider</code> implementation which
 
163
      writes an in-memory string to the consumer:
 
164
    </p>
 
165
 
 
166
    <div class="py-listing"><pre><p class="py-linenumber"> 1
 
167
 2
 
168
 3
 
169
 4
 
170
 5
 
171
 6
 
172
 7
 
173
 8
 
174
 9
 
175
10
 
176
11
 
177
12
 
178
13
 
179
14
 
180
15
 
181
16
 
182
17
 
183
18
 
184
19
 
185
20
 
186
21
 
187
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">implements</span>
 
188
 
 
189
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">defer</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">succeed</span>
 
190
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">iweb</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IBodyProducer</span>
 
191
 
 
192
<span class="py-src-keyword">class</span> <span class="py-src-identifier">StringProducer</span>(<span class="py-src-parameter">object</span>):
 
193
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IBodyProducer</span>)
 
194
 
 
195
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">body</span>):
 
196
        <span class="py-src-variable">self</span>.<span class="py-src-variable">body</span> = <span class="py-src-variable">body</span>
 
197
        <span class="py-src-variable">self</span>.<span class="py-src-variable">length</span> = <span class="py-src-variable">len</span>(<span class="py-src-variable">body</span>)
 
198
 
 
199
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">startProducing</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">consumer</span>):
 
200
        <span class="py-src-variable">consumer</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">body</span>)
 
201
        <span class="py-src-keyword">return</span> <span class="py-src-variable">succeed</span>(<span class="py-src-variable">None</span>)
 
202
 
 
203
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">pauseProducing</span>(<span class="py-src-parameter">self</span>):
 
204
        <span class="py-src-keyword">pass</span>
 
205
 
 
206
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">stopProducing</span>(<span class="py-src-parameter">self</span>):
 
207
        <span class="py-src-keyword">pass</span>
 
208
</pre><div class="caption">
 
209
      A string-based body producer.
 
210
     - <a href="listings/client/stringprod.py"><span class="filename">listings/client/stringprod.py</span></a></div></div>
 
211
 
 
212
    <p>
 
213
      This producer can be used to issue a request with a body:
 
214
    </p>
 
215
 
 
216
    <div class="py-listing"><pre><p class="py-linenumber"> 1
 
217
 2
 
218
 3
 
219
 4
 
220
 5
 
221
 6
 
222
 7
 
223
 8
 
224
 9
 
225
10
 
226
11
 
227
12
 
228
13
 
229
14
 
230
15
 
231
16
 
232
17
 
233
18
 
234
19
 
235
20
 
236
21
 
237
22
 
238
23
 
239
24
 
240
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
241
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">client</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Agent</span>
 
242
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">http_headers</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Headers</span>
 
243
 
 
244
<span class="py-src-keyword">from</span> <span class="py-src-variable">stringprod</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">StringProducer</span>
 
245
 
 
246
<span class="py-src-variable">agent</span> = <span class="py-src-variable">Agent</span>(<span class="py-src-variable">reactor</span>)
 
247
<span class="py-src-variable">body</span> = <span class="py-src-variable">StringProducer</span>(<span class="py-src-string">&quot;hello, world&quot;</span>)
 
248
<span class="py-src-variable">d</span> = <span class="py-src-variable">agent</span>.<span class="py-src-variable">request</span>(
 
249
    <span class="py-src-string">'GET'</span>,
 
250
    <span class="py-src-string">'http://example.com/'</span>,
 
251
    <span class="py-src-variable">Headers</span>({<span class="py-src-string">'User-Agent'</span>: [<span class="py-src-string">'Twisted Web Client Example'</span>],
 
252
             <span class="py-src-string">'Content-Type'</span>: [<span class="py-src-string">'text/x-greeting'</span>]}),
 
253
    <span class="py-src-variable">body</span>)
 
254
 
 
255
<span class="py-src-keyword">def</span> <span class="py-src-identifier">cbResponse</span>(<span class="py-src-parameter">ignored</span>):
 
256
    <span class="py-src-keyword">print</span> <span class="py-src-string">'Response received'</span>
 
257
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cbResponse</span>)
 
258
 
 
259
<span class="py-src-keyword">def</span> <span class="py-src-identifier">cbShutdown</span>(<span class="py-src-parameter">ignored</span>):
 
260
    <span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>()
 
261
<span class="py-src-variable">d</span>.<span class="py-src-variable">addBoth</span>(<span class="py-src-variable">cbShutdown</span>)
 
262
 
 
263
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
264
</pre><div class="caption">
 
265
      Issue a request with a body.
 
266
     - <a href="listings/client/sendbody.py"><span class="filename">listings/client/sendbody.py</span></a></div></div>
 
267
 
 
268
    <h3>
 
269
      Receiving Responses
 
270
    <a name="auto4"/></h3>
 
271
 
 
272
    <p>
 
273
      So far, the examples have demonstrated how to issue a request.  However,
 
274
      they have ignored the response, except for showing that it is a
 
275
      <code>Deferred</code> which seems to fire when the response has been
 
276
      received.  Next we'll cover what that response is and how to interpret
 
277
      it.
 
278
    </p>
 
279
 
 
280
    <p>
 
281
      <code>Agent.request</code>, as with most <code>Deferred</code>-returning
 
282
      APIs, can return a <code>Deferred</code> which fires with a
 
283
      <code>Failure</code>.  If the request fails somehow, this will be
 
284
      reflected with a failure.  This may be due to a problem looking up the
 
285
      host IP address, or it may be because the HTTP server is not accepting
 
286
      connections, or it may be because of a problem parsing the response, or
 
287
      any other problem which arises which prevents the response from being
 
288
      received.  It does <em>not</em> include responses with an error status.
 
289
    </p>
 
290
 
 
291
    <p>
 
292
      If the request succeeds, though, the <code>Deferred</code> will fire with
 
293
      a <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.client.Response.html" title="twisted.web.client.Response">Response</a></code>.  This
 
294
      happens as soon as all the response headers have been received.  It
 
295
      happens before any of the response body, if there is one, is processed.
 
296
      The <code>Response</code> object has several attributes giving the
 
297
      response information: its code, version, phrase, and headers, as well as
 
298
      the length of the body to expect.  The <code>Response</code> object also
 
299
      has a method which makes the response body available: <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web._newclient.Response.deliverBody.deliverBody.html" title="twisted.web._newclient.Response.deliverBody.deliverBody">deliverBody</a></code>.
 
300
      Using the attributes of the response object and this method, here's an
 
301
      example which displays part of the response to a request:
 
302
    </p>
 
303
 
 
304
    <div class="py-listing"><pre><p class="py-linenumber"> 1
 
305
 2
 
306
 3
 
307
 4
 
308
 5
 
309
 6
 
310
 7
 
311
 8
 
312
 9
 
313
10
 
314
11
 
315
12
 
316
13
 
317
14
 
318
15
 
319
16
 
320
17
 
321
18
 
322
19
 
323
20
 
324
21
 
325
22
 
326
23
 
327
24
 
328
25
 
329
26
 
330
27
 
331
28
 
332
29
 
333
30
 
334
31
 
335
32
 
336
33
 
337
34
 
338
35
 
339
36
 
340
37
 
341
38
 
342
39
 
343
40
 
344
41
 
345
42
 
346
43
 
347
44
 
348
45
 
349
46
 
350
47
 
351
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">pprint</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">pformat</span>
 
352
 
 
353
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
354
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">defer</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Deferred</span>
 
355
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>
 
356
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">client</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Agent</span>
 
357
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">http_headers</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Headers</span>
 
358
 
 
359
<span class="py-src-keyword">class</span> <span class="py-src-identifier">BeginningPrinter</span>(<span class="py-src-parameter">Protocol</span>):
 
360
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">finished</span>):
 
361
        <span class="py-src-variable">self</span>.<span class="py-src-variable">finished</span> = <span class="py-src-variable">finished</span>
 
362
        <span class="py-src-variable">self</span>.<span class="py-src-variable">remaining</span> = <span class="py-src-number">1024</span> * <span class="py-src-number">10</span>
 
363
 
 
364
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">dataReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">bytes</span>):
 
365
        <span class="py-src-keyword">if</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">remaining</span>:
 
366
            <span class="py-src-variable">display</span> = <span class="py-src-variable">bytes</span>[:<span class="py-src-variable">self</span>.<span class="py-src-variable">remaining</span>]
 
367
            <span class="py-src-keyword">print</span> <span class="py-src-string">'Some data received:'</span>
 
368
            <span class="py-src-keyword">print</span> <span class="py-src-variable">display</span>
 
369
            <span class="py-src-variable">self</span>.<span class="py-src-variable">remaining</span> -= <span class="py-src-variable">len</span>(<span class="py-src-variable">display</span>)
 
370
 
 
371
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionLost</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">reason</span>):
 
372
        <span class="py-src-keyword">print</span> <span class="py-src-string">'Finished receiving body:'</span>, <span class="py-src-variable">reason</span>.<span class="py-src-variable">getErrorMessage</span>()
 
373
        <span class="py-src-variable">self</span>.<span class="py-src-variable">finished</span>.<span class="py-src-variable">callback</span>(<span class="py-src-variable">None</span>)
 
374
 
 
375
<span class="py-src-variable">agent</span> = <span class="py-src-variable">Agent</span>(<span class="py-src-variable">reactor</span>)
 
376
<span class="py-src-variable">d</span> = <span class="py-src-variable">agent</span>.<span class="py-src-variable">request</span>(
 
377
    <span class="py-src-string">'GET'</span>,
 
378
    <span class="py-src-string">'http://example.com/'</span>,
 
379
    <span class="py-src-variable">Headers</span>({<span class="py-src-string">'User-Agent'</span>: [<span class="py-src-string">'Twisted Web Client Example'</span>]}),
 
380
    <span class="py-src-variable">None</span>)
 
381
 
 
382
<span class="py-src-keyword">def</span> <span class="py-src-identifier">cbRequest</span>(<span class="py-src-parameter">response</span>):
 
383
    <span class="py-src-keyword">print</span> <span class="py-src-string">'Response version:'</span>, <span class="py-src-variable">response</span>.<span class="py-src-variable">version</span>
 
384
    <span class="py-src-keyword">print</span> <span class="py-src-string">'Response code:'</span>, <span class="py-src-variable">response</span>.<span class="py-src-variable">code</span>
 
385
    <span class="py-src-keyword">print</span> <span class="py-src-string">'Response phrase:'</span>, <span class="py-src-variable">response</span>.<span class="py-src-variable">phrase</span>
 
386
    <span class="py-src-keyword">print</span> <span class="py-src-string">'Response headers:'</span>
 
387
    <span class="py-src-keyword">print</span> <span class="py-src-variable">pformat</span>(<span class="py-src-variable">list</span>(<span class="py-src-variable">response</span>.<span class="py-src-variable">headers</span>.<span class="py-src-variable">getAllRawHeaders</span>()))
 
388
    <span class="py-src-variable">finished</span> = <span class="py-src-variable">Deferred</span>()
 
389
    <span class="py-src-variable">response</span>.<span class="py-src-variable">deliverBody</span>(<span class="py-src-variable">BeginningPrinter</span>(<span class="py-src-variable">finished</span>))
 
390
    <span class="py-src-keyword">return</span> <span class="py-src-variable">finished</span>
 
391
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cbRequest</span>)
 
392
 
 
393
<span class="py-src-keyword">def</span> <span class="py-src-identifier">cbShutdown</span>(<span class="py-src-parameter">ignored</span>):
 
394
    <span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>()
 
395
<span class="py-src-variable">d</span>.<span class="py-src-variable">addBoth</span>(<span class="py-src-variable">cbShutdown</span>)
 
396
 
 
397
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
398
</pre><div class="caption">
 
399
      Inspect the response.
 
400
     - <a href="listings/client/response.py"><span class="filename">listings/client/response.py</span></a></div></div>
 
401
 
 
402
    <p>
 
403
      The <code>BeginningPrinter</code> protocol in this example is passed to
 
404
      <code>Response.deliverBody</code> and the response body is then delivered
 
405
      to its <code>dataReceived</code> method as it arrives.  When the body has
 
406
      been completely delivered, the protocol's <code>connectionLost</code>
 
407
      method is called.  It is important to inspect the <code>Failure</code>
 
408
      passed to <code>connectionLost</code>.  If the response body has been
 
409
      completely received, the failure will wrap a <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.client.ResponseDone.html" title="twisted.web.client.ResponseDone">twisted.web.client.ResponseDone</a></code> exception.  This
 
410
      indicates that it is <em>known</em> that all data has been received.  It
 
411
      is also possible for the failure to wrap a <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.http.PotentialDataLoss.html" title="twisted.web.http.PotentialDataLoss">twisted.web.http.PotentialDataLoss</a></code> exception: this
 
412
      indicates that the server framed the response such that there is no way
 
413
      to know when the entire response body has been received.  Only
 
414
      HTTP/1.0 servers should behave this way.  Finally, it is possible for
 
415
      the exception to be of another type, indicating guaranteed data loss for
 
416
      some reason (a lost connection, a memory error, etc).
 
417
    </p>
 
418
 
 
419
    <p>
 
420
      Just as protocols associated with a TCP connection are given a transport,
 
421
      so will be a protocol passed to <code>deliverBody</code>.  Since it makes
 
422
      no sense to write more data to the connection at this stage of the
 
423
      request, though, the transport <em>only</em> provides <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IPushProducer.html" title="twisted.internet.interfaces.IPushProducer">IPushProducer</a></code>.  This allows the
 
424
      protocol to control the flow of the response data: a call to the
 
425
      transport's <code>pauseProducing</code> method will pause delivery; a
 
426
      later call to <code>resumeProducing</code> will resume it.  If it is
 
427
      decided that the rest of the response body is not desired,
 
428
      <code>stopProducing</code> can be used to stop delivery permanently;
 
429
      after this, the protocol's <code>connectionLost</code> method will be
 
430
      called.
 
431
    </p>
 
432
 
 
433
    <p>
 
434
      An important thing to keep in mind is that the body will only be read
 
435
      from the connection after <code>Response.deliverBody</code> is called.
 
436
      This also means that the connection will remain open until this is done
 
437
      (and the body read).  So, in general, any response with a body
 
438
      <em>must</em> have that body read using <code>deliverBody</code>.  If the
 
439
      application is not interested in the body, it should issue a
 
440
      <em>HEAD</em> request or use a protocol which immediately calls
 
441
      <code>stopProducing</code> on its transport.
 
442
    </p>
 
443
 
 
444
    <h2>
 
445
      Conclusion
 
446
    <a name="auto5"/></h2>
 
447
 
 
448
    <p>
 
449
      You should now understand the basics of the Twisted Web HTTP client.  In
 
450
      particular, you should understand:
 
451
    </p>
 
452
 
 
453
    <ul>
 
454
      <li>
 
455
        How to issue requests with arbitrary methods, headers, and bodies.
 
456
      </li>
 
457
      <li>
 
458
        How to access the response version, code, phrase, headers, and body.
 
459
      </li>
 
460
      <li>
 
461
        How to control the streaming of the response body.
 
462
      </li>
 
463
    </ul>
 
464
  </div>
 
465
 
 
466
    <p><a href="index.html">Index</a></p>
 
467
    <span class="version">Version: 10.0.0</span>
 
468
  </body>
 
469
</html>
 
 
b'\\ No newline at end of file'