def request(self, method, url, body): headers = dict(self.pulp_connection.headers) # copy so we don't affect the calling method # Create a new connection each time since HTTPSConnection has problems # reusing a connection for multiple calls (lame). ssl_context = None if self.pulp_connection.username and self.pulp_connection.password: raw = ':'.join((self.pulp_connection.username, self.pulp_connection.password)) encoded = base64.encodestring(raw)[:-1] headers['Authorization'] = 'Basic ' + encoded elif self.pulp_connection.cert_filename: ssl_context = SSL.Context('sslv3') ssl_context.set_session_timeout(self.pulp_connection.timeout) ssl_context.load_cert(self.pulp_connection.cert_filename) # Can't pass in None, so need to decide between two signatures (also lame) if ssl_context is not None: connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port, ssl_context=ssl_context) else: connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port) # Request against the server connection.request(method, url, body=body, headers=headers) try: response = connection.getresponse() except SSL.SSLError, err: # Translate stale login certificate to an auth exception if 'sslv3 alert certificate expired' == str(err): raise exceptions.ClientSSLException(self.pulp_connection.cert_filename) else: raise exceptions.ConnectionException(None, str(err), None)
def request(self, method, url, body): headers = dict(self.pulp_connection.headers ) # copy so we don't affect the calling method # Create a new connection each time since HTTPSConnection has problems # reusing a connection for multiple calls (lame). ssl_context = None if self.pulp_connection.username and self.pulp_connection.password: raw = ':'.join( (self.pulp_connection.username, self.pulp_connection.password)) encoded = base64.encodestring(raw)[:-1] headers['Authorization'] = 'Basic ' + encoded elif self.pulp_connection.cert_filename: ssl_context = SSL.Context('sslv3') ssl_context.set_session_timeout(self.pulp_connection.timeout) ssl_context.load_cert(self.pulp_connection.cert_filename) # oauth configuration if self.pulp_connection.oauth_key and self.pulp_connection.oauth_secret: oauth_consumer = oauth.Consumer(self.pulp_connection.oauth_key, self.pulp_connection.oauth_secret) oauth_request = oauth.Request.from_consumer_and_token( oauth_consumer, http_method=method, http_url='https://%s:%d%s' % (self.pulp_connection.host, self.pulp_connection.port, url)) oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), oauth_consumer, None) oauth_header = oauth_request.to_header() # unicode header values causes m2crypto to do odd things. for k, v in oauth_header.items(): oauth_header[k] = encode_unicode(v) headers.update(oauth_header) headers['pulp-user'] = self.pulp_connection.oauth_user # Can't pass in None, so need to decide between two signatures (also lame) if ssl_context is not None: connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port, ssl_context=ssl_context) else: connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port) # Request against the server connection.request(method, url, body=body, headers=headers) try: response = connection.getresponse() except SSL.SSLError, err: # Translate stale login certificate to an auth exception if 'sslv3 alert certificate expired' == str(err): raise exceptions.ClientSSLException( self.pulp_connection.cert_filename) else: raise exceptions.ConnectionException(None, str(err), None)
def test_connection_error(self): """ Tests a client-side connection error. """ # Test e = exceptions.ConnectionException() code = self.exception_handler.handle_connection_error(e) # Verify self.assertEqual(code, handler.CODE_CONNECTION_EXCEPTION) self.assertTrue('contact the server' in self.recorder.lines[0])
def request(self, method, url, body): """ Make the request against the Pulp server, returning a tuple of (status_code, respose_body). This method creates a new connection each time since HTTPSConnection has problems reusing a connection for multiple calls (as claimed by a prior comment in this module). :param method: The HTTP method to be used for the request (GET, POST, etc.) :type method: str :param url: The Pulp URL to make the request against :type url: str :param body: The body to pass with the request :type body: str :return: A 2-tuple of the status_code and response_body. status_code is the HTTP status code (200, 404, etc.). If the server's response is valid json, it will be parsed and response_body will be a dictionary. If not, it will be returned as a string. :rtype: tuple """ headers = dict(self.pulp_connection.headers ) # copy so we don't affect the calling method # Despite the confusing name, 'sslv23' configures m2crypto to use any available protocol in # the underlying openssl implementation. ssl_context = SSL.Context('sslv23') # This restricts the protocols we are willing to do by configuring m2 not to do SSLv2.0 or # SSLv3.0. EL 5 does not have support for TLS > v1.0, so we have to leave support for # TLSv1.0 enabled. ssl_context.set_options(m2.SSL_OP_NO_SSLv2 | m2.SSL_OP_NO_SSLv3) if self.pulp_connection.verify_ssl: ssl_context.set_verify(SSL.verify_peer, depth=100) # We need to stat the ca_path to see if it exists (error if it doesn't), and if so # whether it is a file or a directory. m2crypto has different directives depending on # which type it is. if os.path.isfile(self.pulp_connection.ca_path): ssl_context.load_verify_locations( cafile=self.pulp_connection.ca_path) elif os.path.isdir(self.pulp_connection.ca_path): ssl_context.load_verify_locations( capath=self.pulp_connection.ca_path) else: # If it's not a file and it's not a directory, it's not a valid setting raise exceptions.MissingCAPathException( self.pulp_connection.ca_path) ssl_context.set_session_timeout(self.pulp_connection.timeout) if self.pulp_connection.username and self.pulp_connection.password: raw = ':'.join( (self.pulp_connection.username, self.pulp_connection.password)) encoded = base64.encodestring(raw)[:-1] headers['Authorization'] = 'Basic ' + encoded elif self.pulp_connection.cert_filename: ssl_context.load_cert(self.pulp_connection.cert_filename) # oauth configuration. This block is only True if oauth is not None, so it won't run on RHEL # 5. if self.pulp_connection.oauth_key and self.pulp_connection.oauth_secret and oauth: oauth_consumer = oauth.Consumer(self.pulp_connection.oauth_key, self.pulp_connection.oauth_secret) oauth_request = oauth.Request.from_consumer_and_token( oauth_consumer, http_method=method, http_url='https://%s:%d%s' % (self.pulp_connection.host, self.pulp_connection.port, url)) oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), oauth_consumer, None) oauth_header = oauth_request.to_header() # unicode header values causes m2crypto to do odd things. for k, v in oauth_header.items(): oauth_header[k] = encode_unicode(v) headers.update(oauth_header) headers['pulp-user'] = self.pulp_connection.oauth_user connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port, ssl_context=ssl_context) try: # Request against the server connection.request(method, url, body=body, headers=headers) response = connection.getresponse() except SSL.SSLError, err: # Translate stale login certificate to an auth exception if 'sslv3 alert certificate expired' == str(err): raise exceptions.ClientCertificateExpiredException( self.pulp_connection.cert_filename) elif 'certificate verify failed' in str(err): raise exceptions.CertificateVerificationException() else: raise exceptions.ConnectionException(None, str(err), None)
def test_handle_exception(self): """ Tests the high level call that branches based on exception type for all types. """ # For each exception type, check that the proper code is returned and # that a failure message has been output. For simplicity in those tests, # reset the tags after each run. code = self.exception_handler.handle_exception( exceptions.BadRequestException({})) self.assertEqual(code, handler.CODE_BAD_REQUEST) self.assertEqual(3, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ConflictException({})) self.assertEqual(code, handler.CODE_CONFLICT) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ConnectionException({})) self.assertEqual(code, handler.CODE_CONNECTION_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.NotFoundException({'resources': { 'repo_id': 'foo' }})) self.assertEqual(code, handler.CODE_NOT_FOUND) self.assertEqual(2, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.PermissionsException({})) self.assertEqual(code, handler.CODE_PERMISSIONS_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.PulpServerException({})) self.assertEqual(code, handler.CODE_PULP_SERVER_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( InvalidConfig('Test Message')) self.assertEqual(code, handler.CODE_INVALID_CONFIG) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( WrongHost('expected', 'actual')) self.assertEqual(code, handler.CODE_WRONG_HOST) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ApacheServerException('Test Message')) self.assertEqual(code, handler.CODE_APACHE_SERVER_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(gaierror()) self.assertEqual(code, handler.CODE_UNKNOWN_HOST) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(socket_error()) self.assertEqual(code, handler.CODE_SOCKET_ERROR) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ClientCertificateExpiredException(CERT_FILENAME)) self.assertEqual(code, handler.CODE_PERMISSIONS_EXCEPTION) self.assertEqual([TAG_FAILURE, TAG_PARAGRAPH], self.prompt.get_write_tags()) self.prompt.tags = [] code = self.exception_handler.handle_exception(Exception({})) self.assertEqual(code, handler.CODE_UNEXPECTED) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = []