ยปCore Development>Code coverage>Lib/wsgiref/headers.py

Python code coverage for Lib/wsgiref/headers.py

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