def getPage(self, url, headers=None, method="GET", body=None, protocol=None): """Open the url with debugging support. Return status, headers, body.""" ServerError.on = False url = always_bytes(url) body = always_bytes(body) self.url = url self.time = None start = time.time() result = openURL(url, headers, method, body, self.HOST, self.PORT, self.HTTP_CONN, protocol or self.PROTOCOL) self.time = time.time() - start self.status, self.headers, self.body = result # Build a list of request cookies from the previous response cookies. self.cookies = [('Cookie', v) for k, v in self.headers if k.lower() == 'set-cookie'] if ServerError.on: raise ServerError() return result
def openURL(url, headers=None, method="GET", body=None, host="127.0.0.1", port=8000, http_conn=HTTPConnection, protocol="HTTP/1.1"): """Open the given HTTP resource and return status, headers, and body.""" headers = cleanHeaders(headers, method, body, host, port) # Trying 10 times is simply in case of socket errors. # Normal case--it should run once. for trial in range(10): try: # Allow http_conn to be a class or an instance if hasattr(http_conn, "host"): conn = http_conn else: conn = http_conn(interface(host), port) conn._http_vsn_str = protocol conn._http_vsn = int("".join([x for x in protocol if x.isdigit()])) # skip_accept_encoding argument added in python version 2.4 if sys.version_info < (2, 4): def putheader(self, header, value): if header == 'Accept-Encoding' and value == 'identity': return self.__class__.putheader(self, header, value) import new conn.putheader = new.instancemethod(putheader, conn, conn.__class__) conn.putrequest(method.upper(), url, skip_host=True) elif not py3k: conn.putrequest(method.upper(), url, skip_host=True, skip_accept_encoding=True) else: import http.client # Replace the stdlib method, which only accepts ASCII url's def putrequest(self, method, url): if self._HTTPConnection__response and self._HTTPConnection__response.isclosed(): self._HTTPConnection__response = None if self._HTTPConnection__state == http.client._CS_IDLE: self._HTTPConnection__state = http.client._CS_REQ_STARTED else: raise http.client.CannotSendRequest() self._method = method if not url: url = ntob('/') request = ntob(' ').join((method.encode("ASCII"), url, self._http_vsn_str.encode("ASCII"))) self._output(request) import types conn.putrequest = types.MethodType(putrequest, conn) conn.putrequest(method.upper(), url) for key, value in headers: conn.putheader(key, always_bytes(value, "Latin-1")) conn.endheaders() if body is not None: conn.send(body) # Handle response response = conn.getresponse() s, h, b = shb(response) if not hasattr(http_conn, "host"): # We made our own conn instance. Close it. conn.close() return s, h, b except socket.error: time.sleep(0.5) if trial == 9: raise