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