1
# -*- test-case-name: twisted.web.test.test_http_headers
2
# Copyright (c) 2008-2009 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
An API for storing HTTP header names and values.
10
from UserDict import DictMixin
13
def _dashCapitalize(name):
15
Return a string which is capitalized using '-' as a word separator.
17
@param name: The name of the header to capitalize.
20
@return: The given header capitalized using '-' as a word separator.
23
return '-'.join([word.capitalize() for word in name.split('-')])
27
class _DictHeaders(DictMixin):
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.
33
@type _headers: L{Headers}
34
@ivar _headers: The real header storage object.
36
def __init__(self, headers):
37
self._headers = headers
40
def __getitem__(self, key):
42
Return the last value for header of C{key}.
44
if self._headers.hasHeader(key):
45
return self._headers.getRawHeaders(key)[-1]
49
def __setitem__(self, key, value):
53
self._headers.setRawHeaders(key, [value])
56
def __delitem__(self, key):
58
Delete the given header.
60
if self._headers.hasHeader(key):
61
self._headers.removeHeader(key)
68
Return a list of all header names.
70
return [k.lower() for k, v in self._headers.getAllRawHeaders()]
75
Return a C{dict} mapping each header name to the last corresponding
78
return dict(self.items())
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):
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}.
91
return DictMixin.setdefault(self, name, value)
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>.
98
def __contains__(self, name):
100
Return C{True} if the named header is present, C{False} otherwise.
102
return self._headers.getRawHeaders(name) is not None
107
Return an iterator of the lowercase name of each header present.
109
for k, v in self._headers.getAllRawHeaders():
115
Return an iterable of two-tuples of each lower-case header name and the
116
last value for that header.
118
for k, v in self._headers.getAllRawHeaders():
119
yield k.lower(), v[-1]
123
class Headers(object):
125
This class stores the HTTP headers as both a parsed representation
126
and the raw string representation. It converts between the two on
129
@cvar _caseMappings: A C{dict} that maps lowercase header names
130
to their canonicalized representation.
132
@ivar _rawHeaders: A C{dict} mapping header names as C{str} to C{lists} of
133
header values as C{str}.
135
_caseMappings = {'www-authenticate': 'WWW-Authenticate'}
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)
146
Return a string fully describing the headers set on this object.
148
return '%s(%r)' % (self.__class__.__name__, self._rawHeaders,)
151
def __cmp__(self, other):
153
Define L{Headers} instances as being equal to each other if they have
154
the same raw headers.
156
if isinstance(other, Headers):
157
return cmp(self._rawHeaders, other._rawHeaders)
158
return NotImplemented
161
def hasHeader(self, name):
163
Check for the existence of a given header.
166
@param name: The name of the HTTP header to check for.
169
@return: C{True} if the header exists, otherwise C{False}.
171
return name.lower() in self._rawHeaders
174
def removeHeader(self, name):
176
Remove the named header from this header object.
179
@param name: The name of the HTTP header to remove.
183
self._rawHeaders.pop(name.lower(), None)
186
def setRawHeaders(self, name, values):
188
Sets the raw representation of the given header.
191
@param name: The name of the HTTP header to set the values for.
193
@type values: C{list}
194
@param values: A list of strings each one being a header value of
199
self._rawHeaders[name.lower()] = values
202
def addRawHeader(self, name, value):
204
Add a new raw value for the given header.
207
@param name: The name of the header for which to set the value.
210
@param value: The value to set for the named header.
212
values = self.getRawHeaders(name)
214
self.setRawHeaders(name, [value])
219
def getRawHeaders(self, name, default=None):
221
Returns a list of headers matching the given name as the raw string
225
@param name: The name of the HTTP header to get the values of.
227
@param default: The value to return if no header with the given C{name}
231
@return: A C{list} of values for the given header.
233
return self._rawHeaders.get(name.lower(), default)
236
def getAllRawHeaders(self):
238
Return an iterator of key, value pairs of all headers contained in this
239
object, as strings. The keys are capitalized in canonical
242
for k, v in self._rawHeaders.iteritems():
243
yield self._canonicalNameCaps(k), v
246
def _canonicalNameCaps(self, name):
248
Return the canonical name for the given header.
251
@param name: The all-lowercase header name to capitalize in its
255
@return: The canonical name of the header.
257
return self._caseMappings.get(name, _dashCapitalize(name))
260
__all__ = ['Headers']