~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/web/http_headers.py

  • Committer: Marc Tardif
  • Date: 2010-05-20 19:56:06 UTC
  • Revision ID: marc.tardif@canonical.com-20100520195606-xdrf0ztlxhvwmmzb
Added twisted-web.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.web.test.test_http_headers
 
2
# Copyright (c) 2008-2009 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
"""
 
6
An API for storing HTTP header names and values.
 
7
"""
 
8
 
 
9
 
 
10
from UserDict import DictMixin
 
11
 
 
12
 
 
13
def _dashCapitalize(name):
 
14
    """
 
15
    Return a string which is capitalized using '-' as a word separator.
 
16
 
 
17
    @param name: The name of the header to capitalize.
 
18
    @type name: str
 
19
 
 
20
    @return: The given header capitalized using '-' as a word separator.
 
21
    @rtype: str
 
22
    """
 
23
    return '-'.join([word.capitalize() for word in name.split('-')])
 
24
 
 
25
 
 
26
 
 
27
class _DictHeaders(DictMixin):
 
28
    """
 
29
    A C{dict}-like wrapper around L{Headers} to provide backwards compatibility
 
30
    for L{Request.received_headers} and L{Request.headers} which used to be
 
31
    plain C{dict} instances.
 
32
 
 
33
    @type _headers: L{Headers}
 
34
    @ivar _headers: The real header storage object.
 
35
    """
 
36
    def __init__(self, headers):
 
37
        self._headers = headers
 
38
 
 
39
 
 
40
    def __getitem__(self, key):
 
41
        """
 
42
        Return the last value for header of C{key}.
 
43
        """
 
44
        if self._headers.hasHeader(key):
 
45
            return self._headers.getRawHeaders(key)[-1]
 
46
        raise KeyError(key)
 
47
 
 
48
 
 
49
    def __setitem__(self, key, value):
 
50
        """
 
51
        Set the given header.
 
52
        """
 
53
        self._headers.setRawHeaders(key, [value])
 
54
 
 
55
 
 
56
    def __delitem__(self, key):
 
57
        """
 
58
        Delete the given header.
 
59
        """
 
60
        if self._headers.hasHeader(key):
 
61
            self._headers.removeHeader(key)
 
62
        else:
 
63
            raise KeyError(key)
 
64
 
 
65
 
 
66
    def keys(self):
 
67
        """
 
68
        Return a list of all header names.
 
69
        """
 
70
        return [k.lower() for k, v in self._headers.getAllRawHeaders()]
 
71
 
 
72
 
 
73
    def copy(self):
 
74
        """
 
75
        Return a C{dict} mapping each header name to the last corresponding
 
76
        header value.
 
77
        """
 
78
        return dict(self.items())
 
79
 
 
80
 
 
81
    # Python 2.3 DictMixin.setdefault is defined so as not to have a default
 
82
    # for the value parameter.  This is necessary to make this setdefault look
 
83
    # like dict.setdefault on Python 2.3. -exarkun
 
84
    def setdefault(self, name, value=None):
 
85
        """
 
86
        Retrieve the last value for the given header name.  If there are no
 
87
        values present for that header, set the value to C{value} and return
 
88
        that instead.  Note that C{None} is the default for C{value} for
 
89
        backwards compatibility, but header values may only be of type C{str}.
 
90
        """
 
91
        return DictMixin.setdefault(self, name, value)
 
92
 
 
93
 
 
94
    # The remaining methods are only for efficiency.  The same behavior
 
95
    # should remain even if they are removed.  For details, see
 
96
    # <http://docs.python.org/lib/module-UserDict.html>.
 
97
    # -exarkun
 
98
    def __contains__(self, name):
 
99
        """
 
100
        Return C{True} if the named header is present, C{False} otherwise.
 
101
        """
 
102
        return self._headers.getRawHeaders(name) is not None
 
103
 
 
104
 
 
105
    def __iter__(self):
 
106
        """
 
107
        Return an iterator of the lowercase name of each header present.
 
108
        """
 
109
        for k, v in self._headers.getAllRawHeaders():
 
110
            yield k.lower()
 
111
 
 
112
 
 
113
    def iteritems(self):
 
114
        """
 
115
        Return an iterable of two-tuples of each lower-case header name and the
 
116
        last value for that header.
 
117
        """
 
118
        for k, v in self._headers.getAllRawHeaders():
 
119
            yield k.lower(), v[-1]
 
120
 
 
121
 
 
122
 
 
123
class Headers(object):
 
124
    """
 
125
    This class stores the HTTP headers as both a parsed representation
 
126
    and the raw string representation. It converts between the two on
 
127
    demand.
 
128
 
 
129
    @cvar _caseMappings: A C{dict} that maps lowercase header names
 
130
        to their canonicalized representation.
 
131
 
 
132
    @ivar _rawHeaders: A C{dict} mapping header names as C{str} to C{lists} of
 
133
        header values as C{str}.
 
134
    """
 
135
    _caseMappings = {'www-authenticate': 'WWW-Authenticate'}
 
136
 
 
137
    def __init__(self, rawHeaders=None):
 
138
        self._rawHeaders = {}
 
139
        if rawHeaders is not None:
 
140
            for name, values in rawHeaders.iteritems():
 
141
                self.setRawHeaders(name, values)
 
142
 
 
143
 
 
144
    def __repr__(self):
 
145
        """
 
146
        Return a string fully describing the headers set on this object.
 
147
        """
 
148
        return '%s(%r)' % (self.__class__.__name__, self._rawHeaders,)
 
149
 
 
150
 
 
151
    def __cmp__(self, other):
 
152
        """
 
153
        Define L{Headers} instances as being equal to each other if they have
 
154
        the same raw headers.
 
155
        """
 
156
        if isinstance(other, Headers):
 
157
            return cmp(self._rawHeaders, other._rawHeaders)
 
158
        return NotImplemented
 
159
 
 
160
 
 
161
    def hasHeader(self, name):
 
162
        """
 
163
        Check for the existence of a given header.
 
164
 
 
165
        @type name: C{str}
 
166
        @param name: The name of the HTTP header to check for.
 
167
 
 
168
        @rtype: C{bool}
 
169
        @return: C{True} if the header exists, otherwise C{False}.
 
170
        """
 
171
        return name.lower() in self._rawHeaders
 
172
 
 
173
 
 
174
    def removeHeader(self, name):
 
175
        """
 
176
        Remove the named header from this header object.
 
177
 
 
178
        @type name: C{str}
 
179
        @param name: The name of the HTTP header to remove.
 
180
 
 
181
        @return: C{None}
 
182
        """
 
183
        self._rawHeaders.pop(name.lower(), None)
 
184
 
 
185
 
 
186
    def setRawHeaders(self, name, values):
 
187
        """
 
188
        Sets the raw representation of the given header.
 
189
 
 
190
        @type name: C{str}
 
191
        @param name: The name of the HTTP header to set the values for.
 
192
 
 
193
        @type values: C{list}
 
194
        @param values: A list of strings each one being a header value of
 
195
            the given name.
 
196
 
 
197
        @return: C{None}
 
198
        """
 
199
        self._rawHeaders[name.lower()] = values
 
200
 
 
201
 
 
202
    def addRawHeader(self, name, value):
 
203
        """
 
204
        Add a new raw value for the given header.
 
205
 
 
206
        @type name: C{str}
 
207
        @param name: The name of the header for which to set the value.
 
208
 
 
209
        @type value: C{str}
 
210
        @param value: The value to set for the named header.
 
211
        """
 
212
        values = self.getRawHeaders(name)
 
213
        if values is None:
 
214
            self.setRawHeaders(name, [value])
 
215
        else:
 
216
            values.append(value)
 
217
 
 
218
 
 
219
    def getRawHeaders(self, name, default=None):
 
220
        """
 
221
        Returns a list of headers matching the given name as the raw string
 
222
        given.
 
223
 
 
224
        @type name: C{str}
 
225
        @param name: The name of the HTTP header to get the values of.
 
226
 
 
227
        @param default: The value to return if no header with the given C{name}
 
228
            exists.
 
229
 
 
230
        @rtype: C{list}
 
231
        @return: A C{list} of values for the given header.
 
232
        """
 
233
        return self._rawHeaders.get(name.lower(), default)
 
234
 
 
235
 
 
236
    def getAllRawHeaders(self):
 
237
        """
 
238
        Return an iterator of key, value pairs of all headers contained in this
 
239
        object, as strings.  The keys are capitalized in canonical
 
240
        capitalization.
 
241
        """
 
242
        for k, v in self._rawHeaders.iteritems():
 
243
            yield self._canonicalNameCaps(k), v
 
244
 
 
245
 
 
246
    def _canonicalNameCaps(self, name):
 
247
        """
 
248
        Return the canonical name for the given header.
 
249
 
 
250
        @type name: C{str}
 
251
        @param name: The all-lowercase header name to capitalize in its
 
252
            canonical form.
 
253
 
 
254
        @rtype: C{str}
 
255
        @return: The canonical name of the header.
 
256
        """
 
257
        return self._caseMappings.get(name, _dashCapitalize(name))
 
258
 
 
259
 
 
260
__all__ = ['Headers']