Exemple #1
0
 def __init__(self,
              region_name,
              host,
              auth,
              user_agent,
              signature_version,
              endpoint_prefix,
              event_emitter,
              proxies=None,
              verify=True,
              timeout=DEFAULT_TIMEOUT):
     self._endpoint_prefix = endpoint_prefix
     self._signature_version = signature_version
     self._event_emitter = event_emitter
     self._user_agent = user_agent
     self.region_name = region_name
     self.host = host
     self.verify = verify
     self.auth = auth
     if proxies is None:
         proxies = {}
     self.proxies = proxies
     self.http_session = Session()
     self.timeout = timeout
     self._lock = threading.Lock()
 def __init__(self, region_name, host, auth, user_agent, signature_version,
              endpoint_prefix, event_emitter, proxies=None, verify=True,
              timeout=DEFAULT_TIMEOUT):
     self._endpoint_prefix = endpoint_prefix
     self._signature_version = signature_version
     self._event_emitter = event_emitter
     self._user_agent = user_agent
     self.region_name = region_name
     self.host = host
     self.verify = verify
     self.auth = auth
     if proxies is None:
         proxies = {}
     self.proxies = proxies
     self.http_session = Session()
     self.timeout = timeout
     self._lock = threading.Lock()
class Endpoint(object):
    """
    Represents an endpoint for a particular service in a specific
    region.  Only an endpoint can make requests.

    :ivar service: The Service object that describes this endpoints
        service.
    :ivar host: The fully qualified endpoint hostname.
    :ivar session: The session object.
    """

    def __init__(self, region_name, host, auth, user_agent, signature_version,
                 endpoint_prefix, event_emitter, proxies=None, verify=True,
                 timeout=DEFAULT_TIMEOUT):
        self._endpoint_prefix = endpoint_prefix
        self._signature_version = signature_version
        self._event_emitter = event_emitter
        self._user_agent = user_agent
        self.region_name = region_name
        self.host = host
        self.verify = verify
        self.auth = auth
        if proxies is None:
            proxies = {}
        self.proxies = proxies
        self.http_session = Session()
        self.timeout = timeout
        self._lock = threading.Lock()

    def __repr__(self):
        return '%s(%s)' % (self._endpoint_prefix, self.host)

    def make_request(self, operation_model, request_dict):
        logger.debug("Making request for %s (verify_ssl=%s) with params: %s",
                     operation_model, self.verify, request_dict)
        prepared_request = self.create_request(request_dict)
        return self._send_request(prepared_request, operation_model)

    def create_request(self, params, signer=None):
        # To decide if we need to do auth or not we check the
        # signature_version attribute on both the service and
        # the operation are not None and we make sure there is an
        # auth class associated with the endpoint.
        # If any of these are not true, we skip auth.
        if signer is not None:
            # If the user explicitly specifies a signer, then we will sign
            # the request.
            signer = signer
        else:
            do_auth = self._signature_version and self.auth
            if do_auth:
                signer = self.auth
            else:
                # If we're not suppose to sign the request, then we set the signer
                # to None.
                signer = None
        request = self._create_request_object(params)
        prepared_request = self.prepare_request(request, signer)
        return prepared_request

    def _create_request_object(self, request_dict):
        r = request_dict
        user_agent = self._user_agent
        headers = r['headers']
        headers['User-Agent'] = user_agent
        url = urljoin(self.host, r['url_path'])
        if r['query_string']:
            encoded_query_string = percent_encode_sequence(r['query_string'])
            if '?' not in url:
                url += '?%s' % encoded_query_string
            else:
                url += '&%s' % encoded_query_string
        request = AWSRequest(method=r['method'], url=url,
                             data=r['body'],
                             headers=headers)
        return request

    def prepare_request(self, request, signer):
        if signer is not None:
            with self._lock:
                # Parts of the auth signing code aren't thread safe (things
                # that manipulate .auth_path), so we're using a lock here to
                # prevent race conditions.
                event_name = 'before-auth.%s' % self._endpoint_prefix
                self._event_emitter.emit(
                    event_name, endpoint=self, request=request, auth=signer)
                signer.add_auth(request=request)
        prepared_request = request.prepare()
        return prepared_request

    def _send_request(self, request, operation_model):
        attempts = 1
        response, exception = self._get_response(request, operation_model, attempts)
        while self._needs_retry(attempts, operation_model, response, exception):
            attempts += 1
            # If there is a stream associated with the request, we need
            # to reset it before attempting to send the request again.
            # This will ensure that we resend the entire contents of the
            # body.
            request.reset_stream()
            response, exception = self._get_response(request, operation_model,
                                                     attempts)
        return response

    def _get_response(self, request, operation_model, attempts):
        try:
            logger.debug("Sending http request: %s", request)
            http_response = self.http_session.send(
                request, verify=self.verify,
                stream=operation_model.has_streaming_output,
                proxies=self.proxies, timeout=self.timeout)
        except Exception as e:
            logger.debug("Exception received when sending HTTP request.",
                         exc_info=True)
            return (None, e)
        # This returns the http_response and the parsed_data.
        return (botocore_eb.response.get_response(operation_model,
                                               http_response), None)

    def _needs_retry(self, attempts, operation_model, response=None,
                     caught_exception=None):
        event_name = 'needs-retry.%s.%s' % (self._endpoint_prefix,
                                            operation_model.name)
        responses = self._event_emitter.emit(
            event_name, response=response, endpoint=self,
            operation=operation_model, attempts=attempts,
            caught_exception=caught_exception)
        handler_response = first_non_none_response(responses)
        if handler_response is None:
            return False
        else:
            # Request needs to be retried, and we need to sleep
            # for the specified number of times.
            logger.debug("Response received to retry, sleeping for "
                         "%s seconds", handler_response)
            time.sleep(handler_response)
            return True
Exemple #4
0
class Endpoint(object):
    """
    Represents an endpoint for a particular service in a specific
    region.  Only an endpoint can make requests.

    :ivar service: The Service object that describes this endpoints
        service.
    :ivar host: The fully qualified endpoint hostname.
    :ivar session: The session object.
    """
    def __init__(self,
                 region_name,
                 host,
                 auth,
                 user_agent,
                 signature_version,
                 endpoint_prefix,
                 event_emitter,
                 proxies=None,
                 verify=True,
                 timeout=DEFAULT_TIMEOUT):
        self._endpoint_prefix = endpoint_prefix
        self._signature_version = signature_version
        self._event_emitter = event_emitter
        self._user_agent = user_agent
        self.region_name = region_name
        self.host = host
        self.verify = verify
        self.auth = auth
        if proxies is None:
            proxies = {}
        self.proxies = proxies
        self.http_session = Session()
        self.timeout = timeout
        self._lock = threading.Lock()

    def __repr__(self):
        return '%s(%s)' % (self._endpoint_prefix, self.host)

    def make_request(self, operation_model, request_dict):
        logger.debug("Making request for %s (verify_ssl=%s) with params: %s",
                     operation_model, self.verify, request_dict)
        prepared_request = self.create_request(request_dict)
        return self._send_request(prepared_request, operation_model)

    def create_request(self, params, signer=None):
        # To decide if we need to do auth or not we check the
        # signature_version attribute on both the service and
        # the operation are not None and we make sure there is an
        # auth class associated with the endpoint.
        # If any of these are not true, we skip auth.
        if signer is not None:
            # If the user explicitly specifies a signer, then we will sign
            # the request.
            signer = signer
        else:
            do_auth = self._signature_version and self.auth
            if do_auth:
                signer = self.auth
            else:
                # If we're not suppose to sign the request, then we set the signer
                # to None.
                signer = None
        request = self._create_request_object(params)
        prepared_request = self.prepare_request(request, signer)
        return prepared_request

    def _create_request_object(self, request_dict):
        r = request_dict
        user_agent = self._user_agent
        headers = r['headers']
        headers['User-Agent'] = user_agent
        url = urljoin(self.host, r['url_path'])
        if r['query_string']:
            encoded_query_string = percent_encode_sequence(r['query_string'])
            if '?' not in url:
                url += '?%s' % encoded_query_string
            else:
                url += '&%s' % encoded_query_string
        request = AWSRequest(method=r['method'],
                             url=url,
                             data=r['body'],
                             headers=headers)
        return request

    def prepare_request(self, request, signer):
        if signer is not None:
            with self._lock:
                # Parts of the auth signing code aren't thread safe (things
                # that manipulate .auth_path), so we're using a lock here to
                # prevent race conditions.
                event_name = 'before-auth.%s' % self._endpoint_prefix
                self._event_emitter.emit(event_name,
                                         endpoint=self,
                                         request=request,
                                         auth=signer)
                signer.add_auth(request=request)
        prepared_request = request.prepare()
        return prepared_request

    def _send_request(self, request, operation_model):
        attempts = 1
        response, exception = self._get_response(request, operation_model,
                                                 attempts)
        while self._needs_retry(attempts, operation_model, response,
                                exception):
            attempts += 1
            # If there is a stream associated with the request, we need
            # to reset it before attempting to send the request again.
            # This will ensure that we resend the entire contents of the
            # body.
            request.reset_stream()
            response, exception = self._get_response(request, operation_model,
                                                     attempts)
        return response

    def _get_response(self, request, operation_model, attempts):
        try:
            logger.debug("Sending http request: %s", request)
            http_response = self.http_session.send(
                request,
                verify=self.verify,
                stream=operation_model.has_streaming_output,
                proxies=self.proxies,
                timeout=self.timeout)
        except Exception as e:
            logger.debug("Exception received when sending HTTP request.",
                         exc_info=True)
            return (None, e)
        # This returns the http_response and the parsed_data.
        return (botocore_eb.response.get_response(operation_model,
                                                  http_response), None)

    def _needs_retry(self,
                     attempts,
                     operation_model,
                     response=None,
                     caught_exception=None):
        event_name = 'needs-retry.%s.%s' % (self._endpoint_prefix,
                                            operation_model.name)
        responses = self._event_emitter.emit(event_name,
                                             response=response,
                                             endpoint=self,
                                             operation=operation_model,
                                             attempts=attempts,
                                             caught_exception=caught_exception)
        handler_response = first_non_none_response(responses)
        if handler_response is None:
            return False
        else:
            # Request needs to be retried, and we need to sleep
            # for the specified number of times.
            logger.debug(
                "Response received to retry, sleeping for "
                "%s seconds", handler_response)
            time.sleep(handler_response)
            return True