def url_append_query(url, query): """ Appends query params to any existing query string in the URL and returns a properly formatted URL. URL fragments are preserved. This is the equivalent of doing:: sorted(URL query parameters) + "&" + sorted(query) :param url: The URL into which the query parameters will be concatenated. :param query: A dictionary of query parameters or a query string. :returns: A URL with the query parameters concatenated. Usage:: >>> url_append_query("http://example.com/foo?a=b#fragment", dict(c="d")) 'http://example.com/foo?a=b&c=d#fragment' """ if not query: return url scheme, netloc, path, params, query_s, fragment = urlparse_normalized(url) query_s = (query_s + SYMBOL_AMPERSAND) if query_s else query_s query_s = query_s + urlencode_s(query_unflatten(query)) return urlunparse((scheme, netloc, path, params, query_s, fragment))
def url_add_query(url, query, predicate=None): """ Adds additional query parameters to a URL while preserving existing ones. The URL will be normalized according to the OAuth specification with the exception that the URL fragment is preserved. :param url: The URL to add the additional query parameters to. :param query: The additional query parameters as a dictionary object or a query string. :param predicate: A callback that will be called for each query parameter and should return ``False`` or a falsy value if that parameter should not be included. By default, all query parameters are included. The function takes the following method signature:: def predicate(name, value): return is_name_allowed(name) and is_value_allowed(value) :returns: A normalized URL with the fragment and existing query parameters preserved and with the extra query parameters added. """ scheme, netloc, path, params, query_s, fragment = urlparse_normalized(url) query_d = query_add(query_s, query) query_s = urlencode_s(query_d, predicate) return urlunparse((scheme, netloc, path, params, query_s, fragment))
def generate_base_string(method, url, oauth_params): """ Calculates a signature base string based on the URL, method, and oauth parameters. Any query parameter by the name "oauth_signature" will be excluded from the base string. :see: Signature base string (http://tools.ietf.org/html/rfc5849#section-3.4.1) :param method: HTTP request method. :param url: The URL. If this includes a query string, query parameters are first extracted and encoded as well. All protocol-specific parameters will be ignored from the query string. :param oauth_params: Protocol-specific parameters must be specified in this dictionary. All non-protocol parameters will be ignored. :returns: Base string. """ allowed_methods = HTTP_METHODS method_normalized = method.upper() if method_normalized not in allowed_methods: raise InvalidHttpMethodError( "Method must be one of the HTTP methods %s: "\ "got `%s` instead" % (allowed_methods, method)) if not url: raise InvalidUrlError("URL must be specified: got `%r`" % url) if not isinstance(oauth_params, dict): raise InvalidOAuthParametersError("Dictionary required: got `%r`" % oauth_params) scheme, netloc, path, matrix_params, query, _ = urlparse_normalized(url) query_string = generate_base_string_query(query, oauth_params) normalized_url = urlunparse(( scheme, netloc, path, matrix_params, None, None )) return SYMBOL_AMPERSAND.join(map(percent_encode, (method_normalized, normalized_url, query_string)))
def oauth_url_sanitize(url, force_secure=True): """ Normalizes an OAuth URL and cleans up protocol-specific parameters from the query string. Used only in base string construction, Authorization headers construction and parsing, and OAuth requests. :param url: The OAuth URL to sanitize. :returns: Normalized sanitized URL. """ scheme, netloc, path, params, query, _ = urlparse_normalized(url) query = urlencode_s(query_remove_oauth(query)) if force_secure and scheme != b("https"): raise InsecureOAuthUrlError( "OAuth specification requires the use of SSL/TLS for "\ "inter-server communication.") elif not force_secure and scheme != b("https"): logging.warning( "INSECURE URL: OAuth specification requires the use of SSL/TLS "\ "for credential requests.") return urlunparse((scheme, netloc, path, params, query, None))