def __init__(self, method=None, url=None, headers=None, data=None, params=None, auth_path=None, stream_output=False): self._request_preparer = self._REQUEST_PREPARER_CLS() # Default empty dicts for dict params. params = {} if params is None else params self.method = method self.url = url self.headers = HTTPHeaders() self.data = data self.params = params self.auth_path = auth_path self.stream_output = stream_output if headers is not None: for key, value in headers.items(): self.headers[key] = value # This is a dictionary to hold information that is used when # processing the request. What is inside of ``context`` is open-ended. # For example, it may have a timestamp key that is used for holding # what the timestamp is when signing the request. Note that none # of the information that is inside of ``context`` is directly # sent over the wire; the information is only used to assist in # creating what is sent over the wire. self.context = {}
def test_duplicate_headers(self): pairs = [('Date', 'Thu, 17 Nov 2005 18:49:58 GMT'), ('Content-Md5', 'c8fdb181845a4ca6b8fec737b3581d76'), ('Content-Type', 'text/html'), ('X-Amz-Meta-Author', '*****@*****.**'), ('X-Amz-Meta-Author', '*****@*****.**'), ('X-Amz-Magic', 'abracadabra')] http_headers = HTTPHeaders.from_pairs(pairs) split = urlsplit('/quotes/nelson') sig = self.hmacv1.get_signature('PUT', split, http_headers) self.assertEqual(sig, 'kIdMxyiYB+F+83zYGR6sSb3ICcE=')
def headers_to_sign(self, request): """ Select the headers from the request that need to be included in the StringToSign. """ header_map = HTTPHeaders() split = urlsplit(request.url) for name, value in request.headers.items(): lname = name.lower() if lname not in SIGNED_HEADERS_BLACKLIST: header_map[lname] = value if 'host' not in header_map: header_map['host'] = split.netloc return header_map
def headers_to_sign(self, request): """ Select the headers from the request that need to be included in the StringToSign. """ header_map = HTTPHeaders() for name, value in request.headers.items(): lname = name.lower() if lname not in SIGNED_HEADERS_BLACKLIST: header_map[lname] = value if 'host' not in header_map: # TODO: We should set the host ourselves, instead of relying on our # HTTP client to set it for us. header_map['host'] = _host_from_url(request.url) return header_map
def headers_to_sign(self, request): """ Select the headers from the request that need to be included in the StringToSign. """ header_map = HTTPHeaders() for name, value in request.headers.items(): lname = name.lower() if lname not in SIGNED_HEADERS_BLACKLIST: header_map[lname] = value if 'host' not in header_map: # Ensure we sign the lowercased version of the host, as that # is what will ultimately be sent on the wire. # TODO: We should set the host ourselves, instead of relying on our # HTTP client to set it for us. header_map['host'] = self._canonical_host(request.url).lower() return header_map
def test_put(self): headers = {'Date': 'Thu, 17 Nov 2005 18:49:58 GMT', 'Content-Md5': 'c8fdb181845a4ca6b8fec737b3581d76', 'Content-Type': 'text/html', 'X-Amz-Meta-Author': '*****@*****.**', 'X-Amz-Magic': 'abracadabra'} http_headers = HTTPHeaders.from_dict(headers) split = urlsplit('/quotes/nelson') cs = self.hmacv1.canonical_string('PUT', split, http_headers) expected_canonical = ( "PUT\nc8fdb181845a4ca6b8fec737b3581d76\ntext/html\n" "Thu, 17 Nov 2005 18:49:58 GMT\nx-amz-magic:abracadabra\n" "x-amz-meta-author:[email protected]\n/quotes/nelson") expected_signature = 'jZNOcbfWmD/A/f3hSvVzXZjM2HU=' self.assertEqual(cs, expected_canonical) sig = self.hmacv1.get_signature('PUT', split, http_headers) self.assertEqual(sig, expected_signature)
def __init__(self, *args, **kwargs): self.auth_path = None if 'auth_path' in kwargs: self.auth_path = kwargs['auth_path'] del kwargs['auth_path'] models.Request.__init__(self, *args, **kwargs) headers = HTTPHeaders() if self.headers is not None: for key, value in self.headers.items(): headers[key] = value self.headers = headers # This is a dictionary to hold information that is used when # processing the request. What is inside of ``context`` is open-ended. # For example, it may have a timestamp key that is used for holding # what the timestamp is when signing the request. Note that none # of the information that is inside of ``context`` is directly # sent over the wire; the information is only used to assist in # creating what is sent over the wire. self.context = {}
def test_query_string(self): split = urlsplit('/quotes/nelson?uploads') pairs = [('Date', 'Thu, 17 Nov 2005 18:49:58 GMT')] sig = self.hmacv1.get_signature('PUT', split, HTTPHeaders.from_pairs(pairs)) self.assertEqual(sig, 'P7pBz3Z4p3GxysRSJ/gR8nk7D4o=')
def test_trims_leading_trailing_spaces(self): auth = self.create_signer() original = HTTPHeaders() original['foo'] = ' leading and trailing ' headers = auth.canonical_headers(original) self.assertEqual(headers, 'foo:leading and trailing')
def test_collapse_multiple_spaces(self): auth = self.create_signer() original = HTTPHeaders() original['foo'] = 'double space' headers = auth.canonical_headers(original) self.assertEqual(headers, 'foo:double space')