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