@@ -0,0 +1,2286 @@
+from urllib.parse import urljoin, urlparse%0Afrom itertools import product%0Aimport csv%0Aimport posixpath%0A%0A%0Adef resolveComponents(url):%0A    %22%22%22%0A    %3E%3E%3E resolveComponents('http://www.example.com/foo/bar/../../baz/bux/')%0A    'http://www.example.com/baz/bux/'%0A    %3E%3E%3E resolveComponents('http://www.example.com/some/path/../file.ext')%0A    'http://www.example.com/some/file.ext'%0A    %22%22%22%0A%0A    parsed = urlparse(url)%0A    new_path = posixpath.normpath(parsed.path)%0A    if parsed.path.endswith('/'):%0A        # Compensate for issue1707768%0A        new_path += '/'%0A    if new_path.startswith('//'):%0A        new_path = new_path%5B1:%5D%0A    cleaned = parsed._replace(path=new_path)%0A    return cleaned.geturl()%0A%0A%0Afirst_authorities = %5B'http://example.com@user:pass:7152', 'https://example.com'%5D%0Asecond_authorities = %5B'', 'https://www.example.org', 'http://example.com@user:pass:1111',%0A                      'file://example.com', 'file://'%5D%0Afirst_paths = %5B'', '/', '/foobar/bazz', 'foobar/bazz/'%5D%0Asecond_paths = %5B'', '/', '/foo/bar', 'foo/bar/', './foo/../bar', 'foo/./.././bar'%5D%0Afirst_queries = %5B'', '?a=1', '?a=647&b=s564'%5D%0Asecond_queries = %5B'', '?a=sdf', '?a=cvb&b=987'%5D%0Afragments = %5B'', '#foo', '#bar'%5D%0A%0Awith open('urls.csv', 'wt') as f:%0A    csvwriter = csv.writer(f, quotechar='%22', quoting=csv.QUOTE_ALL)%0A    csvwriter.writerow(%5B'first_url', 'second_url', 'expected'%5D)%0A    counter = 1%0A    for first_domain, second_domain in product(first_authorities, second_authorities):%0A        for first_path, second_path in product(first_paths, second_paths):%0A            for first_query, second_query in product(first_queries, second_queries):%0A                for first_fragment, second_fragment in product(fragments, fragments):%0A                    if not first_path.startswith('/'):%0A                        first_path = '/' + first_path%0A                    first_url = first_domain + first_path + first_query + first_fragment%0A                    if second_domain and not second_path.startswith('/'):%0A                        second_path = '/' + second_path%0A                    second_url = second_domain + second_path + second_query + second_fragment%0A                    if first_url != second_url:%0A                        csvwriter.writerow(%5Bfirst_url, second_url, resolveComponents(urljoin(first_url, second_url))%5D)%0A

Add script used to generate urls test file.