annotate mercurial/hgweb/wsgiheaders.py @ 45095:8e04607023e5

procutil: ensure that procutil.std{out,err}.write() writes all bytes Python 3 offers different kind of streams and it’s not guaranteed for all of them that calling write() writes all bytes. When Python is started in unbuffered mode, sys.std{out,err}.buffer are instances of io.FileIO, whose write() can write less bytes for platform-specific reasons (e.g. Linux has a 0x7ffff000 bytes maximum and could write less if interrupted by a signal; when writing to Windows consoles, it’s limited to 32767 bytes to avoid the "not enough space" error). This can lead to silent loss of data, both when using sys.std{out,err}.buffer (which may in fact not be a buffered stream) and when using the text streams sys.std{out,err} (I’ve created a CPython bug report for that: https://bugs.python.org/issue41221). Python may fix the problem at some point. For now, we implement our own wrapper for procutil.std{out,err} that calls the raw stream’s write() method until all bytes have been written. We don’t use sys.std{out,err} for larger writes, so I think it’s not worth the effort to patch them.
author Manuel Jacob <me@manueljacob.de>
date Fri, 10 Jul 2020 12:27:58 +0200
parents 6d3b67a837a6
children 6000f5b25c9b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
1 """This was forked from cpython's wsgiref.headers module to work on bytes.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
2
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
3 Header from old file showing copyright is below.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
4
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
5 Much of this module is red-handedly pilfered from email.message in the stdlib,
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
6 so portions are Copyright (C) 2001,2002 Python Software Foundation, and were
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
7 written by Barry Warsaw.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
8 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
9
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
10 # Regular expression that matches `special' characters in parameters, the
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
11 # existence of which force quoting of the parameter value.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
12 from __future__ import absolute_import, print_function
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
13
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
14 import re
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
15
44021
6d3b67a837a6 cleanup: drop redundant character escapes from `[]` character sets
Matt Harbison <matt_harbison@yahoo.com>
parents: 43503
diff changeset
16 tspecials = re.compile(br'[ ()<>@,;:\\"/\[\]?=]')
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
17
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
18
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
19 def _formatparam(param, value=None, quote=1):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
20 """Convenience function to format and return a key=value pair.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
21 This will quote the value if needed or if quote is true.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
22 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
23 if value is not None and len(value) > 0:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
24 if quote or tspecials.search(value):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
25 value = value.replace(b'\\', b'\\\\').replace(b'"', r'\"')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
26 return b'%s="%s"' % (param, value)
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
27 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
28 return b'%s=%s' % (param, value)
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
29 else:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
30 return param
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
31
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
32
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
33 class Headers(object):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
34 """Manage a collection of HTTP response headers"""
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
35
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
36 def __init__(self, headers=None):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
37 headers = headers if headers is not None else []
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
38 if type(headers) is not list:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
39 raise TypeError(b"Headers must be a list of name/value tuples")
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
40 self._headers = headers
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
41 if __debug__:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
42 for k, v in headers:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
43 self._convert_string_type(k)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
44 self._convert_string_type(v)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
45
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
46 def _convert_string_type(self, value):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
47 """Convert/check value type."""
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
48 if type(value) is bytes:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
49 return value
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
50 raise AssertionError(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
51 u"Header names/values must be"
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
52 u" of type bytes (got %s)" % repr(value)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
53 )
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
54
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
55 def __len__(self):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
56 """Return the total number of headers, including duplicates."""
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
57 return len(self._headers)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
58
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
59 def __setitem__(self, name, val):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
60 """Set the value of a header."""
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
61 del self[name]
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
62 self._headers.append(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
63 (self._convert_string_type(name), self._convert_string_type(val))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
64 )
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
65
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
66 def __delitem__(self, name):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
67 """Delete all occurrences of a header, if present.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
68 Does *not* raise an exception if the header is missing.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
69 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
70 name = self._convert_string_type(name.lower())
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
71 self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name]
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
72
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
73 def __getitem__(self, name):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
74 """Get the first header value for 'name'
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
75 Return None if the header is missing instead of raising an exception.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
76 Note that if the header appeared multiple times, the first exactly which
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
77 occurrence gets returned is undefined. Use getall() to get all
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
78 the values matching a header field name.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
79 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
80 return self.get(name)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
81
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
82 def __contains__(self, name):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
83 """Return true if the message contains the header."""
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
84 return self.get(name) is not None
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
85
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
86 def get_all(self, name):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
87 """Return a list of all the values for the named field.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
88 These will be sorted in the order they appeared in the original header
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
89 list or were added to this instance, and may contain duplicates. Any
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
90 fields deleted and re-inserted are always appended to the header list.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
91 If no fields exist with the given name, returns an empty list.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
92 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
93 name = self._convert_string_type(name.lower())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
94 return [kv[1] for kv in self._headers if kv[0].lower() == name]
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
95
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
96 def get(self, name, default=None):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
97 """Get the first header value for 'name', or return 'default'"""
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
98 name = self._convert_string_type(name.lower())
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
99 for k, v in self._headers:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
100 if k.lower() == name:
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
101 return v
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
102 return default
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
103
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
104 def keys(self):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
105 """Return a list of all the header field names.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
106 These will be sorted in the order they appeared in the original header
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
107 list, or were added to this instance, and may contain duplicates.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
108 Any fields deleted and re-inserted are always appended to the header
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
109 list.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
110 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
111 return [k for k, v in self._headers]
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
112
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
113 def values(self):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
114 """Return a list of all header values.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
115 These will be sorted in the order they appeared in the original header
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
116 list, or were added to this instance, and may contain duplicates.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
117 Any fields deleted and re-inserted are always appended to the header
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
118 list.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
119 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
120 return [v for k, v in self._headers]
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
121
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
122 def items(self):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
123 """Get all the header fields and values.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
124 These will be sorted in the order they were in the original header
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
125 list, or were added to this instance, and may contain duplicates.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
126 Any fields deleted and re-inserted are always appended to the header
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
127 list.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
128 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
129 return self._headers[:]
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
130
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
131 def __repr__(self):
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
132 return "%s(%r)" % (self.__class__.__name__, self._headers)
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
133
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
134 def __str__(self):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
135 """str() returns the formatted headers, complete with end line,
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
136 suitable for direct HTTP transmission."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
137 return b'\r\n'.join(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
138 [b"%s: %s" % kv for kv in self._headers] + [b'', b'']
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
139 )
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
140
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
141 def __bytes__(self):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
142 return str(self).encode('iso-8859-1')
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
143
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
144 def setdefault(self, name, value):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
145 """Return first matching header value for 'name', or 'value'
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
146 If there is no header named 'name', add a new header with name 'name'
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
147 and value 'value'."""
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
148 result = self.get(name)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
149 if result is None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
150 self._headers.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
151 (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
152 self._convert_string_type(name),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
153 self._convert_string_type(value),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
154 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
155 )
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
156 return value
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
157 else:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
158 return result
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
159
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
160 def add_header(self, _name, _value, **_params):
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
161 """Extended header setting.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
162 _name is the header field to add. keyword arguments can be used to set
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
163 additional parameters for the header field, with underscores converted
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
164 to dashes. Normally the parameter will be added as key="value" unless
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
165 value is None, in which case only the key will be added.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
166 Example:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
167 h.add_header('content-disposition', 'attachment', filename='bud.gif')
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
168 Note that unlike the corresponding 'email.message' method, this does
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
169 *not* handle '(charset, language, value)' tuples: all values must be
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
170 strings or None.
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
171 """
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
172 parts = []
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
173 if _value is not None:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
174 _value = self._convert_string_type(_value)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
175 parts.append(_value)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
176 for k, v in _params.items():
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
177 k = self._convert_string_type(k)
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
178 if v is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
179 parts.append(k.replace(b'_', b'-'))
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
180 else:
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
181 v = self._convert_string_type(v)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
182 parts.append(_formatparam(k.replace(b'_', b'-'), v))
37605
74e1362585c0 wsgiheaders: import a bytes-ified fork of wsgiref.headers from cpython@46f5072
Augie Fackler <augie@google.com>
parents:
diff changeset
183 self._headers.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
184 (self._convert_string_type(_name), b"; ".join(parts))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41588
diff changeset
185 )