summaryrefslogtreecommitdiffstats
path: root/Lib/http
diff options
context:
space:
mode:
authorAlexey Namyotkin <62434915+nametkin@users.noreply.github.com>2023-05-16 06:20:30 (GMT)
committerGitHub <noreply@github.com>2023-05-16 06:20:30 (GMT)
commit85ec192ac4b000d4e47df6123b65eacbd1fdccfa (patch)
tree6029b8cda6865e42154c9bcea0e419c8ba0f54eb /Lib/http
parent24d8b88420b81fc60aeb0cbcacef1e72d633824a (diff)
downloadcpython-85ec192ac4b000d4e47df6123b65eacbd1fdccfa.zip
cpython-85ec192ac4b000d4e47df6123b65eacbd1fdccfa.tar.gz
cpython-85ec192ac4b000d4e47df6123b65eacbd1fdccfa.tar.bz2
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>
Diffstat (limited to 'Lib/http')
-rw-r--r--Lib/http/client.py37
1 files changed, 29 insertions, 8 deletions
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 50f2b46..59a9fd7 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -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)