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