예제 #1
0
 def _modify_request_before_signing(self, request):
     # Note that we're not including X-Amz-Signature.
     # From the docs: "The Canonical Query String must include all the query
     # parameters from the preceding table except for X-Amz-Signature.
     signed_headers = self.signed_headers(self.headers_to_sign(request))
     auth_params = {
         'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
         'X-Amz-Credential': self.scope(request),
         'X-Amz-Date': request.context['timestamp'],
         'X-Amz-Expires': self._expires,
         'X-Amz-SignedHeaders': signed_headers,
     }
     if self.credentials.token is not None:
         auth_params['X-Amz-Security-Token'] = self.credentials.token
     # Now parse the original query string to a dict, inject our new query
     # params, and serialize back to a query string.
     url_parts = urlsplit(request.url)
     # parse_qs makes each value a list, but in our case we know we won't
     # have repeated keys so we know we have single element lists which we
     # can convert back to scalar values.
     query_dict = dict(
         [(k, v[0]) for k, v in parse_qs(url_parts.query).items()])
     # The spec is particular about this.  It *has* to be:
     # https://<endpoint>?<operation params>&<auth params>
     # You can't mix the two types of params together, i.e just keep doing
     # new_query_params.update(op_params)
     # new_query_params.update(auth_params)
     # percent_encode_sequence(new_query_params)
     operation_params = ''
     if request.data:
         # We also need to move the body params into the query string.
         # request.data will be populated, for example, with query services
         # which normally form encode the params into the body.
         # This means that request.data is a dict() of the operation params.
         query_dict.update(request.data)
         request.data = ''
     if query_dict:
         operation_params = percent_encode_sequence(query_dict) + '&'
     new_query_string = (operation_params +
                         percent_encode_sequence(auth_params))
     # url_parts is a tuple (and therefore immutable) so we need to create
     # a new url_parts with the new query string.
     # <part>   - <index>
     # scheme   - 0
     # netloc   - 1
     # path     - 2
     # query    - 3  <-- we're replacing this.
     # fragment - 4
     p = url_parts
     new_url_parts = (p[0], p[1], p[2], new_query_string, p[4])
     request.url = urlunsplit(new_url_parts)
예제 #2
0
def prepare_request_dict(request_dict, endpoint_url, user_agent=None):
    """
    This method prepares a request dict to be created into an
    KSRequestObject. This prepares the request dict by adding the
    url and the user agent to the request dict.

    :type request_dict: dict
    :param request_dict:  The request dict (created from the
        ``serialize`` module).

    :type user_agent: string
    :param user_agent: The user agent to use for this request.

    :type endpoint_url: string
    :param endpoint_url: The full endpoint url, which contains at least
        the scheme, the hostname, and optionally any path components.
    """
    r = request_dict
    if user_agent is not None:
        headers = r['headers']
        headers['User-Agent'] = user_agent
    url = _urljoin(endpoint_url, 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
    r['url'] = url
예제 #3
0
def prepare_request_dict(request_dict, endpoint_url, user_agent=None):
    """
    This method prepares a request dict to be created into an
    KSRequestObject. This prepares the request dict by adding the
    url and the user agent to the request dict.

    :type request_dict: dict
    :param request_dict:  The request dict (created from the
        ``serialize`` module).

    :type user_agent: string
    :param user_agent: The user agent to use for this request.

    :type endpoint_url: string
    :param endpoint_url: The full endpoint url, which contains at least
        the scheme, the hostname, and optionally any path components.
    """
    r = request_dict
    if user_agent is not None:
        headers = r['headers']
        headers['User-Agent'] = user_agent
    url = _urljoin(endpoint_url, 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
    r['url'] = url
예제 #4
0
    def _inject_signature(self, request, signature):
        query_dict = {}
        query_dict['AWSAccessKeyId'] = self.credentials.access_key
        query_dict['Signature'] = signature

        for header_key in request.headers:
            lk = header_key.lower()
            # For query string requests, Expires is used instead of the
            # Date header.
            if header_key == 'Date':
                query_dict['Expires'] = request.headers['Date']
            # We only want to include relevant headers in the query string.
            # These can be anything that starts with x-amz, is Content-MD5,
            # or is Content-Type.
            elif lk.startswith('x-amz-') or lk in ['content-md5',
                                                   'content-type']:
                query_dict[lk] = request.headers[lk]
        # Combine all of the identified headers into an encoded
        # query string
        new_query_string = percent_encode_sequence(query_dict)

        # Create a new url with the presigned url.
        p = urlsplit(request.url)
        if p[3]:
            # If there was a pre-existing query string, we should
            # add that back before injecting the new query string.
            new_query_string ='%s&%s' % (p[3], new_query_string)
        new_url_parts = (p[0], p[1], p[2], new_query_string, p[4])
        request.url = urlunsplit(new_url_parts)