blob: c3774bb44d45c410fe4761f2028faf9b0998337d [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001"""Manage HTTP Response Headers
2
3Much of this module is red-handedly pilfered from email.Message in the stdlib,
4so portions are Copyright (C) 2001,2002 Python Software Foundation, and were
5written by Barry Warsaw.
6"""
7
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008# Regular expression that matches `special' characters in parameters, the
9# existance of which force quoting of the parameter value.
10import re
11tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')
12
13def _formatparam(param, value=None, quote=1):
14 """Convenience function to format and return a key=value pair.
15
16 This will quote the value if needed or if quote is true.
17 """
18 if value is not None and len(value) > 0:
19 if quote or tspecials.search(value):
20 value = value.replace('\\', '\\\\').replace('"', r'\"')
21 return '%s="%s"' % (param, value)
22 else:
23 return '%s=%s' % (param, value)
24 else:
25 return param
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40class Headers:
41
42 """Manage a collection of HTTP response headers"""
43
44 def __init__(self,headers):
Guido van Rossum13257902007-06-07 23:15:56 +000045 if not isinstance(headers, list):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046 raise TypeError("Headers must be a list of name/value tuples")
47 self._headers = headers
48
49 def __len__(self):
50 """Return the total number of headers, including duplicates."""
51 return len(self._headers)
52
53 def __setitem__(self, name, val):
54 """Set the value of a header."""
55 del self[name]
56 self._headers.append((name, val))
57
58 def __delitem__(self,name):
59 """Delete all occurrences of a header, if present.
60
61 Does *not* raise an exception if the header is missing.
62 """
63 name = name.lower()
Guido van Rossumb053cd82006-08-24 03:53:23 +000064 self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name]
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065
66 def __getitem__(self,name):
67 """Get the first header value for 'name'
68
69 Return None if the header is missing instead of raising an exception.
70
71 Note that if the header appeared multiple times, the first exactly which
72 occurrance gets returned is undefined. Use getall() to get all
73 the values matching a header field name.
74 """
75 return self.get(name)
76
77
78
79
80
Guido van Rossume2b70bc2006-08-18 22:13:04 +000081 def __contains__(self, name):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000082 """Return true if the message contains the header."""
83 return self.get(name) is not None
84
Thomas Wouters0e3f5912006-08-11 14:57:12 +000085
86 def get_all(self, name):
87 """Return a list of all the values for the named field.
88
89 These will be sorted in the order they appeared in the original header
90 list or were added to this instance, and may contain duplicates. Any
91 fields deleted and re-inserted are always appended to the header list.
92 If no fields exist with the given name, returns an empty list.
93 """
94 name = name.lower()
95 return [kv[1] for kv in self._headers if kv[0].lower()==name]
96
97
98 def get(self,name,default=None):
99 """Get the first header value for 'name', or return 'default'"""
100 name = name.lower()
101 for k,v in self._headers:
102 if k.lower()==name:
103 return v
104 return default
105
106
107 def keys(self):
108 """Return a list of all the header field names.
109
110 These will be sorted in the order they appeared in the original header
111 list, or were added to this instance, and may contain duplicates.
112 Any fields deleted and re-inserted are always appended to the header
113 list.
114 """
115 return [k for k, v in self._headers]
116
117
118
119
120 def values(self):
121 """Return a list of all header values.
122
123 These will be sorted in the order they appeared in the original header
124 list, or were added to this instance, and may contain duplicates.
125 Any fields deleted and re-inserted are always appended to the header
126 list.
127 """
128 return [v for k, v in self._headers]
129
130 def items(self):
131 """Get all the header fields and values.
132
133 These will be sorted in the order they were in the original header
134 list, or were added to this instance, and may contain duplicates.
135 Any fields deleted and re-inserted are always appended to the header
136 list.
137 """
138 return self._headers[:]
139
140 def __repr__(self):
Brett Cannon0b70cca2006-08-25 02:59:59 +0000141 return "Headers(%r)" % self._headers
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000142
143 def __str__(self):
144 """str() returns the formatted headers, complete with end line,
145 suitable for direct HTTP transmission."""
146 return '\r\n'.join(["%s: %s" % kv for kv in self._headers]+['',''])
147
148 def setdefault(self,name,value):
149 """Return first matching header value for 'name', or 'value'
150
151 If there is no header named 'name', add a new header with name 'name'
152 and value 'value'."""
153 result = self.get(name)
154 if result is None:
155 self._headers.append((name,value))
156 return value
157 else:
158 return result
159
160
161 def add_header(self, _name, _value, **_params):
162 """Extended header setting.
163
164 _name is the header field to add. keyword arguments can be used to set
165 additional parameters for the header field, with underscores converted
166 to dashes. Normally the parameter will be added as key="value" unless
167 value is None, in which case only the key will be added.
168
169 Example:
170
171 h.add_header('content-disposition', 'attachment', filename='bud.gif')
172
173 Note that unlike the corresponding 'email.Message' method, this does
174 *not* handle '(charset, language, value)' tuples: all values must be
175 strings or None.
176 """
177 parts = []
178 if _value is not None:
179 parts.append(_value)
180 for k, v in _params.items():
181 if v is None:
182 parts.append(k.replace('_', '-'))
183 else:
184 parts.append(_formatparam(k.replace('_', '-'), v))
185 self._headers.append((_name, "; ".join(parts)))
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201#