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