def query_string(self, http_request): parameter_names = sorted(http_request.params.keys()) pairs = [] for pname in parameter_names: pval = txboto.utils.get_utf8_value(http_request.params[pname]) pairs.append(quote(pname, safe='') + '=' + quote(pval, safe='-_~')) return '&'.join(pairs)
def canonical_query_string(self, http_request): # Note that we just do not return an empty string for # POST request. Query strings in url are included in canonical # query string. l = [] for param in sorted(http_request.params): value = txboto.utils.get_utf8_value(http_request.params[param]) l.append('%s=%s' % (quote(param, safe='-_.~'), quote(value, safe='-_.~'))) return '&'.join(l)
def canonical_query_string(self, http_request): # POST requests pass parameters in through the # http_request.body field. if http_request.method == 'POST': return "" l = [] for param in sorted(http_request.params): value = txboto.utils.get_utf8_value(http_request.params[param]) l.append('%s=%s' % (quote(param, safe='-_.~'), quote(value, safe='-_.~'))) return '&'.join(l)
def canonical_uri(self, http_request): # S3 does **NOT** do path normalization that SigV4 typically does. # Urlencode the path, **NOT** ``auth_path`` (because vhosting). path = urlparse(http_request.path) # Because some quoting may have already been applied, let's back it out. unquoted = unquote(path.path) # Requote, this time addressing all characters. encoded = quote(unquoted) return encoded
def canonical_uri(self, http_request): path = http_request.auth_path # Normalize the path # in windows normpath('/') will be '\\' so we chane it back to '/' normalized = posixpath.normpath(path).replace('\\', '/') # Then urlencode whatever's left. encoded = quote(normalized) if len(path) > 1 and path.endswith('/'): encoded += '/' return encoded
def _calc_signature(self, params, verb, path, server_name): txboto.log.debug('using _calc_signature_2') string_to_sign = '%s\n%s\n%s\n' % (verb, server_name.lower(), path) hmac = self._get_hmac() params['SignatureMethod'] = self.algorithm() if self._provider.security_token: params['SecurityToken'] = self._provider.security_token keys = sorted(params.keys()) pairs = [] for key in keys: val = txboto.utils.get_utf8_value(params[key]) pairs.append(quote(key, safe='') + '=' + quote(val, safe='-_~')) qs = '&'.join(pairs) txboto.log.debug('query string: %s' % qs) string_to_sign += qs txboto.log.debug('string_to_sign: %s' % string_to_sign) hmac.update(string_to_sign.encode('utf-8')) b64 = base64.b64encode(hmac.digest()) txboto.log.debug('len(b64)=%d' % len(b64)) txboto.log.debug('base64 encoded digest: %s' % b64) return (qs, b64)
def _calc_signature(self, params, *args): txboto.log.debug('using _calc_signature_1') hmac = self._get_hmac() keys = params.keys() keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower())) pairs = [] for key in keys: hmac.update(key.encode('utf-8')) val = txboto.utils.get_utf8_value(params[key]) hmac.update(val) pairs.append(key + '=' + quote(val)) qs = '&'.join(pairs) return (qs, base64.b64encode(hmac.digest()))
def authorize(self, connection, **kwargs): if not getattr(self, '_headers_quoted', False): for key in self.headers: val = self.headers[key] if isinstance(val, six.text_type): safe = '!"#$%&\'()*+,/:;<=>?@[\\]^`{|}~' self.headers[key] = quote(val.encode('utf-8'), safe) setattr(self, '_headers_quoted', True) self.headers['User-Agent'] = UserAgent connection._auth_handler.add_auth(self, **kwargs) # I'm not sure if this is still needed, now that add_auth is # setting the content-length for POST requests. if 'Content-Length' not in self.headers: if 'Transfer-Encoding' not in self.headers or \ self.headers['Transfer-Encoding'] != 'chunked': self.headers['Content-Length'] = str(len(self.body))
def _escape_value(self, value): # This is changed from a previous version because this string is # being passed to the query string and query strings must # be url encoded. In particular STS requires the saml_response to # be urlencoded when calling assume_role_with_saml. return quote(value)