xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/http/client.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Workerr"""HTTP/1.1 client library
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard Worker<intro stuff goes here>
4*cda5da8dSAndroid Build Coastguard Worker<other stuff, too>
5*cda5da8dSAndroid Build Coastguard Worker
6*cda5da8dSAndroid Build Coastguard WorkerHTTPConnection goes through a number of "states", which define when a client
7*cda5da8dSAndroid Build Coastguard Workermay legally make another request or fetch the response for a particular
8*cda5da8dSAndroid Build Coastguard Workerrequest. This diagram details these state transitions:
9*cda5da8dSAndroid Build Coastguard Worker
10*cda5da8dSAndroid Build Coastguard Worker    (null)
11*cda5da8dSAndroid Build Coastguard Worker      |
12*cda5da8dSAndroid Build Coastguard Worker      | HTTPConnection()
13*cda5da8dSAndroid Build Coastguard Worker      v
14*cda5da8dSAndroid Build Coastguard Worker    Idle
15*cda5da8dSAndroid Build Coastguard Worker      |
16*cda5da8dSAndroid Build Coastguard Worker      | putrequest()
17*cda5da8dSAndroid Build Coastguard Worker      v
18*cda5da8dSAndroid Build Coastguard Worker    Request-started
19*cda5da8dSAndroid Build Coastguard Worker      |
20*cda5da8dSAndroid Build Coastguard Worker      | ( putheader() )*  endheaders()
21*cda5da8dSAndroid Build Coastguard Worker      v
22*cda5da8dSAndroid Build Coastguard Worker    Request-sent
23*cda5da8dSAndroid Build Coastguard Worker      |\_____________________________
24*cda5da8dSAndroid Build Coastguard Worker      |                              | getresponse() raises
25*cda5da8dSAndroid Build Coastguard Worker      | response = getresponse()     | ConnectionError
26*cda5da8dSAndroid Build Coastguard Worker      v                              v
27*cda5da8dSAndroid Build Coastguard Worker    Unread-response                Idle
28*cda5da8dSAndroid Build Coastguard Worker    [Response-headers-read]
29*cda5da8dSAndroid Build Coastguard Worker      |\____________________
30*cda5da8dSAndroid Build Coastguard Worker      |                     |
31*cda5da8dSAndroid Build Coastguard Worker      | response.read()     | putrequest()
32*cda5da8dSAndroid Build Coastguard Worker      v                     v
33*cda5da8dSAndroid Build Coastguard Worker    Idle                  Req-started-unread-response
34*cda5da8dSAndroid Build Coastguard Worker                     ______/|
35*cda5da8dSAndroid Build Coastguard Worker                   /        |
36*cda5da8dSAndroid Build Coastguard Worker   response.read() |        | ( putheader() )*  endheaders()
37*cda5da8dSAndroid Build Coastguard Worker                   v        v
38*cda5da8dSAndroid Build Coastguard Worker       Request-started    Req-sent-unread-response
39*cda5da8dSAndroid Build Coastguard Worker                            |
40*cda5da8dSAndroid Build Coastguard Worker                            | response.read()
41*cda5da8dSAndroid Build Coastguard Worker                            v
42*cda5da8dSAndroid Build Coastguard Worker                          Request-sent
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard WorkerThis diagram presents the following rules:
45*cda5da8dSAndroid Build Coastguard Worker  -- a second request may not be started until {response-headers-read}
46*cda5da8dSAndroid Build Coastguard Worker  -- a response [object] cannot be retrieved until {request-sent}
47*cda5da8dSAndroid Build Coastguard Worker  -- there is no differentiation between an unread response body and a
48*cda5da8dSAndroid Build Coastguard Worker     partially read response body
49*cda5da8dSAndroid Build Coastguard Worker
50*cda5da8dSAndroid Build Coastguard WorkerNote: this enforcement is applied by the HTTPConnection class. The
51*cda5da8dSAndroid Build Coastguard Worker      HTTPResponse class does not enforce this state machine, which
52*cda5da8dSAndroid Build Coastguard Worker      implies sophisticated clients may accelerate the request/response
53*cda5da8dSAndroid Build Coastguard Worker      pipeline. Caution should be taken, though: accelerating the states
54*cda5da8dSAndroid Build Coastguard Worker      beyond the above pattern may imply knowledge of the server's
55*cda5da8dSAndroid Build Coastguard Worker      connection-close behavior for certain requests. For example, it
56*cda5da8dSAndroid Build Coastguard Worker      is impossible to tell whether the server will close the connection
57*cda5da8dSAndroid Build Coastguard Worker      UNTIL the response headers have been read; this means that further
58*cda5da8dSAndroid Build Coastguard Worker      requests cannot be placed into the pipeline until it is known that
59*cda5da8dSAndroid Build Coastguard Worker      the server will NOT be closing the connection.
60*cda5da8dSAndroid Build Coastguard Worker
61*cda5da8dSAndroid Build Coastguard WorkerLogical State                  __state            __response
62*cda5da8dSAndroid Build Coastguard Worker-------------                  -------            ----------
63*cda5da8dSAndroid Build Coastguard WorkerIdle                           _CS_IDLE           None
64*cda5da8dSAndroid Build Coastguard WorkerRequest-started                _CS_REQ_STARTED    None
65*cda5da8dSAndroid Build Coastguard WorkerRequest-sent                   _CS_REQ_SENT       None
66*cda5da8dSAndroid Build Coastguard WorkerUnread-response                _CS_IDLE           <response_class>
67*cda5da8dSAndroid Build Coastguard WorkerReq-started-unread-response    _CS_REQ_STARTED    <response_class>
68*cda5da8dSAndroid Build Coastguard WorkerReq-sent-unread-response       _CS_REQ_SENT       <response_class>
69*cda5da8dSAndroid Build Coastguard Worker"""
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard Workerimport email.parser
72*cda5da8dSAndroid Build Coastguard Workerimport email.message
73*cda5da8dSAndroid Build Coastguard Workerimport errno
74*cda5da8dSAndroid Build Coastguard Workerimport http
75*cda5da8dSAndroid Build Coastguard Workerimport io
76*cda5da8dSAndroid Build Coastguard Workerimport re
77*cda5da8dSAndroid Build Coastguard Workerimport socket
78*cda5da8dSAndroid Build Coastguard Workerimport sys
79*cda5da8dSAndroid Build Coastguard Workerimport collections.abc
80*cda5da8dSAndroid Build Coastguard Workerfrom urllib.parse import urlsplit
81*cda5da8dSAndroid Build Coastguard Worker
82*cda5da8dSAndroid Build Coastguard Worker# HTTPMessage, parse_headers(), and the HTTP status code constants are
83*cda5da8dSAndroid Build Coastguard Worker# intentionally omitted for simplicity
84*cda5da8dSAndroid Build Coastguard Worker__all__ = ["HTTPResponse", "HTTPConnection",
85*cda5da8dSAndroid Build Coastguard Worker           "HTTPException", "NotConnected", "UnknownProtocol",
86*cda5da8dSAndroid Build Coastguard Worker           "UnknownTransferEncoding", "UnimplementedFileMode",
87*cda5da8dSAndroid Build Coastguard Worker           "IncompleteRead", "InvalidURL", "ImproperConnectionState",
88*cda5da8dSAndroid Build Coastguard Worker           "CannotSendRequest", "CannotSendHeader", "ResponseNotReady",
89*cda5da8dSAndroid Build Coastguard Worker           "BadStatusLine", "LineTooLong", "RemoteDisconnected", "error",
90*cda5da8dSAndroid Build Coastguard Worker           "responses"]
91*cda5da8dSAndroid Build Coastguard Worker
92*cda5da8dSAndroid Build Coastguard WorkerHTTP_PORT = 80
93*cda5da8dSAndroid Build Coastguard WorkerHTTPS_PORT = 443
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Worker_UNKNOWN = 'UNKNOWN'
96*cda5da8dSAndroid Build Coastguard Worker
97*cda5da8dSAndroid Build Coastguard Worker# connection states
98*cda5da8dSAndroid Build Coastguard Worker_CS_IDLE = 'Idle'
99*cda5da8dSAndroid Build Coastguard Worker_CS_REQ_STARTED = 'Request-started'
100*cda5da8dSAndroid Build Coastguard Worker_CS_REQ_SENT = 'Request-sent'
101*cda5da8dSAndroid Build Coastguard Worker
102*cda5da8dSAndroid Build Coastguard Worker
103*cda5da8dSAndroid Build Coastguard Worker# hack to maintain backwards compatibility
104*cda5da8dSAndroid Build Coastguard Workerglobals().update(http.HTTPStatus.__members__)
105*cda5da8dSAndroid Build Coastguard Worker
106*cda5da8dSAndroid Build Coastguard Worker# another hack to maintain backwards compatibility
107*cda5da8dSAndroid Build Coastguard Worker# Mapping status codes to official W3C names
108*cda5da8dSAndroid Build Coastguard Workerresponses = {v: v.phrase for v in http.HTTPStatus.__members__.values()}
109*cda5da8dSAndroid Build Coastguard Worker
110*cda5da8dSAndroid Build Coastguard Worker# maximal line length when calling readline().
111*cda5da8dSAndroid Build Coastguard Worker_MAXLINE = 65536
112*cda5da8dSAndroid Build Coastguard Worker_MAXHEADERS = 100
113*cda5da8dSAndroid Build Coastguard Worker
114*cda5da8dSAndroid Build Coastguard Worker# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
115*cda5da8dSAndroid Build Coastguard Worker#
116*cda5da8dSAndroid Build Coastguard Worker# VCHAR          = %x21-7E
117*cda5da8dSAndroid Build Coastguard Worker# obs-text       = %x80-FF
118*cda5da8dSAndroid Build Coastguard Worker# header-field   = field-name ":" OWS field-value OWS
119*cda5da8dSAndroid Build Coastguard Worker# field-name     = token
120*cda5da8dSAndroid Build Coastguard Worker# field-value    = *( field-content / obs-fold )
121*cda5da8dSAndroid Build Coastguard Worker# field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
122*cda5da8dSAndroid Build Coastguard Worker# field-vchar    = VCHAR / obs-text
123*cda5da8dSAndroid Build Coastguard Worker#
124*cda5da8dSAndroid Build Coastguard Worker# obs-fold       = CRLF 1*( SP / HTAB )
125*cda5da8dSAndroid Build Coastguard Worker#                ; obsolete line folding
126*cda5da8dSAndroid Build Coastguard Worker#                ; see Section 3.2.4
127*cda5da8dSAndroid Build Coastguard Worker
128*cda5da8dSAndroid Build Coastguard Worker# token          = 1*tchar
129*cda5da8dSAndroid Build Coastguard Worker#
130*cda5da8dSAndroid Build Coastguard Worker# tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*"
131*cda5da8dSAndroid Build Coastguard Worker#                / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
132*cda5da8dSAndroid Build Coastguard Worker#                / DIGIT / ALPHA
133*cda5da8dSAndroid Build Coastguard Worker#                ; any VCHAR, except delimiters
134*cda5da8dSAndroid Build Coastguard Worker#
135*cda5da8dSAndroid Build Coastguard Worker# VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1
136*cda5da8dSAndroid Build Coastguard Worker
137*cda5da8dSAndroid Build Coastguard Worker# the patterns for both name and value are more lenient than RFC
138*cda5da8dSAndroid Build Coastguard Worker# definitions to allow for backwards compatibility
139*cda5da8dSAndroid Build Coastguard Worker_is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch
140*cda5da8dSAndroid Build Coastguard Worker_is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search
141*cda5da8dSAndroid Build Coastguard Worker
142*cda5da8dSAndroid Build Coastguard Worker# These characters are not allowed within HTTP URL paths.
143*cda5da8dSAndroid Build Coastguard Worker#  See https://tools.ietf.org/html/rfc3986#section-3.3 and the
144*cda5da8dSAndroid Build Coastguard Worker#  https://tools.ietf.org/html/rfc3986#appendix-A pchar definition.
145*cda5da8dSAndroid Build Coastguard Worker# Prevents CVE-2019-9740.  Includes control characters such as \r\n.
146*cda5da8dSAndroid Build Coastguard Worker# We don't restrict chars above \x7f as putrequest() limits us to ASCII.
147*cda5da8dSAndroid Build Coastguard Worker_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]')
148*cda5da8dSAndroid Build Coastguard Worker# Arguably only these _should_ allowed:
149*cda5da8dSAndroid Build Coastguard Worker#  _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$")
150*cda5da8dSAndroid Build Coastguard Worker# We are more lenient for assumed real world compatibility purposes.
151*cda5da8dSAndroid Build Coastguard Worker
152*cda5da8dSAndroid Build Coastguard Worker# These characters are not allowed within HTTP method names
153*cda5da8dSAndroid Build Coastguard Worker# to prevent http header injection.
154*cda5da8dSAndroid Build Coastguard Worker_contains_disallowed_method_pchar_re = re.compile('[\x00-\x1f]')
155*cda5da8dSAndroid Build Coastguard Worker
156*cda5da8dSAndroid Build Coastguard Worker# We always set the Content-Length header for these methods because some
157*cda5da8dSAndroid Build Coastguard Worker# servers will otherwise respond with a 411
158*cda5da8dSAndroid Build Coastguard Worker_METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}
159*cda5da8dSAndroid Build Coastguard Worker
160*cda5da8dSAndroid Build Coastguard Worker
161*cda5da8dSAndroid Build Coastguard Workerdef _encode(data, name='data'):
162*cda5da8dSAndroid Build Coastguard Worker    """Call data.encode("latin-1") but show a better error message."""
163*cda5da8dSAndroid Build Coastguard Worker    try:
164*cda5da8dSAndroid Build Coastguard Worker        return data.encode("latin-1")
165*cda5da8dSAndroid Build Coastguard Worker    except UnicodeEncodeError as err:
166*cda5da8dSAndroid Build Coastguard Worker        raise UnicodeEncodeError(
167*cda5da8dSAndroid Build Coastguard Worker            err.encoding,
168*cda5da8dSAndroid Build Coastguard Worker            err.object,
169*cda5da8dSAndroid Build Coastguard Worker            err.start,
170*cda5da8dSAndroid Build Coastguard Worker            err.end,
171*cda5da8dSAndroid Build Coastguard Worker            "%s (%.20r) is not valid Latin-1. Use %s.encode('utf-8') "
172*cda5da8dSAndroid Build Coastguard Worker            "if you want to send it encoded in UTF-8." %
173*cda5da8dSAndroid Build Coastguard Worker            (name.title(), data[err.start:err.end], name)) from None
174*cda5da8dSAndroid Build Coastguard Worker
175*cda5da8dSAndroid Build Coastguard Worker
176*cda5da8dSAndroid Build Coastguard Workerclass HTTPMessage(email.message.Message):
177*cda5da8dSAndroid Build Coastguard Worker    # XXX The only usage of this method is in
178*cda5da8dSAndroid Build Coastguard Worker    # http.server.CGIHTTPRequestHandler.  Maybe move the code there so
179*cda5da8dSAndroid Build Coastguard Worker    # that it doesn't need to be part of the public API.  The API has
180*cda5da8dSAndroid Build Coastguard Worker    # never been defined so this could cause backwards compatibility
181*cda5da8dSAndroid Build Coastguard Worker    # issues.
182*cda5da8dSAndroid Build Coastguard Worker
183*cda5da8dSAndroid Build Coastguard Worker    def getallmatchingheaders(self, name):
184*cda5da8dSAndroid Build Coastguard Worker        """Find all header lines matching a given header name.
185*cda5da8dSAndroid Build Coastguard Worker
186*cda5da8dSAndroid Build Coastguard Worker        Look through the list of headers and find all lines matching a given
187*cda5da8dSAndroid Build Coastguard Worker        header name (and their continuation lines).  A list of the lines is
188*cda5da8dSAndroid Build Coastguard Worker        returned, without interpretation.  If the header does not occur, an
189*cda5da8dSAndroid Build Coastguard Worker        empty list is returned.  If the header occurs multiple times, all
190*cda5da8dSAndroid Build Coastguard Worker        occurrences are returned.  Case is not important in the header name.
191*cda5da8dSAndroid Build Coastguard Worker
192*cda5da8dSAndroid Build Coastguard Worker        """
193*cda5da8dSAndroid Build Coastguard Worker        name = name.lower() + ':'
194*cda5da8dSAndroid Build Coastguard Worker        n = len(name)
195*cda5da8dSAndroid Build Coastguard Worker        lst = []
196*cda5da8dSAndroid Build Coastguard Worker        hit = 0
197*cda5da8dSAndroid Build Coastguard Worker        for line in self.keys():
198*cda5da8dSAndroid Build Coastguard Worker            if line[:n].lower() == name:
199*cda5da8dSAndroid Build Coastguard Worker                hit = 1
200*cda5da8dSAndroid Build Coastguard Worker            elif not line[:1].isspace():
201*cda5da8dSAndroid Build Coastguard Worker                hit = 0
202*cda5da8dSAndroid Build Coastguard Worker            if hit:
203*cda5da8dSAndroid Build Coastguard Worker                lst.append(line)
204*cda5da8dSAndroid Build Coastguard Worker        return lst
205*cda5da8dSAndroid Build Coastguard Worker
206*cda5da8dSAndroid Build Coastguard Workerdef _read_headers(fp):
207*cda5da8dSAndroid Build Coastguard Worker    """Reads potential header lines into a list from a file pointer.
208*cda5da8dSAndroid Build Coastguard Worker
209*cda5da8dSAndroid Build Coastguard Worker    Length of line is limited by _MAXLINE, and number of
210*cda5da8dSAndroid Build Coastguard Worker    headers is limited by _MAXHEADERS.
211*cda5da8dSAndroid Build Coastguard Worker    """
212*cda5da8dSAndroid Build Coastguard Worker    headers = []
213*cda5da8dSAndroid Build Coastguard Worker    while True:
214*cda5da8dSAndroid Build Coastguard Worker        line = fp.readline(_MAXLINE + 1)
215*cda5da8dSAndroid Build Coastguard Worker        if len(line) > _MAXLINE:
216*cda5da8dSAndroid Build Coastguard Worker            raise LineTooLong("header line")
217*cda5da8dSAndroid Build Coastguard Worker        headers.append(line)
218*cda5da8dSAndroid Build Coastguard Worker        if len(headers) > _MAXHEADERS:
219*cda5da8dSAndroid Build Coastguard Worker            raise HTTPException("got more than %d headers" % _MAXHEADERS)
220*cda5da8dSAndroid Build Coastguard Worker        if line in (b'\r\n', b'\n', b''):
221*cda5da8dSAndroid Build Coastguard Worker            break
222*cda5da8dSAndroid Build Coastguard Worker    return headers
223*cda5da8dSAndroid Build Coastguard Worker
224*cda5da8dSAndroid Build Coastguard Workerdef parse_headers(fp, _class=HTTPMessage):
225*cda5da8dSAndroid Build Coastguard Worker    """Parses only RFC2822 headers from a file pointer.
226*cda5da8dSAndroid Build Coastguard Worker
227*cda5da8dSAndroid Build Coastguard Worker    email Parser wants to see strings rather than bytes.
228*cda5da8dSAndroid Build Coastguard Worker    But a TextIOWrapper around self.rfile would buffer too many bytes
229*cda5da8dSAndroid Build Coastguard Worker    from the stream, bytes which we later need to read as bytes.
230*cda5da8dSAndroid Build Coastguard Worker    So we read the correct bytes here, as bytes, for email Parser
231*cda5da8dSAndroid Build Coastguard Worker    to parse.
232*cda5da8dSAndroid Build Coastguard Worker
233*cda5da8dSAndroid Build Coastguard Worker    """
234*cda5da8dSAndroid Build Coastguard Worker    headers = _read_headers(fp)
235*cda5da8dSAndroid Build Coastguard Worker    hstring = b''.join(headers).decode('iso-8859-1')
236*cda5da8dSAndroid Build Coastguard Worker    return email.parser.Parser(_class=_class).parsestr(hstring)
237*cda5da8dSAndroid Build Coastguard Worker
238*cda5da8dSAndroid Build Coastguard Worker
239*cda5da8dSAndroid Build Coastguard Workerclass HTTPResponse(io.BufferedIOBase):
240*cda5da8dSAndroid Build Coastguard Worker
241*cda5da8dSAndroid Build Coastguard Worker    # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
242*cda5da8dSAndroid Build Coastguard Worker
243*cda5da8dSAndroid Build Coastguard Worker    # The bytes from the socket object are iso-8859-1 strings.
244*cda5da8dSAndroid Build Coastguard Worker    # See RFC 2616 sec 2.2 which notes an exception for MIME-encoded
245*cda5da8dSAndroid Build Coastguard Worker    # text following RFC 2047.  The basic status line parsing only
246*cda5da8dSAndroid Build Coastguard Worker    # accepts iso-8859-1.
247*cda5da8dSAndroid Build Coastguard Worker
248*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, sock, debuglevel=0, method=None, url=None):
249*cda5da8dSAndroid Build Coastguard Worker        # If the response includes a content-length header, we need to
250*cda5da8dSAndroid Build Coastguard Worker        # make sure that the client doesn't read more than the
251*cda5da8dSAndroid Build Coastguard Worker        # specified number of bytes.  If it does, it will block until
252*cda5da8dSAndroid Build Coastguard Worker        # the server times out and closes the connection.  This will
253*cda5da8dSAndroid Build Coastguard Worker        # happen if a self.fp.read() is done (without a size) whether
254*cda5da8dSAndroid Build Coastguard Worker        # self.fp is buffered or not.  So, no self.fp.read() by
255*cda5da8dSAndroid Build Coastguard Worker        # clients unless they know what they are doing.
256*cda5da8dSAndroid Build Coastguard Worker        self.fp = sock.makefile("rb")
257*cda5da8dSAndroid Build Coastguard Worker        self.debuglevel = debuglevel
258*cda5da8dSAndroid Build Coastguard Worker        self._method = method
259*cda5da8dSAndroid Build Coastguard Worker
260*cda5da8dSAndroid Build Coastguard Worker        # The HTTPResponse object is returned via urllib.  The clients
261*cda5da8dSAndroid Build Coastguard Worker        # of http and urllib expect different attributes for the
262*cda5da8dSAndroid Build Coastguard Worker        # headers.  headers is used here and supports urllib.  msg is
263*cda5da8dSAndroid Build Coastguard Worker        # provided as a backwards compatibility layer for http
264*cda5da8dSAndroid Build Coastguard Worker        # clients.
265*cda5da8dSAndroid Build Coastguard Worker
266*cda5da8dSAndroid Build Coastguard Worker        self.headers = self.msg = None
267*cda5da8dSAndroid Build Coastguard Worker
268*cda5da8dSAndroid Build Coastguard Worker        # from the Status-Line of the response
269*cda5da8dSAndroid Build Coastguard Worker        self.version = _UNKNOWN # HTTP-Version
270*cda5da8dSAndroid Build Coastguard Worker        self.status = _UNKNOWN  # Status-Code
271*cda5da8dSAndroid Build Coastguard Worker        self.reason = _UNKNOWN  # Reason-Phrase
272*cda5da8dSAndroid Build Coastguard Worker
273*cda5da8dSAndroid Build Coastguard Worker        self.chunked = _UNKNOWN         # is "chunked" being used?
274*cda5da8dSAndroid Build Coastguard Worker        self.chunk_left = _UNKNOWN      # bytes left to read in current chunk
275*cda5da8dSAndroid Build Coastguard Worker        self.length = _UNKNOWN          # number of bytes left in response
276*cda5da8dSAndroid Build Coastguard Worker        self.will_close = _UNKNOWN      # conn will close at end of response
277*cda5da8dSAndroid Build Coastguard Worker
278*cda5da8dSAndroid Build Coastguard Worker    def _read_status(self):
279*cda5da8dSAndroid Build Coastguard Worker        line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
280*cda5da8dSAndroid Build Coastguard Worker        if len(line) > _MAXLINE:
281*cda5da8dSAndroid Build Coastguard Worker            raise LineTooLong("status line")
282*cda5da8dSAndroid Build Coastguard Worker        if self.debuglevel > 0:
283*cda5da8dSAndroid Build Coastguard Worker            print("reply:", repr(line))
284*cda5da8dSAndroid Build Coastguard Worker        if not line:
285*cda5da8dSAndroid Build Coastguard Worker            # Presumably, the server closed the connection before
286*cda5da8dSAndroid Build Coastguard Worker            # sending a valid response.
287*cda5da8dSAndroid Build Coastguard Worker            raise RemoteDisconnected("Remote end closed connection without"
288*cda5da8dSAndroid Build Coastguard Worker                                     " response")
289*cda5da8dSAndroid Build Coastguard Worker        try:
290*cda5da8dSAndroid Build Coastguard Worker            version, status, reason = line.split(None, 2)
291*cda5da8dSAndroid Build Coastguard Worker        except ValueError:
292*cda5da8dSAndroid Build Coastguard Worker            try:
293*cda5da8dSAndroid Build Coastguard Worker                version, status = line.split(None, 1)
294*cda5da8dSAndroid Build Coastguard Worker                reason = ""
295*cda5da8dSAndroid Build Coastguard Worker            except ValueError:
296*cda5da8dSAndroid Build Coastguard Worker                # empty version will cause next test to fail.
297*cda5da8dSAndroid Build Coastguard Worker                version = ""
298*cda5da8dSAndroid Build Coastguard Worker        if not version.startswith("HTTP/"):
299*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()
300*cda5da8dSAndroid Build Coastguard Worker            raise BadStatusLine(line)
301*cda5da8dSAndroid Build Coastguard Worker
302*cda5da8dSAndroid Build Coastguard Worker        # The status code is a three-digit number
303*cda5da8dSAndroid Build Coastguard Worker        try:
304*cda5da8dSAndroid Build Coastguard Worker            status = int(status)
305*cda5da8dSAndroid Build Coastguard Worker            if status < 100 or status > 999:
306*cda5da8dSAndroid Build Coastguard Worker                raise BadStatusLine(line)
307*cda5da8dSAndroid Build Coastguard Worker        except ValueError:
308*cda5da8dSAndroid Build Coastguard Worker            raise BadStatusLine(line)
309*cda5da8dSAndroid Build Coastguard Worker        return version, status, reason
310*cda5da8dSAndroid Build Coastguard Worker
311*cda5da8dSAndroid Build Coastguard Worker    def begin(self):
312*cda5da8dSAndroid Build Coastguard Worker        if self.headers is not None:
313*cda5da8dSAndroid Build Coastguard Worker            # we've already started reading the response
314*cda5da8dSAndroid Build Coastguard Worker            return
315*cda5da8dSAndroid Build Coastguard Worker
316*cda5da8dSAndroid Build Coastguard Worker        # read until we get a non-100 response
317*cda5da8dSAndroid Build Coastguard Worker        while True:
318*cda5da8dSAndroid Build Coastguard Worker            version, status, reason = self._read_status()
319*cda5da8dSAndroid Build Coastguard Worker            if status != CONTINUE:
320*cda5da8dSAndroid Build Coastguard Worker                break
321*cda5da8dSAndroid Build Coastguard Worker            # skip the header from the 100 response
322*cda5da8dSAndroid Build Coastguard Worker            skipped_headers = _read_headers(self.fp)
323*cda5da8dSAndroid Build Coastguard Worker            if self.debuglevel > 0:
324*cda5da8dSAndroid Build Coastguard Worker                print("headers:", skipped_headers)
325*cda5da8dSAndroid Build Coastguard Worker            del skipped_headers
326*cda5da8dSAndroid Build Coastguard Worker
327*cda5da8dSAndroid Build Coastguard Worker        self.code = self.status = status
328*cda5da8dSAndroid Build Coastguard Worker        self.reason = reason.strip()
329*cda5da8dSAndroid Build Coastguard Worker        if version in ("HTTP/1.0", "HTTP/0.9"):
330*cda5da8dSAndroid Build Coastguard Worker            # Some servers might still return "0.9", treat it as 1.0 anyway
331*cda5da8dSAndroid Build Coastguard Worker            self.version = 10
332*cda5da8dSAndroid Build Coastguard Worker        elif version.startswith("HTTP/1."):
333*cda5da8dSAndroid Build Coastguard Worker            self.version = 11   # use HTTP/1.1 code for HTTP/1.x where x>=1
334*cda5da8dSAndroid Build Coastguard Worker        else:
335*cda5da8dSAndroid Build Coastguard Worker            raise UnknownProtocol(version)
336*cda5da8dSAndroid Build Coastguard Worker
337*cda5da8dSAndroid Build Coastguard Worker        self.headers = self.msg = parse_headers(self.fp)
338*cda5da8dSAndroid Build Coastguard Worker
339*cda5da8dSAndroid Build Coastguard Worker        if self.debuglevel > 0:
340*cda5da8dSAndroid Build Coastguard Worker            for hdr, val in self.headers.items():
341*cda5da8dSAndroid Build Coastguard Worker                print("header:", hdr + ":", val)
342*cda5da8dSAndroid Build Coastguard Worker
343*cda5da8dSAndroid Build Coastguard Worker        # are we using the chunked-style of transfer encoding?
344*cda5da8dSAndroid Build Coastguard Worker        tr_enc = self.headers.get("transfer-encoding")
345*cda5da8dSAndroid Build Coastguard Worker        if tr_enc and tr_enc.lower() == "chunked":
346*cda5da8dSAndroid Build Coastguard Worker            self.chunked = True
347*cda5da8dSAndroid Build Coastguard Worker            self.chunk_left = None
348*cda5da8dSAndroid Build Coastguard Worker        else:
349*cda5da8dSAndroid Build Coastguard Worker            self.chunked = False
350*cda5da8dSAndroid Build Coastguard Worker
351*cda5da8dSAndroid Build Coastguard Worker        # will the connection close at the end of the response?
352*cda5da8dSAndroid Build Coastguard Worker        self.will_close = self._check_close()
353*cda5da8dSAndroid Build Coastguard Worker
354*cda5da8dSAndroid Build Coastguard Worker        # do we have a Content-Length?
355*cda5da8dSAndroid Build Coastguard Worker        # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
356*cda5da8dSAndroid Build Coastguard Worker        self.length = None
357*cda5da8dSAndroid Build Coastguard Worker        length = self.headers.get("content-length")
358*cda5da8dSAndroid Build Coastguard Worker        if length and not self.chunked:
359*cda5da8dSAndroid Build Coastguard Worker            try:
360*cda5da8dSAndroid Build Coastguard Worker                self.length = int(length)
361*cda5da8dSAndroid Build Coastguard Worker            except ValueError:
362*cda5da8dSAndroid Build Coastguard Worker                self.length = None
363*cda5da8dSAndroid Build Coastguard Worker            else:
364*cda5da8dSAndroid Build Coastguard Worker                if self.length < 0:  # ignore nonsensical negative lengths
365*cda5da8dSAndroid Build Coastguard Worker                    self.length = None
366*cda5da8dSAndroid Build Coastguard Worker        else:
367*cda5da8dSAndroid Build Coastguard Worker            self.length = None
368*cda5da8dSAndroid Build Coastguard Worker
369*cda5da8dSAndroid Build Coastguard Worker        # does the body have a fixed length? (of zero)
370*cda5da8dSAndroid Build Coastguard Worker        if (status == NO_CONTENT or status == NOT_MODIFIED or
371*cda5da8dSAndroid Build Coastguard Worker            100 <= status < 200 or      # 1xx codes
372*cda5da8dSAndroid Build Coastguard Worker            self._method == "HEAD"):
373*cda5da8dSAndroid Build Coastguard Worker            self.length = 0
374*cda5da8dSAndroid Build Coastguard Worker
375*cda5da8dSAndroid Build Coastguard Worker        # if the connection remains open, and we aren't using chunked, and
376*cda5da8dSAndroid Build Coastguard Worker        # a content-length was not provided, then assume that the connection
377*cda5da8dSAndroid Build Coastguard Worker        # WILL close.
378*cda5da8dSAndroid Build Coastguard Worker        if (not self.will_close and
379*cda5da8dSAndroid Build Coastguard Worker            not self.chunked and
380*cda5da8dSAndroid Build Coastguard Worker            self.length is None):
381*cda5da8dSAndroid Build Coastguard Worker            self.will_close = True
382*cda5da8dSAndroid Build Coastguard Worker
383*cda5da8dSAndroid Build Coastguard Worker    def _check_close(self):
384*cda5da8dSAndroid Build Coastguard Worker        conn = self.headers.get("connection")
385*cda5da8dSAndroid Build Coastguard Worker        if self.version == 11:
386*cda5da8dSAndroid Build Coastguard Worker            # An HTTP/1.1 proxy is assumed to stay open unless
387*cda5da8dSAndroid Build Coastguard Worker            # explicitly closed.
388*cda5da8dSAndroid Build Coastguard Worker            if conn and "close" in conn.lower():
389*cda5da8dSAndroid Build Coastguard Worker                return True
390*cda5da8dSAndroid Build Coastguard Worker            return False
391*cda5da8dSAndroid Build Coastguard Worker
392*cda5da8dSAndroid Build Coastguard Worker        # Some HTTP/1.0 implementations have support for persistent
393*cda5da8dSAndroid Build Coastguard Worker        # connections, using rules different than HTTP/1.1.
394*cda5da8dSAndroid Build Coastguard Worker
395*cda5da8dSAndroid Build Coastguard Worker        # For older HTTP, Keep-Alive indicates persistent connection.
396*cda5da8dSAndroid Build Coastguard Worker        if self.headers.get("keep-alive"):
397*cda5da8dSAndroid Build Coastguard Worker            return False
398*cda5da8dSAndroid Build Coastguard Worker
399*cda5da8dSAndroid Build Coastguard Worker        # At least Akamai returns a "Connection: Keep-Alive" header,
400*cda5da8dSAndroid Build Coastguard Worker        # which was supposed to be sent by the client.
401*cda5da8dSAndroid Build Coastguard Worker        if conn and "keep-alive" in conn.lower():
402*cda5da8dSAndroid Build Coastguard Worker            return False
403*cda5da8dSAndroid Build Coastguard Worker
404*cda5da8dSAndroid Build Coastguard Worker        # Proxy-Connection is a netscape hack.
405*cda5da8dSAndroid Build Coastguard Worker        pconn = self.headers.get("proxy-connection")
406*cda5da8dSAndroid Build Coastguard Worker        if pconn and "keep-alive" in pconn.lower():
407*cda5da8dSAndroid Build Coastguard Worker            return False
408*cda5da8dSAndroid Build Coastguard Worker
409*cda5da8dSAndroid Build Coastguard Worker        # otherwise, assume it will close
410*cda5da8dSAndroid Build Coastguard Worker        return True
411*cda5da8dSAndroid Build Coastguard Worker
412*cda5da8dSAndroid Build Coastguard Worker    def _close_conn(self):
413*cda5da8dSAndroid Build Coastguard Worker        fp = self.fp
414*cda5da8dSAndroid Build Coastguard Worker        self.fp = None
415*cda5da8dSAndroid Build Coastguard Worker        fp.close()
416*cda5da8dSAndroid Build Coastguard Worker
417*cda5da8dSAndroid Build Coastguard Worker    def close(self):
418*cda5da8dSAndroid Build Coastguard Worker        try:
419*cda5da8dSAndroid Build Coastguard Worker            super().close() # set "closed" flag
420*cda5da8dSAndroid Build Coastguard Worker        finally:
421*cda5da8dSAndroid Build Coastguard Worker            if self.fp:
422*cda5da8dSAndroid Build Coastguard Worker                self._close_conn()
423*cda5da8dSAndroid Build Coastguard Worker
424*cda5da8dSAndroid Build Coastguard Worker    # These implementations are for the benefit of io.BufferedReader.
425*cda5da8dSAndroid Build Coastguard Worker
426*cda5da8dSAndroid Build Coastguard Worker    # XXX This class should probably be revised to act more like
427*cda5da8dSAndroid Build Coastguard Worker    # the "raw stream" that BufferedReader expects.
428*cda5da8dSAndroid Build Coastguard Worker
429*cda5da8dSAndroid Build Coastguard Worker    def flush(self):
430*cda5da8dSAndroid Build Coastguard Worker        super().flush()
431*cda5da8dSAndroid Build Coastguard Worker        if self.fp:
432*cda5da8dSAndroid Build Coastguard Worker            self.fp.flush()
433*cda5da8dSAndroid Build Coastguard Worker
434*cda5da8dSAndroid Build Coastguard Worker    def readable(self):
435*cda5da8dSAndroid Build Coastguard Worker        """Always returns True"""
436*cda5da8dSAndroid Build Coastguard Worker        return True
437*cda5da8dSAndroid Build Coastguard Worker
438*cda5da8dSAndroid Build Coastguard Worker    # End of "raw stream" methods
439*cda5da8dSAndroid Build Coastguard Worker
440*cda5da8dSAndroid Build Coastguard Worker    def isclosed(self):
441*cda5da8dSAndroid Build Coastguard Worker        """True if the connection is closed."""
442*cda5da8dSAndroid Build Coastguard Worker        # NOTE: it is possible that we will not ever call self.close(). This
443*cda5da8dSAndroid Build Coastguard Worker        #       case occurs when will_close is TRUE, length is None, and we
444*cda5da8dSAndroid Build Coastguard Worker        #       read up to the last byte, but NOT past it.
445*cda5da8dSAndroid Build Coastguard Worker        #
446*cda5da8dSAndroid Build Coastguard Worker        # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
447*cda5da8dSAndroid Build Coastguard Worker        #          called, meaning self.isclosed() is meaningful.
448*cda5da8dSAndroid Build Coastguard Worker        return self.fp is None
449*cda5da8dSAndroid Build Coastguard Worker
450*cda5da8dSAndroid Build Coastguard Worker    def read(self, amt=None):
451*cda5da8dSAndroid Build Coastguard Worker        """Read and return the response body, or up to the next amt bytes."""
452*cda5da8dSAndroid Build Coastguard Worker        if self.fp is None:
453*cda5da8dSAndroid Build Coastguard Worker            return b""
454*cda5da8dSAndroid Build Coastguard Worker
455*cda5da8dSAndroid Build Coastguard Worker        if self._method == "HEAD":
456*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()
457*cda5da8dSAndroid Build Coastguard Worker            return b""
458*cda5da8dSAndroid Build Coastguard Worker
459*cda5da8dSAndroid Build Coastguard Worker        if self.chunked:
460*cda5da8dSAndroid Build Coastguard Worker            return self._read_chunked(amt)
461*cda5da8dSAndroid Build Coastguard Worker
462*cda5da8dSAndroid Build Coastguard Worker        if amt is not None:
463*cda5da8dSAndroid Build Coastguard Worker            if self.length is not None and amt > self.length:
464*cda5da8dSAndroid Build Coastguard Worker                # clip the read to the "end of response"
465*cda5da8dSAndroid Build Coastguard Worker                amt = self.length
466*cda5da8dSAndroid Build Coastguard Worker            s = self.fp.read(amt)
467*cda5da8dSAndroid Build Coastguard Worker            if not s and amt:
468*cda5da8dSAndroid Build Coastguard Worker                # Ideally, we would raise IncompleteRead if the content-length
469*cda5da8dSAndroid Build Coastguard Worker                # wasn't satisfied, but it might break compatibility.
470*cda5da8dSAndroid Build Coastguard Worker                self._close_conn()
471*cda5da8dSAndroid Build Coastguard Worker            elif self.length is not None:
472*cda5da8dSAndroid Build Coastguard Worker                self.length -= len(s)
473*cda5da8dSAndroid Build Coastguard Worker                if not self.length:
474*cda5da8dSAndroid Build Coastguard Worker                    self._close_conn()
475*cda5da8dSAndroid Build Coastguard Worker            return s
476*cda5da8dSAndroid Build Coastguard Worker        else:
477*cda5da8dSAndroid Build Coastguard Worker            # Amount is not given (unbounded read) so we must check self.length
478*cda5da8dSAndroid Build Coastguard Worker            if self.length is None:
479*cda5da8dSAndroid Build Coastguard Worker                s = self.fp.read()
480*cda5da8dSAndroid Build Coastguard Worker            else:
481*cda5da8dSAndroid Build Coastguard Worker                try:
482*cda5da8dSAndroid Build Coastguard Worker                    s = self._safe_read(self.length)
483*cda5da8dSAndroid Build Coastguard Worker                except IncompleteRead:
484*cda5da8dSAndroid Build Coastguard Worker                    self._close_conn()
485*cda5da8dSAndroid Build Coastguard Worker                    raise
486*cda5da8dSAndroid Build Coastguard Worker                self.length = 0
487*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()        # we read everything
488*cda5da8dSAndroid Build Coastguard Worker            return s
489*cda5da8dSAndroid Build Coastguard Worker
490*cda5da8dSAndroid Build Coastguard Worker    def readinto(self, b):
491*cda5da8dSAndroid Build Coastguard Worker        """Read up to len(b) bytes into bytearray b and return the number
492*cda5da8dSAndroid Build Coastguard Worker        of bytes read.
493*cda5da8dSAndroid Build Coastguard Worker        """
494*cda5da8dSAndroid Build Coastguard Worker
495*cda5da8dSAndroid Build Coastguard Worker        if self.fp is None:
496*cda5da8dSAndroid Build Coastguard Worker            return 0
497*cda5da8dSAndroid Build Coastguard Worker
498*cda5da8dSAndroid Build Coastguard Worker        if self._method == "HEAD":
499*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()
500*cda5da8dSAndroid Build Coastguard Worker            return 0
501*cda5da8dSAndroid Build Coastguard Worker
502*cda5da8dSAndroid Build Coastguard Worker        if self.chunked:
503*cda5da8dSAndroid Build Coastguard Worker            return self._readinto_chunked(b)
504*cda5da8dSAndroid Build Coastguard Worker
505*cda5da8dSAndroid Build Coastguard Worker        if self.length is not None:
506*cda5da8dSAndroid Build Coastguard Worker            if len(b) > self.length:
507*cda5da8dSAndroid Build Coastguard Worker                # clip the read to the "end of response"
508*cda5da8dSAndroid Build Coastguard Worker                b = memoryview(b)[0:self.length]
509*cda5da8dSAndroid Build Coastguard Worker
510*cda5da8dSAndroid Build Coastguard Worker        # we do not use _safe_read() here because this may be a .will_close
511*cda5da8dSAndroid Build Coastguard Worker        # connection, and the user is reading more bytes than will be provided
512*cda5da8dSAndroid Build Coastguard Worker        # (for example, reading in 1k chunks)
513*cda5da8dSAndroid Build Coastguard Worker        n = self.fp.readinto(b)
514*cda5da8dSAndroid Build Coastguard Worker        if not n and b:
515*cda5da8dSAndroid Build Coastguard Worker            # Ideally, we would raise IncompleteRead if the content-length
516*cda5da8dSAndroid Build Coastguard Worker            # wasn't satisfied, but it might break compatibility.
517*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()
518*cda5da8dSAndroid Build Coastguard Worker        elif self.length is not None:
519*cda5da8dSAndroid Build Coastguard Worker            self.length -= n
520*cda5da8dSAndroid Build Coastguard Worker            if not self.length:
521*cda5da8dSAndroid Build Coastguard Worker                self._close_conn()
522*cda5da8dSAndroid Build Coastguard Worker        return n
523*cda5da8dSAndroid Build Coastguard Worker
524*cda5da8dSAndroid Build Coastguard Worker    def _read_next_chunk_size(self):
525*cda5da8dSAndroid Build Coastguard Worker        # Read the next chunk size from the file
526*cda5da8dSAndroid Build Coastguard Worker        line = self.fp.readline(_MAXLINE + 1)
527*cda5da8dSAndroid Build Coastguard Worker        if len(line) > _MAXLINE:
528*cda5da8dSAndroid Build Coastguard Worker            raise LineTooLong("chunk size")
529*cda5da8dSAndroid Build Coastguard Worker        i = line.find(b";")
530*cda5da8dSAndroid Build Coastguard Worker        if i >= 0:
531*cda5da8dSAndroid Build Coastguard Worker            line = line[:i] # strip chunk-extensions
532*cda5da8dSAndroid Build Coastguard Worker        try:
533*cda5da8dSAndroid Build Coastguard Worker            return int(line, 16)
534*cda5da8dSAndroid Build Coastguard Worker        except ValueError:
535*cda5da8dSAndroid Build Coastguard Worker            # close the connection as protocol synchronisation is
536*cda5da8dSAndroid Build Coastguard Worker            # probably lost
537*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()
538*cda5da8dSAndroid Build Coastguard Worker            raise
539*cda5da8dSAndroid Build Coastguard Worker
540*cda5da8dSAndroid Build Coastguard Worker    def _read_and_discard_trailer(self):
541*cda5da8dSAndroid Build Coastguard Worker        # read and discard trailer up to the CRLF terminator
542*cda5da8dSAndroid Build Coastguard Worker        ### note: we shouldn't have any trailers!
543*cda5da8dSAndroid Build Coastguard Worker        while True:
544*cda5da8dSAndroid Build Coastguard Worker            line = self.fp.readline(_MAXLINE + 1)
545*cda5da8dSAndroid Build Coastguard Worker            if len(line) > _MAXLINE:
546*cda5da8dSAndroid Build Coastguard Worker                raise LineTooLong("trailer line")
547*cda5da8dSAndroid Build Coastguard Worker            if not line:
548*cda5da8dSAndroid Build Coastguard Worker                # a vanishingly small number of sites EOF without
549*cda5da8dSAndroid Build Coastguard Worker                # sending the trailer
550*cda5da8dSAndroid Build Coastguard Worker                break
551*cda5da8dSAndroid Build Coastguard Worker            if line in (b'\r\n', b'\n', b''):
552*cda5da8dSAndroid Build Coastguard Worker                break
553*cda5da8dSAndroid Build Coastguard Worker
554*cda5da8dSAndroid Build Coastguard Worker    def _get_chunk_left(self):
555*cda5da8dSAndroid Build Coastguard Worker        # return self.chunk_left, reading a new chunk if necessary.
556*cda5da8dSAndroid Build Coastguard Worker        # chunk_left == 0: at the end of the current chunk, need to close it
557*cda5da8dSAndroid Build Coastguard Worker        # chunk_left == None: No current chunk, should read next.
558*cda5da8dSAndroid Build Coastguard Worker        # This function returns non-zero or None if the last chunk has
559*cda5da8dSAndroid Build Coastguard Worker        # been read.
560*cda5da8dSAndroid Build Coastguard Worker        chunk_left = self.chunk_left
561*cda5da8dSAndroid Build Coastguard Worker        if not chunk_left: # Can be 0 or None
562*cda5da8dSAndroid Build Coastguard Worker            if chunk_left is not None:
563*cda5da8dSAndroid Build Coastguard Worker                # We are at the end of chunk, discard chunk end
564*cda5da8dSAndroid Build Coastguard Worker                self._safe_read(2)  # toss the CRLF at the end of the chunk
565*cda5da8dSAndroid Build Coastguard Worker            try:
566*cda5da8dSAndroid Build Coastguard Worker                chunk_left = self._read_next_chunk_size()
567*cda5da8dSAndroid Build Coastguard Worker            except ValueError:
568*cda5da8dSAndroid Build Coastguard Worker                raise IncompleteRead(b'')
569*cda5da8dSAndroid Build Coastguard Worker            if chunk_left == 0:
570*cda5da8dSAndroid Build Coastguard Worker                # last chunk: 1*("0") [ chunk-extension ] CRLF
571*cda5da8dSAndroid Build Coastguard Worker                self._read_and_discard_trailer()
572*cda5da8dSAndroid Build Coastguard Worker                # we read everything; close the "file"
573*cda5da8dSAndroid Build Coastguard Worker                self._close_conn()
574*cda5da8dSAndroid Build Coastguard Worker                chunk_left = None
575*cda5da8dSAndroid Build Coastguard Worker            self.chunk_left = chunk_left
576*cda5da8dSAndroid Build Coastguard Worker        return chunk_left
577*cda5da8dSAndroid Build Coastguard Worker
578*cda5da8dSAndroid Build Coastguard Worker    def _read_chunked(self, amt=None):
579*cda5da8dSAndroid Build Coastguard Worker        assert self.chunked != _UNKNOWN
580*cda5da8dSAndroid Build Coastguard Worker        value = []
581*cda5da8dSAndroid Build Coastguard Worker        try:
582*cda5da8dSAndroid Build Coastguard Worker            while True:
583*cda5da8dSAndroid Build Coastguard Worker                chunk_left = self._get_chunk_left()
584*cda5da8dSAndroid Build Coastguard Worker                if chunk_left is None:
585*cda5da8dSAndroid Build Coastguard Worker                    break
586*cda5da8dSAndroid Build Coastguard Worker
587*cda5da8dSAndroid Build Coastguard Worker                if amt is not None and amt <= chunk_left:
588*cda5da8dSAndroid Build Coastguard Worker                    value.append(self._safe_read(amt))
589*cda5da8dSAndroid Build Coastguard Worker                    self.chunk_left = chunk_left - amt
590*cda5da8dSAndroid Build Coastguard Worker                    break
591*cda5da8dSAndroid Build Coastguard Worker
592*cda5da8dSAndroid Build Coastguard Worker                value.append(self._safe_read(chunk_left))
593*cda5da8dSAndroid Build Coastguard Worker                if amt is not None:
594*cda5da8dSAndroid Build Coastguard Worker                    amt -= chunk_left
595*cda5da8dSAndroid Build Coastguard Worker                self.chunk_left = 0
596*cda5da8dSAndroid Build Coastguard Worker            return b''.join(value)
597*cda5da8dSAndroid Build Coastguard Worker        except IncompleteRead as exc:
598*cda5da8dSAndroid Build Coastguard Worker            raise IncompleteRead(b''.join(value)) from exc
599*cda5da8dSAndroid Build Coastguard Worker
600*cda5da8dSAndroid Build Coastguard Worker    def _readinto_chunked(self, b):
601*cda5da8dSAndroid Build Coastguard Worker        assert self.chunked != _UNKNOWN
602*cda5da8dSAndroid Build Coastguard Worker        total_bytes = 0
603*cda5da8dSAndroid Build Coastguard Worker        mvb = memoryview(b)
604*cda5da8dSAndroid Build Coastguard Worker        try:
605*cda5da8dSAndroid Build Coastguard Worker            while True:
606*cda5da8dSAndroid Build Coastguard Worker                chunk_left = self._get_chunk_left()
607*cda5da8dSAndroid Build Coastguard Worker                if chunk_left is None:
608*cda5da8dSAndroid Build Coastguard Worker                    return total_bytes
609*cda5da8dSAndroid Build Coastguard Worker
610*cda5da8dSAndroid Build Coastguard Worker                if len(mvb) <= chunk_left:
611*cda5da8dSAndroid Build Coastguard Worker                    n = self._safe_readinto(mvb)
612*cda5da8dSAndroid Build Coastguard Worker                    self.chunk_left = chunk_left - n
613*cda5da8dSAndroid Build Coastguard Worker                    return total_bytes + n
614*cda5da8dSAndroid Build Coastguard Worker
615*cda5da8dSAndroid Build Coastguard Worker                temp_mvb = mvb[:chunk_left]
616*cda5da8dSAndroid Build Coastguard Worker                n = self._safe_readinto(temp_mvb)
617*cda5da8dSAndroid Build Coastguard Worker                mvb = mvb[n:]
618*cda5da8dSAndroid Build Coastguard Worker                total_bytes += n
619*cda5da8dSAndroid Build Coastguard Worker                self.chunk_left = 0
620*cda5da8dSAndroid Build Coastguard Worker
621*cda5da8dSAndroid Build Coastguard Worker        except IncompleteRead:
622*cda5da8dSAndroid Build Coastguard Worker            raise IncompleteRead(bytes(b[0:total_bytes]))
623*cda5da8dSAndroid Build Coastguard Worker
624*cda5da8dSAndroid Build Coastguard Worker    def _safe_read(self, amt):
625*cda5da8dSAndroid Build Coastguard Worker        """Read the number of bytes requested.
626*cda5da8dSAndroid Build Coastguard Worker
627*cda5da8dSAndroid Build Coastguard Worker        This function should be used when <amt> bytes "should" be present for
628*cda5da8dSAndroid Build Coastguard Worker        reading. If the bytes are truly not available (due to EOF), then the
629*cda5da8dSAndroid Build Coastguard Worker        IncompleteRead exception can be used to detect the problem.
630*cda5da8dSAndroid Build Coastguard Worker        """
631*cda5da8dSAndroid Build Coastguard Worker        data = self.fp.read(amt)
632*cda5da8dSAndroid Build Coastguard Worker        if len(data) < amt:
633*cda5da8dSAndroid Build Coastguard Worker            raise IncompleteRead(data, amt-len(data))
634*cda5da8dSAndroid Build Coastguard Worker        return data
635*cda5da8dSAndroid Build Coastguard Worker
636*cda5da8dSAndroid Build Coastguard Worker    def _safe_readinto(self, b):
637*cda5da8dSAndroid Build Coastguard Worker        """Same as _safe_read, but for reading into a buffer."""
638*cda5da8dSAndroid Build Coastguard Worker        amt = len(b)
639*cda5da8dSAndroid Build Coastguard Worker        n = self.fp.readinto(b)
640*cda5da8dSAndroid Build Coastguard Worker        if n < amt:
641*cda5da8dSAndroid Build Coastguard Worker            raise IncompleteRead(bytes(b[:n]), amt-n)
642*cda5da8dSAndroid Build Coastguard Worker        return n
643*cda5da8dSAndroid Build Coastguard Worker
644*cda5da8dSAndroid Build Coastguard Worker    def read1(self, n=-1):
645*cda5da8dSAndroid Build Coastguard Worker        """Read with at most one underlying system call.  If at least one
646*cda5da8dSAndroid Build Coastguard Worker        byte is buffered, return that instead.
647*cda5da8dSAndroid Build Coastguard Worker        """
648*cda5da8dSAndroid Build Coastguard Worker        if self.fp is None or self._method == "HEAD":
649*cda5da8dSAndroid Build Coastguard Worker            return b""
650*cda5da8dSAndroid Build Coastguard Worker        if self.chunked:
651*cda5da8dSAndroid Build Coastguard Worker            return self._read1_chunked(n)
652*cda5da8dSAndroid Build Coastguard Worker        if self.length is not None and (n < 0 or n > self.length):
653*cda5da8dSAndroid Build Coastguard Worker            n = self.length
654*cda5da8dSAndroid Build Coastguard Worker        result = self.fp.read1(n)
655*cda5da8dSAndroid Build Coastguard Worker        if not result and n:
656*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()
657*cda5da8dSAndroid Build Coastguard Worker        elif self.length is not None:
658*cda5da8dSAndroid Build Coastguard Worker            self.length -= len(result)
659*cda5da8dSAndroid Build Coastguard Worker        return result
660*cda5da8dSAndroid Build Coastguard Worker
661*cda5da8dSAndroid Build Coastguard Worker    def peek(self, n=-1):
662*cda5da8dSAndroid Build Coastguard Worker        # Having this enables IOBase.readline() to read more than one
663*cda5da8dSAndroid Build Coastguard Worker        # byte at a time
664*cda5da8dSAndroid Build Coastguard Worker        if self.fp is None or self._method == "HEAD":
665*cda5da8dSAndroid Build Coastguard Worker            return b""
666*cda5da8dSAndroid Build Coastguard Worker        if self.chunked:
667*cda5da8dSAndroid Build Coastguard Worker            return self._peek_chunked(n)
668*cda5da8dSAndroid Build Coastguard Worker        return self.fp.peek(n)
669*cda5da8dSAndroid Build Coastguard Worker
670*cda5da8dSAndroid Build Coastguard Worker    def readline(self, limit=-1):
671*cda5da8dSAndroid Build Coastguard Worker        if self.fp is None or self._method == "HEAD":
672*cda5da8dSAndroid Build Coastguard Worker            return b""
673*cda5da8dSAndroid Build Coastguard Worker        if self.chunked:
674*cda5da8dSAndroid Build Coastguard Worker            # Fallback to IOBase readline which uses peek() and read()
675*cda5da8dSAndroid Build Coastguard Worker            return super().readline(limit)
676*cda5da8dSAndroid Build Coastguard Worker        if self.length is not None and (limit < 0 or limit > self.length):
677*cda5da8dSAndroid Build Coastguard Worker            limit = self.length
678*cda5da8dSAndroid Build Coastguard Worker        result = self.fp.readline(limit)
679*cda5da8dSAndroid Build Coastguard Worker        if not result and limit:
680*cda5da8dSAndroid Build Coastguard Worker            self._close_conn()
681*cda5da8dSAndroid Build Coastguard Worker        elif self.length is not None:
682*cda5da8dSAndroid Build Coastguard Worker            self.length -= len(result)
683*cda5da8dSAndroid Build Coastguard Worker        return result
684*cda5da8dSAndroid Build Coastguard Worker
685*cda5da8dSAndroid Build Coastguard Worker    def _read1_chunked(self, n):
686*cda5da8dSAndroid Build Coastguard Worker        # Strictly speaking, _get_chunk_left() may cause more than one read,
687*cda5da8dSAndroid Build Coastguard Worker        # but that is ok, since that is to satisfy the chunked protocol.
688*cda5da8dSAndroid Build Coastguard Worker        chunk_left = self._get_chunk_left()
689*cda5da8dSAndroid Build Coastguard Worker        if chunk_left is None or n == 0:
690*cda5da8dSAndroid Build Coastguard Worker            return b''
691*cda5da8dSAndroid Build Coastguard Worker        if not (0 <= n <= chunk_left):
692*cda5da8dSAndroid Build Coastguard Worker            n = chunk_left # if n is negative or larger than chunk_left
693*cda5da8dSAndroid Build Coastguard Worker        read = self.fp.read1(n)
694*cda5da8dSAndroid Build Coastguard Worker        self.chunk_left -= len(read)
695*cda5da8dSAndroid Build Coastguard Worker        if not read:
696*cda5da8dSAndroid Build Coastguard Worker            raise IncompleteRead(b"")
697*cda5da8dSAndroid Build Coastguard Worker        return read
698*cda5da8dSAndroid Build Coastguard Worker
699*cda5da8dSAndroid Build Coastguard Worker    def _peek_chunked(self, n):
700*cda5da8dSAndroid Build Coastguard Worker        # Strictly speaking, _get_chunk_left() may cause more than one read,
701*cda5da8dSAndroid Build Coastguard Worker        # but that is ok, since that is to satisfy the chunked protocol.
702*cda5da8dSAndroid Build Coastguard Worker        try:
703*cda5da8dSAndroid Build Coastguard Worker            chunk_left = self._get_chunk_left()
704*cda5da8dSAndroid Build Coastguard Worker        except IncompleteRead:
705*cda5da8dSAndroid Build Coastguard Worker            return b'' # peek doesn't worry about protocol
706*cda5da8dSAndroid Build Coastguard Worker        if chunk_left is None:
707*cda5da8dSAndroid Build Coastguard Worker            return b'' # eof
708*cda5da8dSAndroid Build Coastguard Worker        # peek is allowed to return more than requested.  Just request the
709*cda5da8dSAndroid Build Coastguard Worker        # entire chunk, and truncate what we get.
710*cda5da8dSAndroid Build Coastguard Worker        return self.fp.peek(chunk_left)[:chunk_left]
711*cda5da8dSAndroid Build Coastguard Worker
712*cda5da8dSAndroid Build Coastguard Worker    def fileno(self):
713*cda5da8dSAndroid Build Coastguard Worker        return self.fp.fileno()
714*cda5da8dSAndroid Build Coastguard Worker
715*cda5da8dSAndroid Build Coastguard Worker    def getheader(self, name, default=None):
716*cda5da8dSAndroid Build Coastguard Worker        '''Returns the value of the header matching *name*.
717*cda5da8dSAndroid Build Coastguard Worker
718*cda5da8dSAndroid Build Coastguard Worker        If there are multiple matching headers, the values are
719*cda5da8dSAndroid Build Coastguard Worker        combined into a single string separated by commas and spaces.
720*cda5da8dSAndroid Build Coastguard Worker
721*cda5da8dSAndroid Build Coastguard Worker        If no matching header is found, returns *default* or None if
722*cda5da8dSAndroid Build Coastguard Worker        the *default* is not specified.
723*cda5da8dSAndroid Build Coastguard Worker
724*cda5da8dSAndroid Build Coastguard Worker        If the headers are unknown, raises http.client.ResponseNotReady.
725*cda5da8dSAndroid Build Coastguard Worker
726*cda5da8dSAndroid Build Coastguard Worker        '''
727*cda5da8dSAndroid Build Coastguard Worker        if self.headers is None:
728*cda5da8dSAndroid Build Coastguard Worker            raise ResponseNotReady()
729*cda5da8dSAndroid Build Coastguard Worker        headers = self.headers.get_all(name) or default
730*cda5da8dSAndroid Build Coastguard Worker        if isinstance(headers, str) or not hasattr(headers, '__iter__'):
731*cda5da8dSAndroid Build Coastguard Worker            return headers
732*cda5da8dSAndroid Build Coastguard Worker        else:
733*cda5da8dSAndroid Build Coastguard Worker            return ', '.join(headers)
734*cda5da8dSAndroid Build Coastguard Worker
735*cda5da8dSAndroid Build Coastguard Worker    def getheaders(self):
736*cda5da8dSAndroid Build Coastguard Worker        """Return list of (header, value) tuples."""
737*cda5da8dSAndroid Build Coastguard Worker        if self.headers is None:
738*cda5da8dSAndroid Build Coastguard Worker            raise ResponseNotReady()
739*cda5da8dSAndroid Build Coastguard Worker        return list(self.headers.items())
740*cda5da8dSAndroid Build Coastguard Worker
741*cda5da8dSAndroid Build Coastguard Worker    # We override IOBase.__iter__ so that it doesn't check for closed-ness
742*cda5da8dSAndroid Build Coastguard Worker
743*cda5da8dSAndroid Build Coastguard Worker    def __iter__(self):
744*cda5da8dSAndroid Build Coastguard Worker        return self
745*cda5da8dSAndroid Build Coastguard Worker
746*cda5da8dSAndroid Build Coastguard Worker    # For compatibility with old-style urllib responses.
747*cda5da8dSAndroid Build Coastguard Worker
748*cda5da8dSAndroid Build Coastguard Worker    def info(self):
749*cda5da8dSAndroid Build Coastguard Worker        '''Returns an instance of the class mimetools.Message containing
750*cda5da8dSAndroid Build Coastguard Worker        meta-information associated with the URL.
751*cda5da8dSAndroid Build Coastguard Worker
752*cda5da8dSAndroid Build Coastguard Worker        When the method is HTTP, these headers are those returned by
753*cda5da8dSAndroid Build Coastguard Worker        the server at the head of the retrieved HTML page (including
754*cda5da8dSAndroid Build Coastguard Worker        Content-Length and Content-Type).
755*cda5da8dSAndroid Build Coastguard Worker
756*cda5da8dSAndroid Build Coastguard Worker        When the method is FTP, a Content-Length header will be
757*cda5da8dSAndroid Build Coastguard Worker        present if (as is now usual) the server passed back a file
758*cda5da8dSAndroid Build Coastguard Worker        length in response to the FTP retrieval request. A
759*cda5da8dSAndroid Build Coastguard Worker        Content-Type header will be present if the MIME type can be
760*cda5da8dSAndroid Build Coastguard Worker        guessed.
761*cda5da8dSAndroid Build Coastguard Worker
762*cda5da8dSAndroid Build Coastguard Worker        When the method is local-file, returned headers will include
763*cda5da8dSAndroid Build Coastguard Worker        a Date representing the file's last-modified time, a
764*cda5da8dSAndroid Build Coastguard Worker        Content-Length giving file size, and a Content-Type
765*cda5da8dSAndroid Build Coastguard Worker        containing a guess at the file's type. See also the
766*cda5da8dSAndroid Build Coastguard Worker        description of the mimetools module.
767*cda5da8dSAndroid Build Coastguard Worker
768*cda5da8dSAndroid Build Coastguard Worker        '''
769*cda5da8dSAndroid Build Coastguard Worker        return self.headers
770*cda5da8dSAndroid Build Coastguard Worker
771*cda5da8dSAndroid Build Coastguard Worker    def geturl(self):
772*cda5da8dSAndroid Build Coastguard Worker        '''Return the real URL of the page.
773*cda5da8dSAndroid Build Coastguard Worker
774*cda5da8dSAndroid Build Coastguard Worker        In some cases, the HTTP server redirects a client to another
775*cda5da8dSAndroid Build Coastguard Worker        URL. The urlopen() function handles this transparently, but in
776*cda5da8dSAndroid Build Coastguard Worker        some cases the caller needs to know which URL the client was
777*cda5da8dSAndroid Build Coastguard Worker        redirected to. The geturl() method can be used to get at this
778*cda5da8dSAndroid Build Coastguard Worker        redirected URL.
779*cda5da8dSAndroid Build Coastguard Worker
780*cda5da8dSAndroid Build Coastguard Worker        '''
781*cda5da8dSAndroid Build Coastguard Worker        return self.url
782*cda5da8dSAndroid Build Coastguard Worker
783*cda5da8dSAndroid Build Coastguard Worker    def getcode(self):
784*cda5da8dSAndroid Build Coastguard Worker        '''Return the HTTP status code that was sent with the response,
785*cda5da8dSAndroid Build Coastguard Worker        or None if the URL is not an HTTP URL.
786*cda5da8dSAndroid Build Coastguard Worker
787*cda5da8dSAndroid Build Coastguard Worker        '''
788*cda5da8dSAndroid Build Coastguard Worker        return self.status
789*cda5da8dSAndroid Build Coastguard Worker
790*cda5da8dSAndroid Build Coastguard Workerclass HTTPConnection:
791*cda5da8dSAndroid Build Coastguard Worker
792*cda5da8dSAndroid Build Coastguard Worker    _http_vsn = 11
793*cda5da8dSAndroid Build Coastguard Worker    _http_vsn_str = 'HTTP/1.1'
794*cda5da8dSAndroid Build Coastguard Worker
795*cda5da8dSAndroid Build Coastguard Worker    response_class = HTTPResponse
796*cda5da8dSAndroid Build Coastguard Worker    default_port = HTTP_PORT
797*cda5da8dSAndroid Build Coastguard Worker    auto_open = 1
798*cda5da8dSAndroid Build Coastguard Worker    debuglevel = 0
799*cda5da8dSAndroid Build Coastguard Worker
800*cda5da8dSAndroid Build Coastguard Worker    @staticmethod
801*cda5da8dSAndroid Build Coastguard Worker    def _is_textIO(stream):
802*cda5da8dSAndroid Build Coastguard Worker        """Test whether a file-like object is a text or a binary stream.
803*cda5da8dSAndroid Build Coastguard Worker        """
804*cda5da8dSAndroid Build Coastguard Worker        return isinstance(stream, io.TextIOBase)
805*cda5da8dSAndroid Build Coastguard Worker
806*cda5da8dSAndroid Build Coastguard Worker    @staticmethod
807*cda5da8dSAndroid Build Coastguard Worker    def _get_content_length(body, method):
808*cda5da8dSAndroid Build Coastguard Worker        """Get the content-length based on the body.
809*cda5da8dSAndroid Build Coastguard Worker
810*cda5da8dSAndroid Build Coastguard Worker        If the body is None, we set Content-Length: 0 for methods that expect
811*cda5da8dSAndroid Build Coastguard Worker        a body (RFC 7230, Section 3.3.2). We also set the Content-Length for
812*cda5da8dSAndroid Build Coastguard Worker        any method if the body is a str or bytes-like object and not a file.
813*cda5da8dSAndroid Build Coastguard Worker        """
814*cda5da8dSAndroid Build Coastguard Worker        if body is None:
815*cda5da8dSAndroid Build Coastguard Worker            # do an explicit check for not None here to distinguish
816*cda5da8dSAndroid Build Coastguard Worker            # between unset and set but empty
817*cda5da8dSAndroid Build Coastguard Worker            if method.upper() in _METHODS_EXPECTING_BODY:
818*cda5da8dSAndroid Build Coastguard Worker                return 0
819*cda5da8dSAndroid Build Coastguard Worker            else:
820*cda5da8dSAndroid Build Coastguard Worker                return None
821*cda5da8dSAndroid Build Coastguard Worker
822*cda5da8dSAndroid Build Coastguard Worker        if hasattr(body, 'read'):
823*cda5da8dSAndroid Build Coastguard Worker            # file-like object.
824*cda5da8dSAndroid Build Coastguard Worker            return None
825*cda5da8dSAndroid Build Coastguard Worker
826*cda5da8dSAndroid Build Coastguard Worker        try:
827*cda5da8dSAndroid Build Coastguard Worker            # does it implement the buffer protocol (bytes, bytearray, array)?
828*cda5da8dSAndroid Build Coastguard Worker            mv = memoryview(body)
829*cda5da8dSAndroid Build Coastguard Worker            return mv.nbytes
830*cda5da8dSAndroid Build Coastguard Worker        except TypeError:
831*cda5da8dSAndroid Build Coastguard Worker            pass
832*cda5da8dSAndroid Build Coastguard Worker
833*cda5da8dSAndroid Build Coastguard Worker        if isinstance(body, str):
834*cda5da8dSAndroid Build Coastguard Worker            return len(body)
835*cda5da8dSAndroid Build Coastguard Worker
836*cda5da8dSAndroid Build Coastguard Worker        return None
837*cda5da8dSAndroid Build Coastguard Worker
838*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
839*cda5da8dSAndroid Build Coastguard Worker                 source_address=None, blocksize=8192):
840*cda5da8dSAndroid Build Coastguard Worker        self.timeout = timeout
841*cda5da8dSAndroid Build Coastguard Worker        self.source_address = source_address
842*cda5da8dSAndroid Build Coastguard Worker        self.blocksize = blocksize
843*cda5da8dSAndroid Build Coastguard Worker        self.sock = None
844*cda5da8dSAndroid Build Coastguard Worker        self._buffer = []
845*cda5da8dSAndroid Build Coastguard Worker        self.__response = None
846*cda5da8dSAndroid Build Coastguard Worker        self.__state = _CS_IDLE
847*cda5da8dSAndroid Build Coastguard Worker        self._method = None
848*cda5da8dSAndroid Build Coastguard Worker        self._tunnel_host = None
849*cda5da8dSAndroid Build Coastguard Worker        self._tunnel_port = None
850*cda5da8dSAndroid Build Coastguard Worker        self._tunnel_headers = {}
851*cda5da8dSAndroid Build Coastguard Worker
852*cda5da8dSAndroid Build Coastguard Worker        (self.host, self.port) = self._get_hostport(host, port)
853*cda5da8dSAndroid Build Coastguard Worker
854*cda5da8dSAndroid Build Coastguard Worker        self._validate_host(self.host)
855*cda5da8dSAndroid Build Coastguard Worker
856*cda5da8dSAndroid Build Coastguard Worker        # This is stored as an instance variable to allow unit
857*cda5da8dSAndroid Build Coastguard Worker        # tests to replace it with a suitable mockup
858*cda5da8dSAndroid Build Coastguard Worker        self._create_connection = socket.create_connection
859*cda5da8dSAndroid Build Coastguard Worker
860*cda5da8dSAndroid Build Coastguard Worker    def set_tunnel(self, host, port=None, headers=None):
861*cda5da8dSAndroid Build Coastguard Worker        """Set up host and port for HTTP CONNECT tunnelling.
862*cda5da8dSAndroid Build Coastguard Worker
863*cda5da8dSAndroid Build Coastguard Worker        In a connection that uses HTTP CONNECT tunneling, the host passed to the
864*cda5da8dSAndroid Build Coastguard Worker        constructor is used as a proxy server that relays all communication to
865*cda5da8dSAndroid Build Coastguard Worker        the endpoint passed to `set_tunnel`. This done by sending an HTTP
866*cda5da8dSAndroid Build Coastguard Worker        CONNECT request to the proxy server when the connection is established.
867*cda5da8dSAndroid Build Coastguard Worker
868*cda5da8dSAndroid Build Coastguard Worker        This method must be called before the HTTP connection has been
869*cda5da8dSAndroid Build Coastguard Worker        established.
870*cda5da8dSAndroid Build Coastguard Worker
871*cda5da8dSAndroid Build Coastguard Worker        The headers argument should be a mapping of extra HTTP headers to send
872*cda5da8dSAndroid Build Coastguard Worker        with the CONNECT request.
873*cda5da8dSAndroid Build Coastguard Worker        """
874*cda5da8dSAndroid Build Coastguard Worker
875*cda5da8dSAndroid Build Coastguard Worker        if self.sock:
876*cda5da8dSAndroid Build Coastguard Worker            raise RuntimeError("Can't set up tunnel for established connection")
877*cda5da8dSAndroid Build Coastguard Worker
878*cda5da8dSAndroid Build Coastguard Worker        self._tunnel_host, self._tunnel_port = self._get_hostport(host, port)
879*cda5da8dSAndroid Build Coastguard Worker        if headers:
880*cda5da8dSAndroid Build Coastguard Worker            self._tunnel_headers = headers
881*cda5da8dSAndroid Build Coastguard Worker        else:
882*cda5da8dSAndroid Build Coastguard Worker            self._tunnel_headers.clear()
883*cda5da8dSAndroid Build Coastguard Worker
884*cda5da8dSAndroid Build Coastguard Worker    def _get_hostport(self, host, port):
885*cda5da8dSAndroid Build Coastguard Worker        if port is None:
886*cda5da8dSAndroid Build Coastguard Worker            i = host.rfind(':')
887*cda5da8dSAndroid Build Coastguard Worker            j = host.rfind(']')         # ipv6 addresses have [...]
888*cda5da8dSAndroid Build Coastguard Worker            if i > j:
889*cda5da8dSAndroid Build Coastguard Worker                try:
890*cda5da8dSAndroid Build Coastguard Worker                    port = int(host[i+1:])
891*cda5da8dSAndroid Build Coastguard Worker                except ValueError:
892*cda5da8dSAndroid Build Coastguard Worker                    if host[i+1:] == "": # http://foo.com:/ == http://foo.com/
893*cda5da8dSAndroid Build Coastguard Worker                        port = self.default_port
894*cda5da8dSAndroid Build Coastguard Worker                    else:
895*cda5da8dSAndroid Build Coastguard Worker                        raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
896*cda5da8dSAndroid Build Coastguard Worker                host = host[:i]
897*cda5da8dSAndroid Build Coastguard Worker            else:
898*cda5da8dSAndroid Build Coastguard Worker                port = self.default_port
899*cda5da8dSAndroid Build Coastguard Worker            if host and host[0] == '[' and host[-1] == ']':
900*cda5da8dSAndroid Build Coastguard Worker                host = host[1:-1]
901*cda5da8dSAndroid Build Coastguard Worker
902*cda5da8dSAndroid Build Coastguard Worker        return (host, port)
903*cda5da8dSAndroid Build Coastguard Worker
904*cda5da8dSAndroid Build Coastguard Worker    def set_debuglevel(self, level):
905*cda5da8dSAndroid Build Coastguard Worker        self.debuglevel = level
906*cda5da8dSAndroid Build Coastguard Worker
907*cda5da8dSAndroid Build Coastguard Worker    def _tunnel(self):
908*cda5da8dSAndroid Build Coastguard Worker        connect = b"CONNECT %s:%d HTTP/1.0\r\n" % (
909*cda5da8dSAndroid Build Coastguard Worker            self._tunnel_host.encode("ascii"), self._tunnel_port)
910*cda5da8dSAndroid Build Coastguard Worker        headers = [connect]
911*cda5da8dSAndroid Build Coastguard Worker        for header, value in self._tunnel_headers.items():
912*cda5da8dSAndroid Build Coastguard Worker            headers.append(f"{header}: {value}\r\n".encode("latin-1"))
913*cda5da8dSAndroid Build Coastguard Worker        headers.append(b"\r\n")
914*cda5da8dSAndroid Build Coastguard Worker        # Making a single send() call instead of one per line encourages
915*cda5da8dSAndroid Build Coastguard Worker        # the host OS to use a more optimal packet size instead of
916*cda5da8dSAndroid Build Coastguard Worker        # potentially emitting a series of small packets.
917*cda5da8dSAndroid Build Coastguard Worker        self.send(b"".join(headers))
918*cda5da8dSAndroid Build Coastguard Worker        del headers
919*cda5da8dSAndroid Build Coastguard Worker
920*cda5da8dSAndroid Build Coastguard Worker        response = self.response_class(self.sock, method=self._method)
921*cda5da8dSAndroid Build Coastguard Worker        try:
922*cda5da8dSAndroid Build Coastguard Worker            (version, code, message) = response._read_status()
923*cda5da8dSAndroid Build Coastguard Worker
924*cda5da8dSAndroid Build Coastguard Worker            if code != http.HTTPStatus.OK:
925*cda5da8dSAndroid Build Coastguard Worker                self.close()
926*cda5da8dSAndroid Build Coastguard Worker                raise OSError(f"Tunnel connection failed: {code} {message.strip()}")
927*cda5da8dSAndroid Build Coastguard Worker            while True:
928*cda5da8dSAndroid Build Coastguard Worker                line = response.fp.readline(_MAXLINE + 1)
929*cda5da8dSAndroid Build Coastguard Worker                if len(line) > _MAXLINE:
930*cda5da8dSAndroid Build Coastguard Worker                    raise LineTooLong("header line")
931*cda5da8dSAndroid Build Coastguard Worker                if not line:
932*cda5da8dSAndroid Build Coastguard Worker                    # for sites which EOF without sending a trailer
933*cda5da8dSAndroid Build Coastguard Worker                    break
934*cda5da8dSAndroid Build Coastguard Worker                if line in (b'\r\n', b'\n', b''):
935*cda5da8dSAndroid Build Coastguard Worker                    break
936*cda5da8dSAndroid Build Coastguard Worker
937*cda5da8dSAndroid Build Coastguard Worker                if self.debuglevel > 0:
938*cda5da8dSAndroid Build Coastguard Worker                    print('header:', line.decode())
939*cda5da8dSAndroid Build Coastguard Worker        finally:
940*cda5da8dSAndroid Build Coastguard Worker            response.close()
941*cda5da8dSAndroid Build Coastguard Worker
942*cda5da8dSAndroid Build Coastguard Worker    def connect(self):
943*cda5da8dSAndroid Build Coastguard Worker        """Connect to the host and port specified in __init__."""
944*cda5da8dSAndroid Build Coastguard Worker        sys.audit("http.client.connect", self, self.host, self.port)
945*cda5da8dSAndroid Build Coastguard Worker        self.sock = self._create_connection(
946*cda5da8dSAndroid Build Coastguard Worker            (self.host,self.port), self.timeout, self.source_address)
947*cda5da8dSAndroid Build Coastguard Worker        # Might fail in OSs that don't implement TCP_NODELAY
948*cda5da8dSAndroid Build Coastguard Worker        try:
949*cda5da8dSAndroid Build Coastguard Worker            self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
950*cda5da8dSAndroid Build Coastguard Worker        except OSError as e:
951*cda5da8dSAndroid Build Coastguard Worker            if e.errno != errno.ENOPROTOOPT:
952*cda5da8dSAndroid Build Coastguard Worker                raise
953*cda5da8dSAndroid Build Coastguard Worker
954*cda5da8dSAndroid Build Coastguard Worker        if self._tunnel_host:
955*cda5da8dSAndroid Build Coastguard Worker            self._tunnel()
956*cda5da8dSAndroid Build Coastguard Worker
957*cda5da8dSAndroid Build Coastguard Worker    def close(self):
958*cda5da8dSAndroid Build Coastguard Worker        """Close the connection to the HTTP server."""
959*cda5da8dSAndroid Build Coastguard Worker        self.__state = _CS_IDLE
960*cda5da8dSAndroid Build Coastguard Worker        try:
961*cda5da8dSAndroid Build Coastguard Worker            sock = self.sock
962*cda5da8dSAndroid Build Coastguard Worker            if sock:
963*cda5da8dSAndroid Build Coastguard Worker                self.sock = None
964*cda5da8dSAndroid Build Coastguard Worker                sock.close()   # close it manually... there may be other refs
965*cda5da8dSAndroid Build Coastguard Worker        finally:
966*cda5da8dSAndroid Build Coastguard Worker            response = self.__response
967*cda5da8dSAndroid Build Coastguard Worker            if response:
968*cda5da8dSAndroid Build Coastguard Worker                self.__response = None
969*cda5da8dSAndroid Build Coastguard Worker                response.close()
970*cda5da8dSAndroid Build Coastguard Worker
971*cda5da8dSAndroid Build Coastguard Worker    def send(self, data):
972*cda5da8dSAndroid Build Coastguard Worker        """Send `data' to the server.
973*cda5da8dSAndroid Build Coastguard Worker        ``data`` can be a string object, a bytes object, an array object, a
974*cda5da8dSAndroid Build Coastguard Worker        file-like object that supports a .read() method, or an iterable object.
975*cda5da8dSAndroid Build Coastguard Worker        """
976*cda5da8dSAndroid Build Coastguard Worker
977*cda5da8dSAndroid Build Coastguard Worker        if self.sock is None:
978*cda5da8dSAndroid Build Coastguard Worker            if self.auto_open:
979*cda5da8dSAndroid Build Coastguard Worker                self.connect()
980*cda5da8dSAndroid Build Coastguard Worker            else:
981*cda5da8dSAndroid Build Coastguard Worker                raise NotConnected()
982*cda5da8dSAndroid Build Coastguard Worker
983*cda5da8dSAndroid Build Coastguard Worker        if self.debuglevel > 0:
984*cda5da8dSAndroid Build Coastguard Worker            print("send:", repr(data))
985*cda5da8dSAndroid Build Coastguard Worker        if hasattr(data, "read") :
986*cda5da8dSAndroid Build Coastguard Worker            if self.debuglevel > 0:
987*cda5da8dSAndroid Build Coastguard Worker                print("sending a readable")
988*cda5da8dSAndroid Build Coastguard Worker            encode = self._is_textIO(data)
989*cda5da8dSAndroid Build Coastguard Worker            if encode and self.debuglevel > 0:
990*cda5da8dSAndroid Build Coastguard Worker                print("encoding file using iso-8859-1")
991*cda5da8dSAndroid Build Coastguard Worker            while 1:
992*cda5da8dSAndroid Build Coastguard Worker                datablock = data.read(self.blocksize)
993*cda5da8dSAndroid Build Coastguard Worker                if not datablock:
994*cda5da8dSAndroid Build Coastguard Worker                    break
995*cda5da8dSAndroid Build Coastguard Worker                if encode:
996*cda5da8dSAndroid Build Coastguard Worker                    datablock = datablock.encode("iso-8859-1")
997*cda5da8dSAndroid Build Coastguard Worker                sys.audit("http.client.send", self, datablock)
998*cda5da8dSAndroid Build Coastguard Worker                self.sock.sendall(datablock)
999*cda5da8dSAndroid Build Coastguard Worker            return
1000*cda5da8dSAndroid Build Coastguard Worker        sys.audit("http.client.send", self, data)
1001*cda5da8dSAndroid Build Coastguard Worker        try:
1002*cda5da8dSAndroid Build Coastguard Worker            self.sock.sendall(data)
1003*cda5da8dSAndroid Build Coastguard Worker        except TypeError:
1004*cda5da8dSAndroid Build Coastguard Worker            if isinstance(data, collections.abc.Iterable):
1005*cda5da8dSAndroid Build Coastguard Worker                for d in data:
1006*cda5da8dSAndroid Build Coastguard Worker                    self.sock.sendall(d)
1007*cda5da8dSAndroid Build Coastguard Worker            else:
1008*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("data should be a bytes-like object "
1009*cda5da8dSAndroid Build Coastguard Worker                                "or an iterable, got %r" % type(data))
1010*cda5da8dSAndroid Build Coastguard Worker
1011*cda5da8dSAndroid Build Coastguard Worker    def _output(self, s):
1012*cda5da8dSAndroid Build Coastguard Worker        """Add a line of output to the current request buffer.
1013*cda5da8dSAndroid Build Coastguard Worker
1014*cda5da8dSAndroid Build Coastguard Worker        Assumes that the line does *not* end with \\r\\n.
1015*cda5da8dSAndroid Build Coastguard Worker        """
1016*cda5da8dSAndroid Build Coastguard Worker        self._buffer.append(s)
1017*cda5da8dSAndroid Build Coastguard Worker
1018*cda5da8dSAndroid Build Coastguard Worker    def _read_readable(self, readable):
1019*cda5da8dSAndroid Build Coastguard Worker        if self.debuglevel > 0:
1020*cda5da8dSAndroid Build Coastguard Worker            print("reading a readable")
1021*cda5da8dSAndroid Build Coastguard Worker        encode = self._is_textIO(readable)
1022*cda5da8dSAndroid Build Coastguard Worker        if encode and self.debuglevel > 0:
1023*cda5da8dSAndroid Build Coastguard Worker            print("encoding file using iso-8859-1")
1024*cda5da8dSAndroid Build Coastguard Worker        while True:
1025*cda5da8dSAndroid Build Coastguard Worker            datablock = readable.read(self.blocksize)
1026*cda5da8dSAndroid Build Coastguard Worker            if not datablock:
1027*cda5da8dSAndroid Build Coastguard Worker                break
1028*cda5da8dSAndroid Build Coastguard Worker            if encode:
1029*cda5da8dSAndroid Build Coastguard Worker                datablock = datablock.encode("iso-8859-1")
1030*cda5da8dSAndroid Build Coastguard Worker            yield datablock
1031*cda5da8dSAndroid Build Coastguard Worker
1032*cda5da8dSAndroid Build Coastguard Worker    def _send_output(self, message_body=None, encode_chunked=False):
1033*cda5da8dSAndroid Build Coastguard Worker        """Send the currently buffered request and clear the buffer.
1034*cda5da8dSAndroid Build Coastguard Worker
1035*cda5da8dSAndroid Build Coastguard Worker        Appends an extra \\r\\n to the buffer.
1036*cda5da8dSAndroid Build Coastguard Worker        A message_body may be specified, to be appended to the request.
1037*cda5da8dSAndroid Build Coastguard Worker        """
1038*cda5da8dSAndroid Build Coastguard Worker        self._buffer.extend((b"", b""))
1039*cda5da8dSAndroid Build Coastguard Worker        msg = b"\r\n".join(self._buffer)
1040*cda5da8dSAndroid Build Coastguard Worker        del self._buffer[:]
1041*cda5da8dSAndroid Build Coastguard Worker        self.send(msg)
1042*cda5da8dSAndroid Build Coastguard Worker
1043*cda5da8dSAndroid Build Coastguard Worker        if message_body is not None:
1044*cda5da8dSAndroid Build Coastguard Worker
1045*cda5da8dSAndroid Build Coastguard Worker            # create a consistent interface to message_body
1046*cda5da8dSAndroid Build Coastguard Worker            if hasattr(message_body, 'read'):
1047*cda5da8dSAndroid Build Coastguard Worker                # Let file-like take precedence over byte-like.  This
1048*cda5da8dSAndroid Build Coastguard Worker                # is needed to allow the current position of mmap'ed
1049*cda5da8dSAndroid Build Coastguard Worker                # files to be taken into account.
1050*cda5da8dSAndroid Build Coastguard Worker                chunks = self._read_readable(message_body)
1051*cda5da8dSAndroid Build Coastguard Worker            else:
1052*cda5da8dSAndroid Build Coastguard Worker                try:
1053*cda5da8dSAndroid Build Coastguard Worker                    # this is solely to check to see if message_body
1054*cda5da8dSAndroid Build Coastguard Worker                    # implements the buffer API.  it /would/ be easier
1055*cda5da8dSAndroid Build Coastguard Worker                    # to capture if PyObject_CheckBuffer was exposed
1056*cda5da8dSAndroid Build Coastguard Worker                    # to Python.
1057*cda5da8dSAndroid Build Coastguard Worker                    memoryview(message_body)
1058*cda5da8dSAndroid Build Coastguard Worker                except TypeError:
1059*cda5da8dSAndroid Build Coastguard Worker                    try:
1060*cda5da8dSAndroid Build Coastguard Worker                        chunks = iter(message_body)
1061*cda5da8dSAndroid Build Coastguard Worker                    except TypeError:
1062*cda5da8dSAndroid Build Coastguard Worker                        raise TypeError("message_body should be a bytes-like "
1063*cda5da8dSAndroid Build Coastguard Worker                                        "object or an iterable, got %r"
1064*cda5da8dSAndroid Build Coastguard Worker                                        % type(message_body))
1065*cda5da8dSAndroid Build Coastguard Worker                else:
1066*cda5da8dSAndroid Build Coastguard Worker                    # the object implements the buffer interface and
1067*cda5da8dSAndroid Build Coastguard Worker                    # can be passed directly into socket methods
1068*cda5da8dSAndroid Build Coastguard Worker                    chunks = (message_body,)
1069*cda5da8dSAndroid Build Coastguard Worker
1070*cda5da8dSAndroid Build Coastguard Worker            for chunk in chunks:
1071*cda5da8dSAndroid Build Coastguard Worker                if not chunk:
1072*cda5da8dSAndroid Build Coastguard Worker                    if self.debuglevel > 0:
1073*cda5da8dSAndroid Build Coastguard Worker                        print('Zero length chunk ignored')
1074*cda5da8dSAndroid Build Coastguard Worker                    continue
1075*cda5da8dSAndroid Build Coastguard Worker
1076*cda5da8dSAndroid Build Coastguard Worker                if encode_chunked and self._http_vsn == 11:
1077*cda5da8dSAndroid Build Coastguard Worker                    # chunked encoding
1078*cda5da8dSAndroid Build Coastguard Worker                    chunk = f'{len(chunk):X}\r\n'.encode('ascii') + chunk \
1079*cda5da8dSAndroid Build Coastguard Worker                        + b'\r\n'
1080*cda5da8dSAndroid Build Coastguard Worker                self.send(chunk)
1081*cda5da8dSAndroid Build Coastguard Worker
1082*cda5da8dSAndroid Build Coastguard Worker            if encode_chunked and self._http_vsn == 11:
1083*cda5da8dSAndroid Build Coastguard Worker                # end chunked transfer
1084*cda5da8dSAndroid Build Coastguard Worker                self.send(b'0\r\n\r\n')
1085*cda5da8dSAndroid Build Coastguard Worker
1086*cda5da8dSAndroid Build Coastguard Worker    def putrequest(self, method, url, skip_host=False,
1087*cda5da8dSAndroid Build Coastguard Worker                   skip_accept_encoding=False):
1088*cda5da8dSAndroid Build Coastguard Worker        """Send a request to the server.
1089*cda5da8dSAndroid Build Coastguard Worker
1090*cda5da8dSAndroid Build Coastguard Worker        `method' specifies an HTTP request method, e.g. 'GET'.
1091*cda5da8dSAndroid Build Coastguard Worker        `url' specifies the object being requested, e.g. '/index.html'.
1092*cda5da8dSAndroid Build Coastguard Worker        `skip_host' if True does not add automatically a 'Host:' header
1093*cda5da8dSAndroid Build Coastguard Worker        `skip_accept_encoding' if True does not add automatically an
1094*cda5da8dSAndroid Build Coastguard Worker           'Accept-Encoding:' header
1095*cda5da8dSAndroid Build Coastguard Worker        """
1096*cda5da8dSAndroid Build Coastguard Worker
1097*cda5da8dSAndroid Build Coastguard Worker        # if a prior response has been completed, then forget about it.
1098*cda5da8dSAndroid Build Coastguard Worker        if self.__response and self.__response.isclosed():
1099*cda5da8dSAndroid Build Coastguard Worker            self.__response = None
1100*cda5da8dSAndroid Build Coastguard Worker
1101*cda5da8dSAndroid Build Coastguard Worker
1102*cda5da8dSAndroid Build Coastguard Worker        # in certain cases, we cannot issue another request on this connection.
1103*cda5da8dSAndroid Build Coastguard Worker        # this occurs when:
1104*cda5da8dSAndroid Build Coastguard Worker        #   1) we are in the process of sending a request.   (_CS_REQ_STARTED)
1105*cda5da8dSAndroid Build Coastguard Worker        #   2) a response to a previous request has signalled that it is going
1106*cda5da8dSAndroid Build Coastguard Worker        #      to close the connection upon completion.
1107*cda5da8dSAndroid Build Coastguard Worker        #   3) the headers for the previous response have not been read, thus
1108*cda5da8dSAndroid Build Coastguard Worker        #      we cannot determine whether point (2) is true.   (_CS_REQ_SENT)
1109*cda5da8dSAndroid Build Coastguard Worker        #
1110*cda5da8dSAndroid Build Coastguard Worker        # if there is no prior response, then we can request at will.
1111*cda5da8dSAndroid Build Coastguard Worker        #
1112*cda5da8dSAndroid Build Coastguard Worker        # if point (2) is true, then we will have passed the socket to the
1113*cda5da8dSAndroid Build Coastguard Worker        # response (effectively meaning, "there is no prior response"), and
1114*cda5da8dSAndroid Build Coastguard Worker        # will open a new one when a new request is made.
1115*cda5da8dSAndroid Build Coastguard Worker        #
1116*cda5da8dSAndroid Build Coastguard Worker        # Note: if a prior response exists, then we *can* start a new request.
1117*cda5da8dSAndroid Build Coastguard Worker        #       We are not allowed to begin fetching the response to this new
1118*cda5da8dSAndroid Build Coastguard Worker        #       request, however, until that prior response is complete.
1119*cda5da8dSAndroid Build Coastguard Worker        #
1120*cda5da8dSAndroid Build Coastguard Worker        if self.__state == _CS_IDLE:
1121*cda5da8dSAndroid Build Coastguard Worker            self.__state = _CS_REQ_STARTED
1122*cda5da8dSAndroid Build Coastguard Worker        else:
1123*cda5da8dSAndroid Build Coastguard Worker            raise CannotSendRequest(self.__state)
1124*cda5da8dSAndroid Build Coastguard Worker
1125*cda5da8dSAndroid Build Coastguard Worker        self._validate_method(method)
1126*cda5da8dSAndroid Build Coastguard Worker
1127*cda5da8dSAndroid Build Coastguard Worker        # Save the method for use later in the response phase
1128*cda5da8dSAndroid Build Coastguard Worker        self._method = method
1129*cda5da8dSAndroid Build Coastguard Worker
1130*cda5da8dSAndroid Build Coastguard Worker        url = url or '/'
1131*cda5da8dSAndroid Build Coastguard Worker        self._validate_path(url)
1132*cda5da8dSAndroid Build Coastguard Worker
1133*cda5da8dSAndroid Build Coastguard Worker        request = '%s %s %s' % (method, url, self._http_vsn_str)
1134*cda5da8dSAndroid Build Coastguard Worker
1135*cda5da8dSAndroid Build Coastguard Worker        self._output(self._encode_request(request))
1136*cda5da8dSAndroid Build Coastguard Worker
1137*cda5da8dSAndroid Build Coastguard Worker        if self._http_vsn == 11:
1138*cda5da8dSAndroid Build Coastguard Worker            # Issue some standard headers for better HTTP/1.1 compliance
1139*cda5da8dSAndroid Build Coastguard Worker
1140*cda5da8dSAndroid Build Coastguard Worker            if not skip_host:
1141*cda5da8dSAndroid Build Coastguard Worker                # this header is issued *only* for HTTP/1.1
1142*cda5da8dSAndroid Build Coastguard Worker                # connections. more specifically, this means it is
1143*cda5da8dSAndroid Build Coastguard Worker                # only issued when the client uses the new
1144*cda5da8dSAndroid Build Coastguard Worker                # HTTPConnection() class. backwards-compat clients
1145*cda5da8dSAndroid Build Coastguard Worker                # will be using HTTP/1.0 and those clients may be
1146*cda5da8dSAndroid Build Coastguard Worker                # issuing this header themselves. we should NOT issue
1147*cda5da8dSAndroid Build Coastguard Worker                # it twice; some web servers (such as Apache) barf
1148*cda5da8dSAndroid Build Coastguard Worker                # when they see two Host: headers
1149*cda5da8dSAndroid Build Coastguard Worker
1150*cda5da8dSAndroid Build Coastguard Worker                # If we need a non-standard port,include it in the
1151*cda5da8dSAndroid Build Coastguard Worker                # header.  If the request is going through a proxy,
1152*cda5da8dSAndroid Build Coastguard Worker                # but the host of the actual URL, not the host of the
1153*cda5da8dSAndroid Build Coastguard Worker                # proxy.
1154*cda5da8dSAndroid Build Coastguard Worker
1155*cda5da8dSAndroid Build Coastguard Worker                netloc = ''
1156*cda5da8dSAndroid Build Coastguard Worker                if url.startswith('http'):
1157*cda5da8dSAndroid Build Coastguard Worker                    nil, netloc, nil, nil, nil = urlsplit(url)
1158*cda5da8dSAndroid Build Coastguard Worker
1159*cda5da8dSAndroid Build Coastguard Worker                if netloc:
1160*cda5da8dSAndroid Build Coastguard Worker                    try:
1161*cda5da8dSAndroid Build Coastguard Worker                        netloc_enc = netloc.encode("ascii")
1162*cda5da8dSAndroid Build Coastguard Worker                    except UnicodeEncodeError:
1163*cda5da8dSAndroid Build Coastguard Worker                        netloc_enc = netloc.encode("idna")
1164*cda5da8dSAndroid Build Coastguard Worker                    self.putheader('Host', netloc_enc)
1165*cda5da8dSAndroid Build Coastguard Worker                else:
1166*cda5da8dSAndroid Build Coastguard Worker                    if self._tunnel_host:
1167*cda5da8dSAndroid Build Coastguard Worker                        host = self._tunnel_host
1168*cda5da8dSAndroid Build Coastguard Worker                        port = self._tunnel_port
1169*cda5da8dSAndroid Build Coastguard Worker                    else:
1170*cda5da8dSAndroid Build Coastguard Worker                        host = self.host
1171*cda5da8dSAndroid Build Coastguard Worker                        port = self.port
1172*cda5da8dSAndroid Build Coastguard Worker
1173*cda5da8dSAndroid Build Coastguard Worker                    try:
1174*cda5da8dSAndroid Build Coastguard Worker                        host_enc = host.encode("ascii")
1175*cda5da8dSAndroid Build Coastguard Worker                    except UnicodeEncodeError:
1176*cda5da8dSAndroid Build Coastguard Worker                        host_enc = host.encode("idna")
1177*cda5da8dSAndroid Build Coastguard Worker
1178*cda5da8dSAndroid Build Coastguard Worker                    # As per RFC 273, IPv6 address should be wrapped with []
1179*cda5da8dSAndroid Build Coastguard Worker                    # when used as Host header
1180*cda5da8dSAndroid Build Coastguard Worker
1181*cda5da8dSAndroid Build Coastguard Worker                    if host.find(':') >= 0:
1182*cda5da8dSAndroid Build Coastguard Worker                        host_enc = b'[' + host_enc + b']'
1183*cda5da8dSAndroid Build Coastguard Worker
1184*cda5da8dSAndroid Build Coastguard Worker                    if port == self.default_port:
1185*cda5da8dSAndroid Build Coastguard Worker                        self.putheader('Host', host_enc)
1186*cda5da8dSAndroid Build Coastguard Worker                    else:
1187*cda5da8dSAndroid Build Coastguard Worker                        host_enc = host_enc.decode("ascii")
1188*cda5da8dSAndroid Build Coastguard Worker                        self.putheader('Host', "%s:%s" % (host_enc, port))
1189*cda5da8dSAndroid Build Coastguard Worker
1190*cda5da8dSAndroid Build Coastguard Worker            # note: we are assuming that clients will not attempt to set these
1191*cda5da8dSAndroid Build Coastguard Worker            #       headers since *this* library must deal with the
1192*cda5da8dSAndroid Build Coastguard Worker            #       consequences. this also means that when the supporting
1193*cda5da8dSAndroid Build Coastguard Worker            #       libraries are updated to recognize other forms, then this
1194*cda5da8dSAndroid Build Coastguard Worker            #       code should be changed (removed or updated).
1195*cda5da8dSAndroid Build Coastguard Worker
1196*cda5da8dSAndroid Build Coastguard Worker            # we only want a Content-Encoding of "identity" since we don't
1197*cda5da8dSAndroid Build Coastguard Worker            # support encodings such as x-gzip or x-deflate.
1198*cda5da8dSAndroid Build Coastguard Worker            if not skip_accept_encoding:
1199*cda5da8dSAndroid Build Coastguard Worker                self.putheader('Accept-Encoding', 'identity')
1200*cda5da8dSAndroid Build Coastguard Worker
1201*cda5da8dSAndroid Build Coastguard Worker            # we can accept "chunked" Transfer-Encodings, but no others
1202*cda5da8dSAndroid Build Coastguard Worker            # NOTE: no TE header implies *only* "chunked"
1203*cda5da8dSAndroid Build Coastguard Worker            #self.putheader('TE', 'chunked')
1204*cda5da8dSAndroid Build Coastguard Worker
1205*cda5da8dSAndroid Build Coastguard Worker            # if TE is supplied in the header, then it must appear in a
1206*cda5da8dSAndroid Build Coastguard Worker            # Connection header.
1207*cda5da8dSAndroid Build Coastguard Worker            #self.putheader('Connection', 'TE')
1208*cda5da8dSAndroid Build Coastguard Worker
1209*cda5da8dSAndroid Build Coastguard Worker        else:
1210*cda5da8dSAndroid Build Coastguard Worker            # For HTTP/1.0, the server will assume "not chunked"
1211*cda5da8dSAndroid Build Coastguard Worker            pass
1212*cda5da8dSAndroid Build Coastguard Worker
1213*cda5da8dSAndroid Build Coastguard Worker    def _encode_request(self, request):
1214*cda5da8dSAndroid Build Coastguard Worker        # ASCII also helps prevent CVE-2019-9740.
1215*cda5da8dSAndroid Build Coastguard Worker        return request.encode('ascii')
1216*cda5da8dSAndroid Build Coastguard Worker
1217*cda5da8dSAndroid Build Coastguard Worker    def _validate_method(self, method):
1218*cda5da8dSAndroid Build Coastguard Worker        """Validate a method name for putrequest."""
1219*cda5da8dSAndroid Build Coastguard Worker        # prevent http header injection
1220*cda5da8dSAndroid Build Coastguard Worker        match = _contains_disallowed_method_pchar_re.search(method)
1221*cda5da8dSAndroid Build Coastguard Worker        if match:
1222*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(
1223*cda5da8dSAndroid Build Coastguard Worker                    f"method can't contain control characters. {method!r} "
1224*cda5da8dSAndroid Build Coastguard Worker                    f"(found at least {match.group()!r})")
1225*cda5da8dSAndroid Build Coastguard Worker
1226*cda5da8dSAndroid Build Coastguard Worker    def _validate_path(self, url):
1227*cda5da8dSAndroid Build Coastguard Worker        """Validate a url for putrequest."""
1228*cda5da8dSAndroid Build Coastguard Worker        # Prevent CVE-2019-9740.
1229*cda5da8dSAndroid Build Coastguard Worker        match = _contains_disallowed_url_pchar_re.search(url)
1230*cda5da8dSAndroid Build Coastguard Worker        if match:
1231*cda5da8dSAndroid Build Coastguard Worker            raise InvalidURL(f"URL can't contain control characters. {url!r} "
1232*cda5da8dSAndroid Build Coastguard Worker                             f"(found at least {match.group()!r})")
1233*cda5da8dSAndroid Build Coastguard Worker
1234*cda5da8dSAndroid Build Coastguard Worker    def _validate_host(self, host):
1235*cda5da8dSAndroid Build Coastguard Worker        """Validate a host so it doesn't contain control characters."""
1236*cda5da8dSAndroid Build Coastguard Worker        # Prevent CVE-2019-18348.
1237*cda5da8dSAndroid Build Coastguard Worker        match = _contains_disallowed_url_pchar_re.search(host)
1238*cda5da8dSAndroid Build Coastguard Worker        if match:
1239*cda5da8dSAndroid Build Coastguard Worker            raise InvalidURL(f"URL can't contain control characters. {host!r} "
1240*cda5da8dSAndroid Build Coastguard Worker                             f"(found at least {match.group()!r})")
1241*cda5da8dSAndroid Build Coastguard Worker
1242*cda5da8dSAndroid Build Coastguard Worker    def putheader(self, header, *values):
1243*cda5da8dSAndroid Build Coastguard Worker        """Send a request header line to the server.
1244*cda5da8dSAndroid Build Coastguard Worker
1245*cda5da8dSAndroid Build Coastguard Worker        For example: h.putheader('Accept', 'text/html')
1246*cda5da8dSAndroid Build Coastguard Worker        """
1247*cda5da8dSAndroid Build Coastguard Worker        if self.__state != _CS_REQ_STARTED:
1248*cda5da8dSAndroid Build Coastguard Worker            raise CannotSendHeader()
1249*cda5da8dSAndroid Build Coastguard Worker
1250*cda5da8dSAndroid Build Coastguard Worker        if hasattr(header, 'encode'):
1251*cda5da8dSAndroid Build Coastguard Worker            header = header.encode('ascii')
1252*cda5da8dSAndroid Build Coastguard Worker
1253*cda5da8dSAndroid Build Coastguard Worker        if not _is_legal_header_name(header):
1254*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('Invalid header name %r' % (header,))
1255*cda5da8dSAndroid Build Coastguard Worker
1256*cda5da8dSAndroid Build Coastguard Worker        values = list(values)
1257*cda5da8dSAndroid Build Coastguard Worker        for i, one_value in enumerate(values):
1258*cda5da8dSAndroid Build Coastguard Worker            if hasattr(one_value, 'encode'):
1259*cda5da8dSAndroid Build Coastguard Worker                values[i] = one_value.encode('latin-1')
1260*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(one_value, int):
1261*cda5da8dSAndroid Build Coastguard Worker                values[i] = str(one_value).encode('ascii')
1262*cda5da8dSAndroid Build Coastguard Worker
1263*cda5da8dSAndroid Build Coastguard Worker            if _is_illegal_header_value(values[i]):
1264*cda5da8dSAndroid Build Coastguard Worker                raise ValueError('Invalid header value %r' % (values[i],))
1265*cda5da8dSAndroid Build Coastguard Worker
1266*cda5da8dSAndroid Build Coastguard Worker        value = b'\r\n\t'.join(values)
1267*cda5da8dSAndroid Build Coastguard Worker        header = header + b': ' + value
1268*cda5da8dSAndroid Build Coastguard Worker        self._output(header)
1269*cda5da8dSAndroid Build Coastguard Worker
1270*cda5da8dSAndroid Build Coastguard Worker    def endheaders(self, message_body=None, *, encode_chunked=False):
1271*cda5da8dSAndroid Build Coastguard Worker        """Indicate that the last header line has been sent to the server.
1272*cda5da8dSAndroid Build Coastguard Worker
1273*cda5da8dSAndroid Build Coastguard Worker        This method sends the request to the server.  The optional message_body
1274*cda5da8dSAndroid Build Coastguard Worker        argument can be used to pass a message body associated with the
1275*cda5da8dSAndroid Build Coastguard Worker        request.
1276*cda5da8dSAndroid Build Coastguard Worker        """
1277*cda5da8dSAndroid Build Coastguard Worker        if self.__state == _CS_REQ_STARTED:
1278*cda5da8dSAndroid Build Coastguard Worker            self.__state = _CS_REQ_SENT
1279*cda5da8dSAndroid Build Coastguard Worker        else:
1280*cda5da8dSAndroid Build Coastguard Worker            raise CannotSendHeader()
1281*cda5da8dSAndroid Build Coastguard Worker        self._send_output(message_body, encode_chunked=encode_chunked)
1282*cda5da8dSAndroid Build Coastguard Worker
1283*cda5da8dSAndroid Build Coastguard Worker    def request(self, method, url, body=None, headers={}, *,
1284*cda5da8dSAndroid Build Coastguard Worker                encode_chunked=False):
1285*cda5da8dSAndroid Build Coastguard Worker        """Send a complete request to the server."""
1286*cda5da8dSAndroid Build Coastguard Worker        self._send_request(method, url, body, headers, encode_chunked)
1287*cda5da8dSAndroid Build Coastguard Worker
1288*cda5da8dSAndroid Build Coastguard Worker    def _send_request(self, method, url, body, headers, encode_chunked):
1289*cda5da8dSAndroid Build Coastguard Worker        # Honor explicitly requested Host: and Accept-Encoding: headers.
1290*cda5da8dSAndroid Build Coastguard Worker        header_names = frozenset(k.lower() for k in headers)
1291*cda5da8dSAndroid Build Coastguard Worker        skips = {}
1292*cda5da8dSAndroid Build Coastguard Worker        if 'host' in header_names:
1293*cda5da8dSAndroid Build Coastguard Worker            skips['skip_host'] = 1
1294*cda5da8dSAndroid Build Coastguard Worker        if 'accept-encoding' in header_names:
1295*cda5da8dSAndroid Build Coastguard Worker            skips['skip_accept_encoding'] = 1
1296*cda5da8dSAndroid Build Coastguard Worker
1297*cda5da8dSAndroid Build Coastguard Worker        self.putrequest(method, url, **skips)
1298*cda5da8dSAndroid Build Coastguard Worker
1299*cda5da8dSAndroid Build Coastguard Worker        # chunked encoding will happen if HTTP/1.1 is used and either
1300*cda5da8dSAndroid Build Coastguard Worker        # the caller passes encode_chunked=True or the following
1301*cda5da8dSAndroid Build Coastguard Worker        # conditions hold:
1302*cda5da8dSAndroid Build Coastguard Worker        # 1. content-length has not been explicitly set
1303*cda5da8dSAndroid Build Coastguard Worker        # 2. the body is a file or iterable, but not a str or bytes-like
1304*cda5da8dSAndroid Build Coastguard Worker        # 3. Transfer-Encoding has NOT been explicitly set by the caller
1305*cda5da8dSAndroid Build Coastguard Worker
1306*cda5da8dSAndroid Build Coastguard Worker        if 'content-length' not in header_names:
1307*cda5da8dSAndroid Build Coastguard Worker            # only chunk body if not explicitly set for backwards
1308*cda5da8dSAndroid Build Coastguard Worker            # compatibility, assuming the client code is already handling the
1309*cda5da8dSAndroid Build Coastguard Worker            # chunking
1310*cda5da8dSAndroid Build Coastguard Worker            if 'transfer-encoding' not in header_names:
1311*cda5da8dSAndroid Build Coastguard Worker                # if content-length cannot be automatically determined, fall
1312*cda5da8dSAndroid Build Coastguard Worker                # back to chunked encoding
1313*cda5da8dSAndroid Build Coastguard Worker                encode_chunked = False
1314*cda5da8dSAndroid Build Coastguard Worker                content_length = self._get_content_length(body, method)
1315*cda5da8dSAndroid Build Coastguard Worker                if content_length is None:
1316*cda5da8dSAndroid Build Coastguard Worker                    if body is not None:
1317*cda5da8dSAndroid Build Coastguard Worker                        if self.debuglevel > 0:
1318*cda5da8dSAndroid Build Coastguard Worker                            print('Unable to determine size of %r' % body)
1319*cda5da8dSAndroid Build Coastguard Worker                        encode_chunked = True
1320*cda5da8dSAndroid Build Coastguard Worker                        self.putheader('Transfer-Encoding', 'chunked')
1321*cda5da8dSAndroid Build Coastguard Worker                else:
1322*cda5da8dSAndroid Build Coastguard Worker                    self.putheader('Content-Length', str(content_length))
1323*cda5da8dSAndroid Build Coastguard Worker        else:
1324*cda5da8dSAndroid Build Coastguard Worker            encode_chunked = False
1325*cda5da8dSAndroid Build Coastguard Worker
1326*cda5da8dSAndroid Build Coastguard Worker        for hdr, value in headers.items():
1327*cda5da8dSAndroid Build Coastguard Worker            self.putheader(hdr, value)
1328*cda5da8dSAndroid Build Coastguard Worker        if isinstance(body, str):
1329*cda5da8dSAndroid Build Coastguard Worker            # RFC 2616 Section 3.7.1 says that text default has a
1330*cda5da8dSAndroid Build Coastguard Worker            # default charset of iso-8859-1.
1331*cda5da8dSAndroid Build Coastguard Worker            body = _encode(body, 'body')
1332*cda5da8dSAndroid Build Coastguard Worker        self.endheaders(body, encode_chunked=encode_chunked)
1333*cda5da8dSAndroid Build Coastguard Worker
1334*cda5da8dSAndroid Build Coastguard Worker    def getresponse(self):
1335*cda5da8dSAndroid Build Coastguard Worker        """Get the response from the server.
1336*cda5da8dSAndroid Build Coastguard Worker
1337*cda5da8dSAndroid Build Coastguard Worker        If the HTTPConnection is in the correct state, returns an
1338*cda5da8dSAndroid Build Coastguard Worker        instance of HTTPResponse or of whatever object is returned by
1339*cda5da8dSAndroid Build Coastguard Worker        the response_class variable.
1340*cda5da8dSAndroid Build Coastguard Worker
1341*cda5da8dSAndroid Build Coastguard Worker        If a request has not been sent or if a previous response has
1342*cda5da8dSAndroid Build Coastguard Worker        not be handled, ResponseNotReady is raised.  If the HTTP
1343*cda5da8dSAndroid Build Coastguard Worker        response indicates that the connection should be closed, then
1344*cda5da8dSAndroid Build Coastguard Worker        it will be closed before the response is returned.  When the
1345*cda5da8dSAndroid Build Coastguard Worker        connection is closed, the underlying socket is closed.
1346*cda5da8dSAndroid Build Coastguard Worker        """
1347*cda5da8dSAndroid Build Coastguard Worker
1348*cda5da8dSAndroid Build Coastguard Worker        # if a prior response has been completed, then forget about it.
1349*cda5da8dSAndroid Build Coastguard Worker        if self.__response and self.__response.isclosed():
1350*cda5da8dSAndroid Build Coastguard Worker            self.__response = None
1351*cda5da8dSAndroid Build Coastguard Worker
1352*cda5da8dSAndroid Build Coastguard Worker        # if a prior response exists, then it must be completed (otherwise, we
1353*cda5da8dSAndroid Build Coastguard Worker        # cannot read this response's header to determine the connection-close
1354*cda5da8dSAndroid Build Coastguard Worker        # behavior)
1355*cda5da8dSAndroid Build Coastguard Worker        #
1356*cda5da8dSAndroid Build Coastguard Worker        # note: if a prior response existed, but was connection-close, then the
1357*cda5da8dSAndroid Build Coastguard Worker        # socket and response were made independent of this HTTPConnection
1358*cda5da8dSAndroid Build Coastguard Worker        # object since a new request requires that we open a whole new
1359*cda5da8dSAndroid Build Coastguard Worker        # connection
1360*cda5da8dSAndroid Build Coastguard Worker        #
1361*cda5da8dSAndroid Build Coastguard Worker        # this means the prior response had one of two states:
1362*cda5da8dSAndroid Build Coastguard Worker        #   1) will_close: this connection was reset and the prior socket and
1363*cda5da8dSAndroid Build Coastguard Worker        #                  response operate independently
1364*cda5da8dSAndroid Build Coastguard Worker        #   2) persistent: the response was retained and we await its
1365*cda5da8dSAndroid Build Coastguard Worker        #                  isclosed() status to become true.
1366*cda5da8dSAndroid Build Coastguard Worker        #
1367*cda5da8dSAndroid Build Coastguard Worker        if self.__state != _CS_REQ_SENT or self.__response:
1368*cda5da8dSAndroid Build Coastguard Worker            raise ResponseNotReady(self.__state)
1369*cda5da8dSAndroid Build Coastguard Worker
1370*cda5da8dSAndroid Build Coastguard Worker        if self.debuglevel > 0:
1371*cda5da8dSAndroid Build Coastguard Worker            response = self.response_class(self.sock, self.debuglevel,
1372*cda5da8dSAndroid Build Coastguard Worker                                           method=self._method)
1373*cda5da8dSAndroid Build Coastguard Worker        else:
1374*cda5da8dSAndroid Build Coastguard Worker            response = self.response_class(self.sock, method=self._method)
1375*cda5da8dSAndroid Build Coastguard Worker
1376*cda5da8dSAndroid Build Coastguard Worker        try:
1377*cda5da8dSAndroid Build Coastguard Worker            try:
1378*cda5da8dSAndroid Build Coastguard Worker                response.begin()
1379*cda5da8dSAndroid Build Coastguard Worker            except ConnectionError:
1380*cda5da8dSAndroid Build Coastguard Worker                self.close()
1381*cda5da8dSAndroid Build Coastguard Worker                raise
1382*cda5da8dSAndroid Build Coastguard Worker            assert response.will_close != _UNKNOWN
1383*cda5da8dSAndroid Build Coastguard Worker            self.__state = _CS_IDLE
1384*cda5da8dSAndroid Build Coastguard Worker
1385*cda5da8dSAndroid Build Coastguard Worker            if response.will_close:
1386*cda5da8dSAndroid Build Coastguard Worker                # this effectively passes the connection to the response
1387*cda5da8dSAndroid Build Coastguard Worker                self.close()
1388*cda5da8dSAndroid Build Coastguard Worker            else:
1389*cda5da8dSAndroid Build Coastguard Worker                # remember this, so we can tell when it is complete
1390*cda5da8dSAndroid Build Coastguard Worker                self.__response = response
1391*cda5da8dSAndroid Build Coastguard Worker
1392*cda5da8dSAndroid Build Coastguard Worker            return response
1393*cda5da8dSAndroid Build Coastguard Worker        except:
1394*cda5da8dSAndroid Build Coastguard Worker            response.close()
1395*cda5da8dSAndroid Build Coastguard Worker            raise
1396*cda5da8dSAndroid Build Coastguard Worker
1397*cda5da8dSAndroid Build Coastguard Workertry:
1398*cda5da8dSAndroid Build Coastguard Worker    import ssl
1399*cda5da8dSAndroid Build Coastguard Workerexcept ImportError:
1400*cda5da8dSAndroid Build Coastguard Worker    pass
1401*cda5da8dSAndroid Build Coastguard Workerelse:
1402*cda5da8dSAndroid Build Coastguard Worker    class HTTPSConnection(HTTPConnection):
1403*cda5da8dSAndroid Build Coastguard Worker        "This class allows communication via SSL."
1404*cda5da8dSAndroid Build Coastguard Worker
1405*cda5da8dSAndroid Build Coastguard Worker        default_port = HTTPS_PORT
1406*cda5da8dSAndroid Build Coastguard Worker
1407*cda5da8dSAndroid Build Coastguard Worker        # XXX Should key_file and cert_file be deprecated in favour of context?
1408*cda5da8dSAndroid Build Coastguard Worker
1409*cda5da8dSAndroid Build Coastguard Worker        def __init__(self, host, port=None, key_file=None, cert_file=None,
1410*cda5da8dSAndroid Build Coastguard Worker                     timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
1411*cda5da8dSAndroid Build Coastguard Worker                     source_address=None, *, context=None,
1412*cda5da8dSAndroid Build Coastguard Worker                     check_hostname=None, blocksize=8192):
1413*cda5da8dSAndroid Build Coastguard Worker            super(HTTPSConnection, self).__init__(host, port, timeout,
1414*cda5da8dSAndroid Build Coastguard Worker                                                  source_address,
1415*cda5da8dSAndroid Build Coastguard Worker                                                  blocksize=blocksize)
1416*cda5da8dSAndroid Build Coastguard Worker            if (key_file is not None or cert_file is not None or
1417*cda5da8dSAndroid Build Coastguard Worker                        check_hostname is not None):
1418*cda5da8dSAndroid Build Coastguard Worker                import warnings
1419*cda5da8dSAndroid Build Coastguard Worker                warnings.warn("key_file, cert_file and check_hostname are "
1420*cda5da8dSAndroid Build Coastguard Worker                              "deprecated, use a custom context instead.",
1421*cda5da8dSAndroid Build Coastguard Worker                              DeprecationWarning, 2)
1422*cda5da8dSAndroid Build Coastguard Worker            self.key_file = key_file
1423*cda5da8dSAndroid Build Coastguard Worker            self.cert_file = cert_file
1424*cda5da8dSAndroid Build Coastguard Worker            if context is None:
1425*cda5da8dSAndroid Build Coastguard Worker                context = ssl._create_default_https_context()
1426*cda5da8dSAndroid Build Coastguard Worker                # send ALPN extension to indicate HTTP/1.1 protocol
1427*cda5da8dSAndroid Build Coastguard Worker                if self._http_vsn == 11:
1428*cda5da8dSAndroid Build Coastguard Worker                    context.set_alpn_protocols(['http/1.1'])
1429*cda5da8dSAndroid Build Coastguard Worker                # enable PHA for TLS 1.3 connections if available
1430*cda5da8dSAndroid Build Coastguard Worker                if context.post_handshake_auth is not None:
1431*cda5da8dSAndroid Build Coastguard Worker                    context.post_handshake_auth = True
1432*cda5da8dSAndroid Build Coastguard Worker            will_verify = context.verify_mode != ssl.CERT_NONE
1433*cda5da8dSAndroid Build Coastguard Worker            if check_hostname is None:
1434*cda5da8dSAndroid Build Coastguard Worker                check_hostname = context.check_hostname
1435*cda5da8dSAndroid Build Coastguard Worker            if check_hostname and not will_verify:
1436*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("check_hostname needs a SSL context with "
1437*cda5da8dSAndroid Build Coastguard Worker                                 "either CERT_OPTIONAL or CERT_REQUIRED")
1438*cda5da8dSAndroid Build Coastguard Worker            if key_file or cert_file:
1439*cda5da8dSAndroid Build Coastguard Worker                context.load_cert_chain(cert_file, key_file)
1440*cda5da8dSAndroid Build Coastguard Worker                # cert and key file means the user wants to authenticate.
1441*cda5da8dSAndroid Build Coastguard Worker                # enable TLS 1.3 PHA implicitly even for custom contexts.
1442*cda5da8dSAndroid Build Coastguard Worker                if context.post_handshake_auth is not None:
1443*cda5da8dSAndroid Build Coastguard Worker                    context.post_handshake_auth = True
1444*cda5da8dSAndroid Build Coastguard Worker            self._context = context
1445*cda5da8dSAndroid Build Coastguard Worker            if check_hostname is not None:
1446*cda5da8dSAndroid Build Coastguard Worker                self._context.check_hostname = check_hostname
1447*cda5da8dSAndroid Build Coastguard Worker
1448*cda5da8dSAndroid Build Coastguard Worker        def connect(self):
1449*cda5da8dSAndroid Build Coastguard Worker            "Connect to a host on a given (SSL) port."
1450*cda5da8dSAndroid Build Coastguard Worker
1451*cda5da8dSAndroid Build Coastguard Worker            super().connect()
1452*cda5da8dSAndroid Build Coastguard Worker
1453*cda5da8dSAndroid Build Coastguard Worker            if self._tunnel_host:
1454*cda5da8dSAndroid Build Coastguard Worker                server_hostname = self._tunnel_host
1455*cda5da8dSAndroid Build Coastguard Worker            else:
1456*cda5da8dSAndroid Build Coastguard Worker                server_hostname = self.host
1457*cda5da8dSAndroid Build Coastguard Worker
1458*cda5da8dSAndroid Build Coastguard Worker            self.sock = self._context.wrap_socket(self.sock,
1459*cda5da8dSAndroid Build Coastguard Worker                                                  server_hostname=server_hostname)
1460*cda5da8dSAndroid Build Coastguard Worker
1461*cda5da8dSAndroid Build Coastguard Worker    __all__.append("HTTPSConnection")
1462*cda5da8dSAndroid Build Coastguard Worker
1463*cda5da8dSAndroid Build Coastguard Workerclass HTTPException(Exception):
1464*cda5da8dSAndroid Build Coastguard Worker    # Subclasses that define an __init__ must call Exception.__init__
1465*cda5da8dSAndroid Build Coastguard Worker    # or define self.args.  Otherwise, str() will fail.
1466*cda5da8dSAndroid Build Coastguard Worker    pass
1467*cda5da8dSAndroid Build Coastguard Worker
1468*cda5da8dSAndroid Build Coastguard Workerclass NotConnected(HTTPException):
1469*cda5da8dSAndroid Build Coastguard Worker    pass
1470*cda5da8dSAndroid Build Coastguard Worker
1471*cda5da8dSAndroid Build Coastguard Workerclass InvalidURL(HTTPException):
1472*cda5da8dSAndroid Build Coastguard Worker    pass
1473*cda5da8dSAndroid Build Coastguard Worker
1474*cda5da8dSAndroid Build Coastguard Workerclass UnknownProtocol(HTTPException):
1475*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, version):
1476*cda5da8dSAndroid Build Coastguard Worker        self.args = version,
1477*cda5da8dSAndroid Build Coastguard Worker        self.version = version
1478*cda5da8dSAndroid Build Coastguard Worker
1479*cda5da8dSAndroid Build Coastguard Workerclass UnknownTransferEncoding(HTTPException):
1480*cda5da8dSAndroid Build Coastguard Worker    pass
1481*cda5da8dSAndroid Build Coastguard Worker
1482*cda5da8dSAndroid Build Coastguard Workerclass UnimplementedFileMode(HTTPException):
1483*cda5da8dSAndroid Build Coastguard Worker    pass
1484*cda5da8dSAndroid Build Coastguard Worker
1485*cda5da8dSAndroid Build Coastguard Workerclass IncompleteRead(HTTPException):
1486*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, partial, expected=None):
1487*cda5da8dSAndroid Build Coastguard Worker        self.args = partial,
1488*cda5da8dSAndroid Build Coastguard Worker        self.partial = partial
1489*cda5da8dSAndroid Build Coastguard Worker        self.expected = expected
1490*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
1491*cda5da8dSAndroid Build Coastguard Worker        if self.expected is not None:
1492*cda5da8dSAndroid Build Coastguard Worker            e = ', %i more expected' % self.expected
1493*cda5da8dSAndroid Build Coastguard Worker        else:
1494*cda5da8dSAndroid Build Coastguard Worker            e = ''
1495*cda5da8dSAndroid Build Coastguard Worker        return '%s(%i bytes read%s)' % (self.__class__.__name__,
1496*cda5da8dSAndroid Build Coastguard Worker                                        len(self.partial), e)
1497*cda5da8dSAndroid Build Coastguard Worker    __str__ = object.__str__
1498*cda5da8dSAndroid Build Coastguard Worker
1499*cda5da8dSAndroid Build Coastguard Workerclass ImproperConnectionState(HTTPException):
1500*cda5da8dSAndroid Build Coastguard Worker    pass
1501*cda5da8dSAndroid Build Coastguard Worker
1502*cda5da8dSAndroid Build Coastguard Workerclass CannotSendRequest(ImproperConnectionState):
1503*cda5da8dSAndroid Build Coastguard Worker    pass
1504*cda5da8dSAndroid Build Coastguard Worker
1505*cda5da8dSAndroid Build Coastguard Workerclass CannotSendHeader(ImproperConnectionState):
1506*cda5da8dSAndroid Build Coastguard Worker    pass
1507*cda5da8dSAndroid Build Coastguard Worker
1508*cda5da8dSAndroid Build Coastguard Workerclass ResponseNotReady(ImproperConnectionState):
1509*cda5da8dSAndroid Build Coastguard Worker    pass
1510*cda5da8dSAndroid Build Coastguard Worker
1511*cda5da8dSAndroid Build Coastguard Workerclass BadStatusLine(HTTPException):
1512*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, line):
1513*cda5da8dSAndroid Build Coastguard Worker        if not line:
1514*cda5da8dSAndroid Build Coastguard Worker            line = repr(line)
1515*cda5da8dSAndroid Build Coastguard Worker        self.args = line,
1516*cda5da8dSAndroid Build Coastguard Worker        self.line = line
1517*cda5da8dSAndroid Build Coastguard Worker
1518*cda5da8dSAndroid Build Coastguard Workerclass LineTooLong(HTTPException):
1519*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, line_type):
1520*cda5da8dSAndroid Build Coastguard Worker        HTTPException.__init__(self, "got more than %d bytes when reading %s"
1521*cda5da8dSAndroid Build Coastguard Worker                                     % (_MAXLINE, line_type))
1522*cda5da8dSAndroid Build Coastguard Worker
1523*cda5da8dSAndroid Build Coastguard Workerclass RemoteDisconnected(ConnectionResetError, BadStatusLine):
1524*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, *pos, **kw):
1525*cda5da8dSAndroid Build Coastguard Worker        BadStatusLine.__init__(self, "")
1526*cda5da8dSAndroid Build Coastguard Worker        ConnectionResetError.__init__(self, *pos, **kw)
1527*cda5da8dSAndroid Build Coastguard Worker
1528*cda5da8dSAndroid Build Coastguard Worker# for backwards compatibility
1529*cda5da8dSAndroid Build Coastguard Workererror = HTTPException
1530