def connect(self): """Connect to SSL port and apply per-connection parameters.""" try: addresses = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM) except OSError as msg: raise exc.RestClientException(msg) for res in addresses: af, socktype, proto, canonname, sa = res sock = socket.socket(af, socket.SOCK_STREAM) if self.timeout is not None: # '0' microseconds sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, struct.pack('LL', self.timeout, 0)) self.sock = OpenSSLConnectionDelegator(self.context, sock) try: self.sock.connect(sa) except OSError as msg: if self.sock: self.sock = None continue break if self.sock is None: # Happen only when all results have failed. raise exc.RestClientException('Cannot connect to %s' % self.host)
def _error_checker(self, method, url, headers, body, resp, resp_body): # NOTE(mtreinish): Check for httplib response from glance_http. The # object can't be used here because importing httplib breaks httplib2. # If another object from a class not imported were passed here as # resp this could possibly fail if str(type(resp)) == "<type 'instance'>": ctype = resp.getheader('content-type') else: try: ctype = resp['content-type'] # NOTE(mtreinish): Keystone delete user responses doesn't have a # content-type header. (They don't have a body) So just pretend it # is set. except KeyError: ctype = 'application/json' # It is not an error response if resp.status < 400: return JSON_ENC = [ 'application/json; charset=UTF-8', 'application/json', 'application/json; charset=utf-8' ] # NOTE(mtreinish): This is for compatibility with Glance and swift # APIs. These are the return content types that Glance api v1 # (and occasionally swift) are using. TXT_ENC = [ 'text/plain; charset=UTF-8', 'text/html; charset=UTF-8', 'text/plain; charset=utf-8' ] XML_ENC = ['application/xml', 'application/xml; charset=UTF-8'] if ctype in JSON_ENC or ctype in XML_ENC: parse_resp = True elif ctype in TXT_ENC: parse_resp = False else: raise exceptions.RestClientException(str(resp.status)) if resp.status == 401 or resp.status == 403: raise exceptions.Unauthorized() if resp.status == 404: raise exceptions.NotFound(resp_body) if resp.status == 400: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.BadRequest(resp_body) if resp.status == 409: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.Duplicate(resp_body) if resp.status == 413: if parse_resp: resp_body = self._parse_resp(resp_body) if self.is_absolute_limit(resp, resp_body): raise exceptions.OverLimit(resp_body) else: raise exceptions.RateLimitExceeded(resp_body) if resp.status == 422: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.UnprocessableEntity(resp_body) if resp.status in (500, 501): message = resp_body if parse_resp: resp_body = self._parse_resp(resp_body) #I'm seeing both computeFault and cloudServersFault come back. #Will file a bug to fix, but leave as is for now. if 'cloudServersFault' in resp_body: message = resp_body['cloudServersFault']['message'] elif 'computeFault' in resp_body: message = resp_body['computeFault']['message'] elif 'error' in resp_body: # Keystone errors message = resp_body['error']['message'] raise exceptions.IdentityError(message) elif 'message' in resp_body: message = resp_body['message'] raise exceptions.ComputeFault(message) if resp.status >= 400: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.RestClientException(str(resp.status))