mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-69152: add method get_proxy_response_headers to HTTPConnection class (#104248)
Add http.client.HTTPConnection method get_proxy_response_headers() - this is a followup to https://github.com/python/cpython/pull/26152 which added it as a non-public attribute. This way we don't pre-compute a headers dictionary that most users will never access. The new method is properly public and documented and triggers full proxy header parsing into a dict only when actually called. --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Gregory P. Smith <greg@krypto.org>
This commit is contained in:
parent
24d8b88420
commit
85ec192ac4
4 changed files with 44 additions and 12 deletions
|
@ -221,8 +221,9 @@ def _read_headers(fp):
|
|||
break
|
||||
return headers
|
||||
|
||||
def parse_headers(fp, _class=HTTPMessage):
|
||||
"""Parses only RFC2822 headers from a file pointer.
|
||||
def _parse_header_lines(header_lines, _class=HTTPMessage):
|
||||
"""
|
||||
Parses only RFC2822 headers from header lines.
|
||||
|
||||
email Parser wants to see strings rather than bytes.
|
||||
But a TextIOWrapper around self.rfile would buffer too many bytes
|
||||
|
@ -231,10 +232,15 @@ def parse_headers(fp, _class=HTTPMessage):
|
|||
to parse.
|
||||
|
||||
"""
|
||||
headers = _read_headers(fp)
|
||||
hstring = b''.join(headers).decode('iso-8859-1')
|
||||
hstring = b''.join(header_lines).decode('iso-8859-1')
|
||||
return email.parser.Parser(_class=_class).parsestr(hstring)
|
||||
|
||||
def parse_headers(fp, _class=HTTPMessage):
|
||||
"""Parses only RFC2822 headers from a file pointer."""
|
||||
|
||||
headers = _read_headers(fp)
|
||||
return _parse_header_lines(headers, _class)
|
||||
|
||||
|
||||
class HTTPResponse(io.BufferedIOBase):
|
||||
|
||||
|
@ -858,7 +864,7 @@ class HTTPConnection:
|
|||
self._tunnel_host = None
|
||||
self._tunnel_port = None
|
||||
self._tunnel_headers = {}
|
||||
self._proxy_response_headers = None
|
||||
self._raw_proxy_headers = None
|
||||
|
||||
(self.host, self.port) = self._get_hostport(host, port)
|
||||
|
||||
|
@ -945,11 +951,11 @@ class HTTPConnection:
|
|||
try:
|
||||
(version, code, message) = response._read_status()
|
||||
|
||||
self._proxy_response_headers = parse_headers(response.fp)
|
||||
self._raw_proxy_headers = _read_headers(response.fp)
|
||||
|
||||
if self.debuglevel > 0:
|
||||
for hdr, val in self._proxy_response_headers.items():
|
||||
print("header:", hdr + ":", val)
|
||||
for header in self._raw_proxy_headers:
|
||||
print('header:', header.decode())
|
||||
|
||||
if code != http.HTTPStatus.OK:
|
||||
self.close()
|
||||
|
@ -958,6 +964,21 @@ class HTTPConnection:
|
|||
finally:
|
||||
response.close()
|
||||
|
||||
def get_proxy_response_headers(self):
|
||||
"""
|
||||
Returns a dictionary with the headers of the response
|
||||
received from the proxy server to the CONNECT request
|
||||
sent to set the tunnel.
|
||||
|
||||
If the CONNECT request was not sent, the method returns
|
||||
an empty dictionary.
|
||||
"""
|
||||
return (
|
||||
_parse_header_lines(self._raw_proxy_headers)
|
||||
if self._raw_proxy_headers is not None
|
||||
else {}
|
||||
)
|
||||
|
||||
def connect(self):
|
||||
"""Connect to the host and port specified in __init__."""
|
||||
sys.audit("http.client.connect", self, self.host, self.port)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue