~jk0/nova/xs-ipv6

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/web/iweb.py

  • 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
# -*- test-case-name: twisted.web.test -*-
 
2
# Copyright (c) 2008-2009 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
"""
 
6
Interface definitions for L{twisted.web}.
 
7
 
 
8
@var UNKNOWN_LENGTH: An opaque object which may be used as the value of
 
9
    L{IBodyProducer.length} to indicate that the length of the entity
 
10
    body is not known in advance.
 
11
"""
 
12
 
 
13
from zope.interface import Interface, Attribute
 
14
 
 
15
from twisted.internet.interfaces import IPushProducer
 
16
from twisted.cred.credentials import IUsernameDigestHash
 
17
 
 
18
 
 
19
class IRequest(Interface):
 
20
    """
 
21
    An HTTP request.
 
22
 
 
23
    @since: 9.0
 
24
    """
 
25
 
 
26
    method = Attribute("A C{str} giving the HTTP method that was used.")
 
27
    uri = Attribute(
 
28
        "A C{str} giving the full encoded URI which was requested (including "
 
29
        "query arguments).")
 
30
    path = Attribute(
 
31
        "A C{str} giving the encoded query path of the request URI.")
 
32
    args = Attribute(
 
33
        "A mapping of decoded query argument names as C{str} to "
 
34
        "corresponding query argument values as C{list}s of C{str}.  "
 
35
        "For example, for a URI with C{'foo=bar&foo=baz&quux=spam'} "
 
36
        "for its query part, C{args} will be C{{'foo': ['bar', 'baz'], "
 
37
        "'quux': ['spam']}}.")
 
38
 
 
39
    received_headers = Attribute(
 
40
        "Backwards-compatibility access to C{requestHeaders}.  Use "
 
41
        "C{requestHeaders} instead.  C{received_headers} behaves mostly "
 
42
        "like a C{dict} and does not provide access to all header values.")
 
43
 
 
44
    requestHeaders = Attribute(
 
45
        "A L{http_headers.Headers} instance giving all received HTTP request "
 
46
        "headers.")
 
47
 
 
48
    headers = Attribute(
 
49
        "Backwards-compatibility access to C{responseHeaders}.  Use"
 
50
        "C{responseHeaders} instead.  C{headers} behaves mostly like a "
 
51
        "C{dict} and does not provide access to all header values nor "
 
52
        "does it allow multiple values for one header to be set.")
 
53
 
 
54
    responseHeaders = Attribute(
 
55
        "A L{http_headers.Headers} instance holding all HTTP response "
 
56
        "headers to be sent.")
 
57
 
 
58
    def getHeader(key):
 
59
        """
 
60
        Get an HTTP request header.
 
61
 
 
62
        @type key: C{str}
 
63
        @param key: The name of the header to get the value of.
 
64
 
 
65
        @rtype: C{str} or C{NoneType}
 
66
        @return: The value of the specified header, or C{None} if that header
 
67
            was not present in the request.
 
68
        """
 
69
 
 
70
 
 
71
    def getCookie(key):
 
72
        """
 
73
        Get a cookie that was sent from the network.
 
74
        """
 
75
 
 
76
 
 
77
    def getAllHeaders():
 
78
        """
 
79
        Return dictionary mapping the names of all received headers to the last
 
80
        value received for each.
 
81
 
 
82
        Since this method does not return all header information,
 
83
        C{requestHeaders.getAllRawHeaders()} may be preferred.
 
84
        """
 
85
 
 
86
 
 
87
    def getRequestHostname():
 
88
        """
 
89
        Get the hostname that the user passed in to the request.
 
90
 
 
91
        This will either use the Host: header (if it is available) or the
 
92
        host we are listening on if the header is unavailable.
 
93
 
 
94
        @returns: the requested hostname
 
95
        @rtype: C{str}
 
96
        """
 
97
 
 
98
 
 
99
    def getHost():
 
100
        """
 
101
        Get my originally requesting transport's host.
 
102
 
 
103
        @return: An L{IAddress}.
 
104
        """
 
105
 
 
106
 
 
107
    def getClientIP():
 
108
        """
 
109
        Return the IP address of the client who submitted this request.
 
110
 
 
111
        @returns: the client IP address or C{None} if the request was submitted
 
112
            over a transport where IP addresses do not make sense.
 
113
        @rtype: C{str} or L{NoneType}
 
114
        """
 
115
 
 
116
 
 
117
    def getClient():
 
118
        """
 
119
        Return the hostname of the IP address of the client who submitted this
 
120
        request, if possible.
 
121
 
 
122
        This method is B{deprecated}.  See L{getClientIP} instead.
 
123
 
 
124
        @rtype: L{NoneType} or L{str}
 
125
        @return: The canonical hostname of the client, as determined by
 
126
            performing a name lookup on the IP address of the client.
 
127
        """
 
128
 
 
129
 
 
130
    def getUser():
 
131
        """
 
132
        Return the HTTP user sent with this request, if any.
 
133
 
 
134
        If no user was supplied, return the empty string.
 
135
 
 
136
        @returns: the HTTP user, if any
 
137
        @rtype: C{str}
 
138
        """
 
139
 
 
140
 
 
141
    def getPassword():
 
142
        """
 
143
        Return the HTTP password sent with this request, if any.
 
144
 
 
145
        If no password was supplied, return the empty string.
 
146
 
 
147
        @returns: the HTTP password, if any
 
148
        @rtype: C{str}
 
149
        """
 
150
 
 
151
 
 
152
    def isSecure():
 
153
        """
 
154
        Return True if this request is using a secure transport.
 
155
 
 
156
        Normally this method returns True if this request's HTTPChannel
 
157
        instance is using a transport that implements ISSLTransport.
 
158
 
 
159
        This will also return True if setHost() has been called
 
160
        with ssl=True.
 
161
 
 
162
        @returns: True if this request is secure
 
163
        @rtype: C{bool}
 
164
        """
 
165
 
 
166
 
 
167
    def getSession(sessionInterface=None):
 
168
        """
 
169
        Look up the session associated with this request or create a new one if
 
170
        there is not one.
 
171
 
 
172
        @return: The L{Session} instance identified by the session cookie in
 
173
            the request, or the C{sessionInterface} component of that session
 
174
            if C{sessionInterface} is specified.
 
175
        """
 
176
 
 
177
 
 
178
    def URLPath():
 
179
        """
 
180
        @return: A L{URLPath} instance which identifies the URL for which this
 
181
            request is.
 
182
        """
 
183
 
 
184
 
 
185
    def prePathURL():
 
186
        """
 
187
        @return: At any time during resource traversal, a L{str} giving an
 
188
            absolute URL to the most nested resource which has yet been
 
189
            reached.
 
190
        """
 
191
 
 
192
 
 
193
    def rememberRootURL():
 
194
        """
 
195
        Remember the currently-processed part of the URL for later
 
196
        recalling.
 
197
        """
 
198
 
 
199
 
 
200
    def getRootURL():
 
201
        """
 
202
        Get a previously-remembered URL.
 
203
        """
 
204
 
 
205
 
 
206
    # Methods for outgoing response
 
207
    def finish():
 
208
        """
 
209
        Indicate that the response to this request is complete.
 
210
        """
 
211
 
 
212
 
 
213
    def write(data):
 
214
        """
 
215
        Write some data to the body of the response to this request.  Response
 
216
        headers are written the first time this method is called, after which
 
217
        new response headers may not be added.
 
218
        """
 
219
 
 
220
 
 
221
    def addCookie(k, v, expires=None, domain=None, path=None, max_age=None, comment=None, secure=None):
 
222
        """
 
223
        Set an outgoing HTTP cookie.
 
224
 
 
225
        In general, you should consider using sessions instead of cookies, see
 
226
        L{twisted.web.server.Request.getSession} and the
 
227
        L{twisted.web.server.Session} class for details.
 
228
        """
 
229
 
 
230
 
 
231
    def setResponseCode(code, message=None):
 
232
        """
 
233
        Set the HTTP response code.
 
234
        """
 
235
 
 
236
 
 
237
    def setHeader(k, v):
 
238
        """
 
239
        Set an HTTP response header.  Overrides any previously set values for
 
240
        this header.
 
241
 
 
242
        @type name: C{str}
 
243
        @param name: The name of the header for which to set the value.
 
244
 
 
245
        @type value: C{str}
 
246
        @param value: The value to set for the named header.
 
247
        """
 
248
 
 
249
 
 
250
    def redirect(url):
 
251
        """
 
252
        Utility function that does a redirect.
 
253
 
 
254
        The request should have finish() called after this.
 
255
        """
 
256
 
 
257
 
 
258
    def setLastModified(when):
 
259
        """
 
260
        Set the C{Last-Modified} time for the response to this request.
 
261
 
 
262
        If I am called more than once, I ignore attempts to set Last-Modified
 
263
        earlier, only replacing the Last-Modified time if it is to a later
 
264
        value.
 
265
 
 
266
        If I am a conditional request, I may modify my response code to
 
267
        L{NOT_MODIFIED} if appropriate for the time given.
 
268
 
 
269
        @param when: The last time the resource being returned was modified, in
 
270
            seconds since the epoch.
 
271
        @type when: C{int}, C{long} or C{float}
 
272
 
 
273
        @return: If I am a C{If-Modified-Since} conditional request and the
 
274
            time given is not newer than the condition, I return
 
275
            L{http.CACHED<CACHED>} to indicate that you should write no body.
 
276
            Otherwise, I return a false value.
 
277
        """
 
278
 
 
279
 
 
280
    def setETag(etag):
 
281
        """
 
282
        Set an C{entity tag} for the outgoing response.
 
283
 
 
284
        That's "entity tag" as in the HTTP/1.1 C{ETag} header, "used for
 
285
        comparing two or more entities from the same requested resource."
 
286
 
 
287
        If I am a conditional request, I may modify my response code to
 
288
        L{NOT_MODIFIED} or L{PRECONDITION_FAILED}, if appropriate for the tag
 
289
        given.
 
290
 
 
291
        @param etag: The entity tag for the resource being returned.
 
292
        @type etag: C{str}
 
293
        @return: If I am a C{If-None-Match} conditional request and the tag
 
294
            matches one in the request, I return L{http.CACHED<CACHED>} to
 
295
            indicate that you should write no body.  Otherwise, I return a
 
296
            false value.
 
297
        """
 
298
 
 
299
 
 
300
    def setHost(host, port, ssl=0):
 
301
        """
 
302
        Change the host and port the request thinks it's using.
 
303
 
 
304
        This method is useful for working with reverse HTTP proxies (e.g.  both
 
305
        Squid and Apache's mod_proxy can do this), when the address the HTTP
 
306
        client is using is different than the one we're listening on.
 
307
 
 
308
        For example, Apache may be listening on https://www.example.com, and
 
309
        then forwarding requests to http://localhost:8080, but we don't want
 
310
        HTML produced by Twisted to say 'http://localhost:8080', they should
 
311
        say 'https://www.example.com', so we do::
 
312
 
 
313
           request.setHost('www.example.com', 443, ssl=1)
 
314
        """
 
315
 
 
316
 
 
317
 
 
318
class ICredentialFactory(Interface):
 
319
    """
 
320
    A credential factory defines a way to generate a particular kind of
 
321
    authentication challenge and a way to interpret the responses to these
 
322
    challenges.  It creates L{ICredentials} providers from responses.  These
 
323
    objects will be used with L{twisted.cred} to authenticate an authorize
 
324
    requests.
 
325
    """
 
326
    scheme = Attribute(
 
327
        "A C{str} giving the name of the authentication scheme with which "
 
328
        "this factory is associated.  For example, C{'basic'} or C{'digest'}.")
 
329
 
 
330
 
 
331
    def getChallenge(request):
 
332
        """
 
333
        Generate a new challenge to be sent to a client.
 
334
 
 
335
        @type peer: L{twisted.web.http.Request}
 
336
        @param peer: The request the response to which this challenge will be
 
337
            included.
 
338
 
 
339
        @rtype: C{dict}
 
340
        @return: A mapping from C{str} challenge fields to associated C{str}
 
341
            values.
 
342
        """
 
343
 
 
344
 
 
345
    def decode(response, request):
 
346
        """
 
347
        Create a credentials object from the given response.
 
348
 
 
349
        @type response: C{str}
 
350
        @param response: scheme specific response string
 
351
 
 
352
        @type request: L{twisted.web.http.Request}
 
353
        @param request: The request being processed (from which the response
 
354
            was taken).
 
355
 
 
356
        @raise twisted.cred.error.LoginFailed: If the response is invalid.
 
357
 
 
358
        @rtype: L{twisted.cred.credentials.ICredentials} provider
 
359
        @return: The credentials represented by the given response.
 
360
        """
 
361
 
 
362
 
 
363
 
 
364
class IBodyProducer(IPushProducer):
 
365
    """
 
366
    Objects which provide L{IBodyProducer} write bytes to an object which
 
367
    provides L{IConsumer} by calling its C{write} method repeatedly.
 
368
 
 
369
    L{IBodyProducer} providers may start producing as soon as they have
 
370
    an L{IConsumer} provider.  That is, they should not wait for a
 
371
    C{resumeProducing} call to begin writing data.
 
372
 
 
373
    L{IConsumer.unregisterProducer} must not be called.  Instead, the
 
374
    L{Deferred} returned from C{startProducing} must be fired when all bytes
 
375
    have been written.
 
376
 
 
377
    L{IConsumer.write} may synchronously invoke any of C{pauseProducing},
 
378
    C{resumeProducing}, or C{stopProducing}.  These methods must be implemented
 
379
    with this in mind.
 
380
 
 
381
    @since: 9.0
 
382
    """
 
383
 
 
384
    # Despite the restrictions above and the additional requirements of
 
385
    # stopProducing documented below, this interface still needs to be an
 
386
    # IPushProducer subclass.  Providers of it will be passed to IConsumer
 
387
    # providers which only know about IPushProducer and IPullProducer, not
 
388
    # about this interface.  This interface needs to remain close enough to one
 
389
    # of those interfaces for consumers to work with it.
 
390
 
 
391
    length = Attribute(
 
392
        """
 
393
        C{length} is a C{int} indicating how many bytes in total this
 
394
        L{IBodyProducer} will write to the consumer or L{UNKNOWN_LENGTH}
 
395
        if this is not known in advance.
 
396
        """)
 
397
 
 
398
    def startProducing(consumer):
 
399
        """
 
400
        Start producing to the given L{IConsumer} provider.
 
401
 
 
402
        @return: A L{Deferred} which fires with C{None} when all bytes have
 
403
            been produced or with a L{Failure} if there is any problem before
 
404
            all bytes have been produced.
 
405
        """
 
406
 
 
407
 
 
408
    def stopProducing():
 
409
        """
 
410
        In addition to the standard behavior of L{IProducer.stopProducing}
 
411
        (stop producing data), make sure the L{Deferred} returned by
 
412
        C{startProducing} is never fired.
 
413
        """
 
414
 
 
415
UNKNOWN_LENGTH = u"twisted.web.iweb.UNKNOWN_LENGTH"
 
416
 
 
417
__all__ = [
 
418
    "IUsernameDigestHash", "ICredentialFactory", "IRequest",
 
419
    "IBodyProducer",
 
420
 
 
421
    "UNKNOWN_LENGTH"]