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