Пример #1
0
def upload_pseudo_file(bucket, key_name, length,
                       chunk_size_list=None, **kwargs):
    '''Set contents of key from pseudofile with large size.
    '''
    if 'headers' in kwargs:
        headers = kwargs['headers'].copy()
    else:
        headers = {}

    if 'query_args' in kwargs:
        query_args = kwargs['query_args']
    else:
        query_args = None

    # Overwrite user-supplied user-agent.
    for header in find_matching_headers('User-Agent', headers):
        del headers[header]
    headers['User-Agent'] = UserAgent

    # Overwrite user-supplied date.
    for header in find_matching_headers('Date', headers):
        del headers[header]

    utc_time = time.strftime('%a, %d %b %Y %H:%M:%S GMT',
                             time.localtime(time.time()))
    headers['Date'] = utc_time

    hash_string = 'PUT' + '\n' + '\n' + '\n' + utc_time + '\n'

    request_resource = '/' + urllib.quote(bucket.name, '') + \
                       '/' + urllib.quote(key_name, '')

    if query_args:
        request_resource += '?' + query_args
    hash_string += request_resource

    signature = get_signature(bucket.connection.provider.secret_key,
                              hash_string)
    authorization = 'AWS' + ' ' + bucket.connection.provider.access_key + \
                    ":" + signature

    pseudofile = filehelper.PseudoFile(length)
    if not find_matching_headers('Content-Length', headers):
        headers['Content-Length'] = length

    if not find_matching_headers('Authorization', headers):
        headers['Authorization'] = authorization

    return pseudofile, _make_request(bucket, 'PUT', request_resource,
                                     headers, pseudofile)
Пример #2
0
def request(method, url, access_key, secret_key, **kwargs):
    """Sends request with different method
    This is to construct a whole headers by adding basic header
    e.g. Date/Authorization besides user defined.
    And also sort params by its name for signature.
    """
    if access_key is None:
        access_key = cfg["ACCESS_KEY"]
    if secret_key is None:
        secret_key = cfg["ACCESS_SECRET"]
    logger.debug("access_key: %s, secret_key: %s", access_key, secret_key)

    if "headers" in kwargs:
        headers = kwargs["headers"].copy()
    else:
        headers = {}

    if not find_matching_headers(constants.DATE, headers):
        headers[constants.DATE] = formatdate(usegmt=True)

    string_to_sign = "%s\n" % method
    if find_matching_headers(constants.CONTENT_MD5, headers):
        string_to_sign += "%s\n" % headers[constants.CONTENT_MD5]
    else:
        string_to_sign += "\n"

    if find_matching_headers(constants.CONTENT_TYPE, headers):
        string_to_sign += "%s\n" % headers[constants.CONTENT_TYPE]
    else:
        string_to_sign += "\n"

    string_to_sign += headers[constants.DATE] + "\n"

    # Sort canonicalizedAmzHeaders by name
    amz_keys = [h for h in headers if h.lower().startswith("x-amz-")]
    amz_keys.sort()
    for key in amz_keys:
        string_to_sign += "%s:%s\n" % (key, headers[key].strip())

    canonicalized_resource = ""

    # The subresources that must be included
    # when constructing the CanonicalizedResource
    # for calculating signature.
    subresources = [
        "acl",
        "lifecycle",
        "location",
        "logging",
        "notification",
        "partNumber",
        "policy",
        "requestPayment",
        "torrent",
        "uploadId",
        "uploads",
        "versionId",
        "versioning",
        "versions",
        "website",
    ]

    _, _, _, _, path, _, _ = parse_url(url)

    if not path:
        path = "/"

    canonicalized_resource += path

    if "params" in kwargs:
        params = kwargs["params"].copy()
    else:
        params = {}

    subresource_without_value = []
    subresource_to_sign = []

    # Sort subresource by name, otherwise signature will not match.
    # If the value of key in dict params is none, e.g. ?acl,
    # it will not be appended to query string by requests parsing.
    # So need to pick it up from params to query string by manual.
    params = sorted(params.items(), key=lambda d: d[0])
    for key, value in params:
        if key in subresources:
            # subresource has value
            if value is not None:
                subresource_to_sign.append("%s=%s" % (key, value))
            else:
                subresource_to_sign.append("%s" % key)
                subresource_without_value.append("%s" % key)
        else:
            if value is None:
                subresource_without_value.append("%s" % key)

    if subresource_to_sign:
        canonicalized_resource += "?"
        canonicalized_resource += "&".join(subresource_to_sign)

    if subresource_without_value:
        url += "?"
        url += "&".join(subresource_without_value)

    string_to_sign += canonicalized_resource
    logger.debug("string to sign:\n%s", string_to_sign)
    logger.debug("request url:\n%s", url)

    headers[constants.AUTHORIZATION] = "AWS %s:%s" % (access_key, utils.get_signature(secret_key, string_to_sign))
    logger.debug("headers is " + repr(headers))

    if "verify" not in kwargs:
        kwargs["verify"] = False

    kwargs["timeout"] = cfg["REQUEST_TIMEOUT"]
    kwargs["headers"] = headers
    logger.debug("kwargs headers is " + repr(kwargs["headers"]))
    kwargs["params"] = params
    logger.debug("kwargs params is " + repr(kwargs["params"]))

    session = requests.Session()
    response = session.request(method, url, **kwargs)
    return response