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