Mercurial > public > mercurial-scm > hg-stable
annotate tests/test-url.py @ 13848:b2798c1defff
url: be stricter about detecting schemes
While the URL parser is very forgiving about what characters are
allowed in each component, it's useful to be strict about the scheme
so we don't accidentally interpret local paths with colons as URLs.
This restricts schemes to containing alphanumeric characters, dashes,
pluses, and dots (as specified in RFC 2396).
author | Brodie Rao <brodie@bitheap.org> |
---|---|
date | Thu, 31 Mar 2011 17:37:33 -0700 |
parents | f1823b9f073b |
children | 924c82157d46 |
rev | line source |
---|---|
12737
7adb1274a4f9
test-url: skip test when ssl module is unavailable
Augie Fackler <durin42@gmail.com>
parents:
12592
diff
changeset
|
1 import sys |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
2 |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
3 def check(a, b): |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
4 if a != b: |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
5 print (a, b) |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
6 |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
7 def cert(cn): |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
8 return dict(subject=((('commonName', cn),),)) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
9 |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
10 from mercurial.url import _verifycert |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
11 |
12724
66e7ba85585b
test-url: remove trailing whitespace
Augie Fackler <durin42@gmail.com>
parents:
12606
diff
changeset
|
12 # Test non-wildcard certificates |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
13 check(_verifycert(cert('example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
14 None) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
15 check(_verifycert(cert('example.com'), 'www.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
16 'certificate is for example.com') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
17 check(_verifycert(cert('www.example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
18 'certificate is for www.example.com') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
19 |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
20 # Test wildcard certificates |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
21 check(_verifycert(cert('*.example.com'), 'www.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
22 None) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
23 check(_verifycert(cert('*.example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
24 'certificate is for *.example.com') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
25 check(_verifycert(cert('*.example.com'), 'w.w.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
26 'certificate is for *.example.com') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
27 |
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
28 # Test subjectAltName |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
29 san_cert = {'subject': ((('commonName', 'example.com'),),), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
30 'subjectAltName': (('DNS', '*.example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
31 ('DNS', 'example.net'))} |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
32 check(_verifycert(san_cert, 'example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
33 None) |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
34 check(_verifycert(san_cert, 'foo.example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
35 None) |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
36 # subject is only checked when subjectAltName is empty |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
37 check(_verifycert(san_cert, 'example.com'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
38 'certificate is for *.example.net, example.net') |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
39 |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
40 # Avoid some pitfalls |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
41 check(_verifycert(cert('*.foo'), 'foo'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
42 'certificate is for *.foo') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
43 check(_verifycert(cert('*o'), 'foo'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
44 'certificate is for *o') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
45 |
12742
6ab4a7d3c179
url: validity (notBefore/notAfter) is checked by OpenSSL (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
12738
diff
changeset
|
46 check(_verifycert({'subject': ()}, |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
47 'example.com'), |
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
48 'no commonName or subjectAltName found in certificate') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
49 check(_verifycert(None, 'example.com'), |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
50 'no certificate received') |
13248
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
51 |
13770 | 52 import doctest |
53 | |
54 def test_url(): | |
55 """ | |
56 >>> from mercurial.url import url | |
57 | |
58 This tests for edge cases in url.URL's parsing algorithm. Most of | |
59 these aren't useful for documentation purposes, so they aren't | |
60 part of the class's doc tests. | |
61 | |
62 Query strings and fragments: | |
63 | |
64 >>> url('http://host/a?b#c') | |
65 <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'> | |
66 >>> url('http://host/a?') | |
67 <url scheme: 'http', host: 'host', path: 'a'> | |
68 >>> url('http://host/a#b#c') | |
69 <url scheme: 'http', host: 'host', path: 'a', fragment: 'b#c'> | |
70 >>> url('http://host/a#b?c') | |
71 <url scheme: 'http', host: 'host', path: 'a', fragment: 'b?c'> | |
72 >>> url('http://host/?a#b') | |
73 <url scheme: 'http', host: 'host', path: '', query: 'a', fragment: 'b'> | |
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
74 >>> url('http://host/?a#b', parsequery=False) |
13770 | 75 <url scheme: 'http', host: 'host', path: '?a', fragment: 'b'> |
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
76 >>> url('http://host/?a#b', parsefragment=False) |
13770 | 77 <url scheme: 'http', host: 'host', path: '', query: 'a#b'> |
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
78 >>> url('http://host/?a#b', parsequery=False, parsefragment=False) |
13770 | 79 <url scheme: 'http', host: 'host', path: '?a#b'> |
80 | |
81 IPv6 addresses: | |
82 | |
83 >>> url('ldap://[2001:db8::7]/c=GB?objectClass?one') | |
84 <url scheme: 'ldap', host: '[2001:db8::7]', path: 'c=GB', | |
85 query: 'objectClass?one'> | |
86 >>> url('ldap://joe:xxx@[2001:db8::7]:80/c=GB?objectClass?one') | |
87 <url scheme: 'ldap', user: 'joe', passwd: 'xxx', host: '[2001:db8::7]', | |
88 port: '80', path: 'c=GB', query: 'objectClass?one'> | |
89 | |
90 Missing scheme, host, etc.: | |
91 | |
92 >>> url('://192.0.2.16:80/') | |
93 <url path: '://192.0.2.16:80/'> | |
94 >>> url('http://mercurial.selenic.com') | |
95 <url scheme: 'http', host: 'mercurial.selenic.com'> | |
96 >>> url('/foo') | |
97 <url path: '/foo'> | |
98 >>> url('bundle:/foo') | |
99 <url scheme: 'bundle', path: '/foo'> | |
100 >>> url('a?b#c') | |
101 <url path: 'a?b', fragment: 'c'> | |
102 >>> url('http://x.com?arg=/foo') | |
103 <url scheme: 'http', host: 'x.com', query: 'arg=/foo'> | |
104 >>> url('http://joe:xxx@/foo') | |
105 <url scheme: 'http', user: 'joe', passwd: 'xxx', path: 'foo'> | |
106 | |
107 Just a scheme and a path: | |
108 | |
109 >>> url('mailto:John.Doe@example.com') | |
110 <url scheme: 'mailto', path: 'John.Doe@example.com'> | |
111 >>> url('a:b:c:d') | |
13808 | 112 <url path: 'a:b:c:d'> |
113 >>> url('aa:bb:cc:dd') | |
114 <url scheme: 'aa', path: 'bb:cc:dd'> | |
13770 | 115 |
116 SSH examples: | |
117 | |
118 >>> url('ssh://joe@host//home/joe') | |
119 <url scheme: 'ssh', user: 'joe', host: 'host', path: '/home/joe'> | |
120 >>> url('ssh://joe:xxx@host/src') | |
121 <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', path: 'src'> | |
122 >>> url('ssh://joe:xxx@host') | |
123 <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host'> | |
124 >>> url('ssh://joe@host') | |
125 <url scheme: 'ssh', user: 'joe', host: 'host'> | |
126 >>> url('ssh://host') | |
127 <url scheme: 'ssh', host: 'host'> | |
128 >>> url('ssh://') | |
129 <url scheme: 'ssh'> | |
130 >>> url('ssh:') | |
131 <url scheme: 'ssh'> | |
132 | |
133 Non-numeric port: | |
134 | |
135 >>> url('http://example.com:dd') | |
136 <url scheme: 'http', host: 'example.com', port: 'dd'> | |
137 >>> url('ssh://joe:xxx@host:ssh/foo') | |
138 <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', port: 'ssh', | |
139 path: 'foo'> | |
140 | |
141 Bad authentication credentials: | |
142 | |
143 >>> url('http://joe@joeville:123@4:@host/a?b#c') | |
144 <url scheme: 'http', user: 'joe@joeville', passwd: '123@4:', | |
145 host: 'host', path: 'a', query: 'b', fragment: 'c'> | |
146 >>> url('http://!*#?/@!*#?/:@host/a?b#c') | |
147 <url scheme: 'http', host: '!*', fragment: '?/@!*#?/:@host/a?b#c'> | |
148 >>> url('http://!*#?@!*#?:@host/a?b#c') | |
149 <url scheme: 'http', host: '!*', fragment: '?@!*#?:@host/a?b#c'> | |
150 >>> url('http://!*@:!*@@host/a?b#c') | |
151 <url scheme: 'http', user: '!*@', passwd: '!*@', host: 'host', | |
152 path: 'a', query: 'b', fragment: 'c'> | |
153 | |
154 File paths: | |
155 | |
156 >>> url('a/b/c/d.g.f') | |
157 <url path: 'a/b/c/d.g.f'> | |
158 >>> url('/x///z/y/') | |
159 <url path: '/x///z/y/'> | |
13848
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
160 >>> url('/foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
161 <url path: '/foo:bar'> |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
162 >>> url('\\\\foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
163 <url path: '\\\\foo:bar'> |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
164 >>> url('./foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
165 <url path: './foo:bar'> |
13770 | 166 |
13817
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
167 Non-localhost file URL: |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
168 |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
169 >>> u = url('file://mercurial.selenic.com/foo') |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
170 Traceback (most recent call last): |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
171 File "<stdin>", line 1, in ? |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
172 Abort: file:// URLs can only refer to localhost |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
173 |
13770 | 174 Empty URL: |
175 | |
176 >>> u = url('') | |
177 >>> u | |
178 <url path: ''> | |
179 >>> str(u) | |
180 '' | |
181 | |
182 Empty path with query string: | |
183 | |
184 >>> str(url('http://foo/?bar')) | |
185 'http://foo/?bar' | |
186 | |
187 Invalid path: | |
188 | |
189 >>> u = url('http://foo/bar') | |
190 >>> u.path = 'bar' | |
191 >>> str(u) | |
192 'http://foo/bar' | |
193 | |
194 >>> u = url('file:///foo/bar/baz') | |
195 >>> u | |
196 <url scheme: 'file', path: '/foo/bar/baz'> | |
197 >>> str(u) | |
198 'file:/foo/bar/baz' | |
199 """ | |
200 | |
201 doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE) | |
202 | |
13248
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
203 # Unicode (IDN) certname isn't supported |
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
204 check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'), |
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
205 'IDN in certificate not supported') |