Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/wsgiref/headers.py @ 68:5028fdace37b
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 16:23:26 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 68:5028fdace37b |
---|---|
1 """Manage HTTP Response Headers | |
2 | |
3 Much of this module is red-handedly pilfered from email.message in the stdlib, | |
4 so portions are Copyright (C) 2001,2002 Python Software Foundation, and were | |
5 written by Barry Warsaw. | |
6 """ | |
7 | |
8 # Regular expression that matches `special' characters in parameters, the | |
9 # existence of which force quoting of the parameter value. | |
10 import re | |
11 tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]') | |
12 | |
13 def _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 class Headers: | |
29 """Manage a collection of HTTP response headers""" | |
30 | |
31 def __init__(self, headers=None): | |
32 headers = headers if headers is not None else [] | |
33 if type(headers) is not list: | |
34 raise TypeError("Headers must be a list of name/value tuples") | |
35 self._headers = headers | |
36 if __debug__: | |
37 for k, v in headers: | |
38 self._convert_string_type(k) | |
39 self._convert_string_type(v) | |
40 | |
41 def _convert_string_type(self, value): | |
42 """Convert/check value type.""" | |
43 if type(value) is str: | |
44 return value | |
45 raise AssertionError("Header names/values must be" | |
46 " of type str (got {0})".format(repr(value))) | |
47 | |
48 def __len__(self): | |
49 """Return the total number of headers, including duplicates.""" | |
50 return len(self._headers) | |
51 | |
52 def __setitem__(self, name, val): | |
53 """Set the value of a header.""" | |
54 del self[name] | |
55 self._headers.append( | |
56 (self._convert_string_type(name), self._convert_string_type(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 = self._convert_string_type(name.lower()) | |
64 self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name] | |
65 | |
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 occurrence 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 def __contains__(self, name): | |
78 """Return true if the message contains the header.""" | |
79 return self.get(name) is not None | |
80 | |
81 | |
82 def get_all(self, name): | |
83 """Return a list of all the values for the named field. | |
84 | |
85 These will be sorted in the order they appeared in the original header | |
86 list or were added to this instance, and may contain duplicates. Any | |
87 fields deleted and re-inserted are always appended to the header list. | |
88 If no fields exist with the given name, returns an empty list. | |
89 """ | |
90 name = self._convert_string_type(name.lower()) | |
91 return [kv[1] for kv in self._headers if kv[0].lower()==name] | |
92 | |
93 | |
94 def get(self,name,default=None): | |
95 """Get the first header value for 'name', or return 'default'""" | |
96 name = self._convert_string_type(name.lower()) | |
97 for k,v in self._headers: | |
98 if k.lower()==name: | |
99 return v | |
100 return default | |
101 | |
102 | |
103 def keys(self): | |
104 """Return a list of all the header field names. | |
105 | |
106 These will be sorted in the order they appeared in the original header | |
107 list, or were added to this instance, and may contain duplicates. | |
108 Any fields deleted and re-inserted are always appended to the header | |
109 list. | |
110 """ | |
111 return [k for k, v in self._headers] | |
112 | |
113 def values(self): | |
114 """Return a list of all header values. | |
115 | |
116 These will be sorted in the order they appeared in the original header | |
117 list, or were added to this instance, and may contain duplicates. | |
118 Any fields deleted and re-inserted are always appended to the header | |
119 list. | |
120 """ | |
121 return [v for k, v in self._headers] | |
122 | |
123 def items(self): | |
124 """Get all the header fields and values. | |
125 | |
126 These will be sorted in the order they were in the original header | |
127 list, or were added to this instance, and may contain duplicates. | |
128 Any fields deleted and re-inserted are always appended to the header | |
129 list. | |
130 """ | |
131 return self._headers[:] | |
132 | |
133 def __repr__(self): | |
134 return "%s(%r)" % (self.__class__.__name__, self._headers) | |
135 | |
136 def __str__(self): | |
137 """str() returns the formatted headers, complete with end line, | |
138 suitable for direct HTTP transmission.""" | |
139 return '\r\n'.join(["%s: %s" % kv for kv in self._headers]+['','']) | |
140 | |
141 def __bytes__(self): | |
142 return str(self).encode('iso-8859-1') | |
143 | |
144 def setdefault(self,name,value): | |
145 """Return first matching header value for 'name', or 'value' | |
146 | |
147 If there is no header named 'name', add a new header with name 'name' | |
148 and value 'value'.""" | |
149 result = self.get(name) | |
150 if result is None: | |
151 self._headers.append((self._convert_string_type(name), | |
152 self._convert_string_type(value))) | |
153 return value | |
154 else: | |
155 return result | |
156 | |
157 def add_header(self, _name, _value, **_params): | |
158 """Extended header setting. | |
159 | |
160 _name is the header field to add. keyword arguments can be used to set | |
161 additional parameters for the header field, with underscores converted | |
162 to dashes. Normally the parameter will be added as key="value" unless | |
163 value is None, in which case only the key will be added. | |
164 | |
165 Example: | |
166 | |
167 h.add_header('content-disposition', 'attachment', filename='bud.gif') | |
168 | |
169 Note that unlike the corresponding 'email.message' method, this does | |
170 *not* handle '(charset, language, value)' tuples: all values must be | |
171 strings or None. | |
172 """ | |
173 parts = [] | |
174 if _value is not None: | |
175 _value = self._convert_string_type(_value) | |
176 parts.append(_value) | |
177 for k, v in _params.items(): | |
178 k = self._convert_string_type(k) | |
179 if v is None: | |
180 parts.append(k.replace('_', '-')) | |
181 else: | |
182 v = self._convert_string_type(v) | |
183 parts.append(_formatparam(k.replace('_', '-'), v)) | |
184 self._headers.append((self._convert_string_type(_name), "; ".join(parts))) |