##// END OF EJS Templates
tests: enable HTTP digest testing...
Matt Harbison -
r41729:46432c04 default
parent child Browse files
Show More
@@ -1,98 +1,113 b''
1 1 from __future__ import absolute_import
2 2
3 3 import base64
4 4 import hashlib
5 5
6 6 from mercurial.hgweb import common
7 7 from mercurial import (
8 8 node,
9 9 )
10 10
11 11 def parse_keqv_list(req, l):
12 12 """Parse list of key=value strings where keys are not duplicated."""
13 13 parsed = {}
14 14 for elt in l:
15 15 k, v = elt.split(b'=', 1)
16 16 if v[0:1] == b'"' and v[-1:] == b'"':
17 17 v = v[1:-1]
18 18 parsed[k] = v
19 19 return parsed
20 20
21 21 class digestauthserver(object):
22 22 def __init__(self):
23 23 self._user_hashes = {}
24 24
25 25 def gethashers(self):
26 26 def _md5sum(x):
27 27 m = hashlib.md5()
28 28 m.update(x)
29 29 return node.hex(m.digest())
30 30
31 31 h = _md5sum
32 32
33 33 kd = lambda s, d, h=h: h(b"%s:%s" % (s, d))
34 34 return h, kd
35 35
36 36 def adduser(self, user, password, realm):
37 37 h, kd = self.gethashers()
38 38 a1 = h(b'%s:%s:%s' % (user, realm, password))
39 39 self._user_hashes[(user, realm)] = a1
40 40
41 41 def makechallenge(self, realm):
42 42 # We aren't testing the protocol here, just that the bytes make the
43 43 # proper round trip. So hardcoded seems fine.
44 44 nonce = b'064af982c5b571cea6450d8eda91c20d'
45 45 return b'realm="%s", nonce="%s", algorithm=MD5, qop="auth"' % (realm,
46 46 nonce)
47 47
48 48 def checkauth(self, req, header):
49 49 log = req.rawenv[b'wsgi.errors']
50 50
51 51 h, kd = self.gethashers()
52 52 resp = parse_keqv_list(req, header.split(b', '))
53 53
54 54 if resp.get(b'algorithm', b'MD5').upper() != b'MD5':
55 55 log.write(b'Unsupported algorithm: %s' % resp.get(b'algorithm'))
56 56 raise common.ErrorResponse(common.HTTP_FORBIDDEN,
57 57 b"unknown algorithm")
58 58 user = resp[b'username']
59 59 realm = resp[b'realm']
60 60 nonce = resp[b'nonce']
61 61
62 62 ha1 = self._user_hashes.get((user, realm))
63 63 if not ha1:
64 64 log.write(b'No hash found for user/realm "%s/%s"' % (user, realm))
65 65 raise common.ErrorResponse(common.HTTP_FORBIDDEN, b"bad user")
66 66
67 67 qop = resp.get(b'qop', b'auth')
68 68 if qop != b'auth':
69 69 log.write(b"Unsupported qop: %s" % qop)
70 70 raise common.ErrorResponse(common.HTTP_FORBIDDEN, b"bad qop")
71 71
72 72 cnonce, ncvalue = resp.get(b'cnonce'), resp.get(b'nc')
73 73 if not cnonce or not ncvalue:
74 74 log.write(b'No cnonce (%s) or ncvalue (%s)' % (cnonce, ncvalue))
75 75 raise common.ErrorResponse(common.HTTP_FORBIDDEN, b"no cnonce")
76 76
77 77 a2 = b'%s:%s' % (req.method, resp[b'uri'])
78 78 noncebit = b"%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, h(a2))
79 79
80 80 respdig = kd(ha1, noncebit)
81 81 if respdig != resp[b'response']:
82 82 log.write(b'User/realm "%s/%s" gave %s, but expected %s'
83 83 % (user, realm, resp[b'response'], respdig))
84 84 return False
85 85
86 86 return True
87 87
88 digest = digestauthserver()
89
88 90 def perform_authentication(hgweb, req, op):
89 91 auth = req.headers.get(b'Authorization')
92
93 if req.headers.get(b'X-HgTest-AuthType') == b'Digest':
94 if not auth:
95 challenge = digest.makechallenge(b'mercurial')
96 raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, b'who',
97 [(b'WWW-Authenticate', b'Digest %s' % challenge)])
98
99 if not digest.checkauth(req, auth[7:]):
100 raise common.ErrorResponse(common.HTTP_FORBIDDEN, b'no')
101
102 return
103
90 104 if not auth:
91 105 raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, b'who',
92 106 [(b'WWW-Authenticate', b'Basic Realm="mercurial"')])
93 107
94 108 if base64.b64decode(auth.split()[1]).split(b':', 1) != [b'user', b'pass']:
95 109 raise common.ErrorResponse(common.HTTP_FORBIDDEN, b'no')
96 110
97 111 def extsetup(ui):
98 112 common.permhooks.insert(0, perform_authentication)
113 digest.adduser(b'user', b'pass', b'mercurial')
@@ -1,552 +1,584 b''
1 1 #require serve
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ echo foo>foo
6 6 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
7 7 $ echo foo>foo.d/foo
8 8 $ echo bar>foo.d/bAr.hg.d/BaR
9 9 $ echo bar>foo.d/baR.d.hg/bAR
10 10 $ hg commit -A -m 1
11 11 adding foo
12 12 adding foo.d/bAr.hg.d/BaR
13 13 adding foo.d/baR.d.hg/bAR
14 14 adding foo.d/foo
15 15 $ hg serve -p $HGPORT -d --pid-file=../hg1.pid -E ../error.log
16 16 $ hg serve --config server.uncompressed=False -p $HGPORT1 -d --pid-file=../hg2.pid
17 17
18 18 Test server address cannot be reused
19 19
20 20 $ hg serve -p $HGPORT1 2>&1
21 21 abort: cannot start server at 'localhost:$HGPORT1': $EADDRINUSE$
22 22 [255]
23 23
24 24 $ cd ..
25 25 $ cat hg1.pid hg2.pid >> $DAEMON_PIDS
26 26
27 27 clone via stream
28 28
29 29 #if no-reposimplestore
30 30 $ hg clone --stream http://localhost:$HGPORT/ copy 2>&1
31 31 streaming all changes
32 32 9 files to transfer, 715 bytes of data
33 33 transferred * bytes in * seconds (*/sec) (glob)
34 34 updating to branch default
35 35 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 36 $ hg verify -R copy
37 37 checking changesets
38 38 checking manifests
39 39 crosschecking files in changesets and manifests
40 40 checking files
41 41 checked 1 changesets with 4 changes to 4 files
42 42 #endif
43 43
44 44 try to clone via stream, should use pull instead
45 45
46 46 $ hg clone --stream http://localhost:$HGPORT1/ copy2
47 47 warning: stream clone requested but server has them disabled
48 48 requesting all changes
49 49 adding changesets
50 50 adding manifests
51 51 adding file changes
52 52 added 1 changesets with 4 changes to 4 files
53 53 new changesets 8b6053c928fe
54 54 updating to branch default
55 55 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 56
57 57 try to clone via stream but missing requirements, so should use pull instead
58 58
59 59 $ cat > $TESTTMP/removesupportedformat.py << EOF
60 60 > from mercurial import localrepo
61 61 > def extsetup(ui):
62 62 > localrepo.localrepository.supportedformats.remove(b'generaldelta')
63 63 > EOF
64 64
65 65 $ hg clone --config extensions.rsf=$TESTTMP/removesupportedformat.py --stream http://localhost:$HGPORT/ copy3
66 66 warning: stream clone requested but client is missing requirements: generaldelta
67 67 (see https://www.mercurial-scm.org/wiki/MissingRequirement for more information)
68 68 requesting all changes
69 69 adding changesets
70 70 adding manifests
71 71 adding file changes
72 72 added 1 changesets with 4 changes to 4 files
73 73 new changesets 8b6053c928fe
74 74 updating to branch default
75 75 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
76 76
77 77 clone via pull
78 78
79 79 $ hg clone http://localhost:$HGPORT1/ copy-pull
80 80 requesting all changes
81 81 adding changesets
82 82 adding manifests
83 83 adding file changes
84 84 added 1 changesets with 4 changes to 4 files
85 85 new changesets 8b6053c928fe
86 86 updating to branch default
87 87 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 88 $ hg verify -R copy-pull
89 89 checking changesets
90 90 checking manifests
91 91 crosschecking files in changesets and manifests
92 92 checking files
93 93 checked 1 changesets with 4 changes to 4 files
94 94 $ cd test
95 95 $ echo bar > bar
96 96 $ hg commit -A -d '1 0' -m 2
97 97 adding bar
98 98 $ cd ..
99 99
100 100 clone over http with --update
101 101
102 102 $ hg clone http://localhost:$HGPORT1/ updated --update 0
103 103 requesting all changes
104 104 adding changesets
105 105 adding manifests
106 106 adding file changes
107 107 added 2 changesets with 5 changes to 5 files
108 108 new changesets 8b6053c928fe:5fed3813f7f5
109 109 updating to branch default
110 110 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 111 $ hg log -r . -R updated
112 112 changeset: 0:8b6053c928fe
113 113 user: test
114 114 date: Thu Jan 01 00:00:00 1970 +0000
115 115 summary: 1
116 116
117 117 $ rm -rf updated
118 118
119 119 incoming via HTTP
120 120
121 121 $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
122 122 adding changesets
123 123 adding manifests
124 124 adding file changes
125 125 added 1 changesets with 4 changes to 4 files
126 126 new changesets 8b6053c928fe
127 127 updating to branch default
128 128 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
129 129 $ cd partial
130 130 $ touch LOCAL
131 131 $ hg ci -qAm LOCAL
132 132 $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
133 133 comparing with http://localhost:$HGPORT1/
134 134 searching for changes
135 135 2
136 136 $ cd ..
137 137
138 138 pull
139 139
140 140 $ cd copy-pull
141 141 $ cat >> .hg/hgrc <<EOF
142 142 > [hooks]
143 143 > changegroup = sh -c "printenv.py --line changegroup"
144 144 > EOF
145 145 $ hg pull
146 146 pulling from http://localhost:$HGPORT1/
147 147 searching for changes
148 148 adding changesets
149 149 adding manifests
150 150 adding file changes
151 151 added 1 changesets with 1 changes to 1 files
152 152 new changesets 5fed3813f7f5
153 153 changegroup hook: HG_HOOKNAME=changegroup
154 154 HG_HOOKTYPE=changegroup
155 155 HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
156 156 HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
157 157 HG_SOURCE=pull
158 158 HG_TXNID=TXN:$ID$
159 159 HG_URL=http://localhost:$HGPORT1/
160 160
161 161 (run 'hg update' to get a working copy)
162 162 $ cd ..
163 163
164 164 clone from invalid URL
165 165
166 166 $ hg clone http://localhost:$HGPORT/bad
167 167 abort: HTTP Error 404: Not Found
168 168 [255]
169 169
170 170 test http authentication
171 171 + use the same server to test server side streaming preference
172 172
173 173 $ cd test
174 174
175 175 $ hg serve --config extensions.x=$TESTDIR/httpserverauth.py -p $HGPORT2 -d \
176 > --pid-file=pid --config server.preferuncompressed=True \
176 > --pid-file=pid --config server.preferuncompressed=True -E ../errors2.log \
177 177 > --config web.push_ssl=False --config web.allow_push=* -A ../access.log
178 178 $ cat pid >> $DAEMON_PIDS
179 179
180 180 $ cat << EOF > get_pass.py
181 181 > import getpass
182 182 > def newgetpass(arg):
183 183 > return "pass"
184 184 > getpass.getpass = newgetpass
185 185 > EOF
186 186
187 187 $ hg id http://localhost:$HGPORT2/
188 188 abort: http authorization required for http://localhost:$HGPORT2/
189 189 [255]
190 190 $ hg id http://localhost:$HGPORT2/
191 191 abort: http authorization required for http://localhost:$HGPORT2/
192 192 [255]
193 193 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
194 194 http authorization required for http://localhost:$HGPORT2/
195 195 realm: mercurial
196 196 user: user
197 197 password: 5fed3813f7f5
198 198 $ hg id http://user:pass@localhost:$HGPORT2/
199 199 5fed3813f7f5
200 200 $ echo '[auth]' >> .hg/hgrc
201 201 $ echo 'l.schemes=http' >> .hg/hgrc
202 202 $ echo 'l.prefix=lo' >> .hg/hgrc
203 203 $ echo 'l.username=user' >> .hg/hgrc
204 204 $ echo 'l.password=pass' >> .hg/hgrc
205 205 $ hg id http://localhost:$HGPORT2/
206 206 5fed3813f7f5
207 207 $ hg id http://localhost:$HGPORT2/
208 208 5fed3813f7f5
209 209 $ hg id http://user@localhost:$HGPORT2/
210 210 5fed3813f7f5
211 211
212 $ cat > use_digests.py << EOF
213 > from mercurial import (
214 > exthelper,
215 > url,
216 > )
217 >
218 > eh = exthelper.exthelper()
219 > uisetup = eh.finaluisetup
220 >
221 > @eh.wrapfunction(url, 'opener')
222 > def urlopener(orig, *args, **kwargs):
223 > opener = orig(*args, **kwargs)
224 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
225 > return opener
226 > EOF
227
228 $ hg id http://localhost:$HGPORT2/ --config extensions.x=use_digests.py || true
229 abort: HTTP Error 403: bad user (py3 !)
230 5fed3813f7f5 (no-py3 !)
231
212 232 #if no-reposimplestore
213 233 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
214 234 streaming all changes
215 235 10 files to transfer, 1.01 KB of data
216 236 transferred * KB in * seconds (*/sec) (glob)
217 237 updating to branch default
218 238 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 239 #endif
220 240
221 241 --pull should override server's preferuncompressed
222 242 $ hg clone --pull http://user:pass@localhost:$HGPORT2/ dest-pull 2>&1
223 243 requesting all changes
224 244 adding changesets
225 245 adding manifests
226 246 adding file changes
227 247 added 2 changesets with 5 changes to 5 files
228 248 new changesets 8b6053c928fe:5fed3813f7f5
229 249 updating to branch default
230 250 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 251
232 252 $ hg id http://user2@localhost:$HGPORT2/
233 253 abort: http authorization required for http://localhost:$HGPORT2/
234 254 [255]
235 255 $ hg id http://user:pass2@localhost:$HGPORT2/
236 256 abort: HTTP Error 403: no
237 257 [255]
238 258
239 259 $ hg -R dest-pull tag -r tip top
240 260 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/
241 261 pushing to http://user:***@localhost:$HGPORT2/
242 262 searching for changes
243 263 remote: adding changesets
244 264 remote: adding manifests
245 265 remote: adding file changes
246 266 remote: added 1 changesets with 1 changes to 1 files
247 267 $ hg rollback -q
248 268 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/ --debug --config devel.debug.peer-request=yes
249 269 pushing to http://user:***@localhost:$HGPORT2/
250 270 using http://localhost:$HGPORT2/
251 271 http auth: user user, password ****
252 272 sending capabilities command
253 273 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=capabilities
254 274 http auth: user user, password ****
255 275 devel-peer-request: finished in *.???? seconds (200) (glob)
256 276 query 1; heads
257 277 devel-peer-request: batched-content
258 278 devel-peer-request: - heads (0 arguments)
259 279 devel-peer-request: - known (1 arguments)
260 280 sending batch command
261 281 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=batch
262 282 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
263 283 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
264 284 devel-peer-request: 68 bytes of commands arguments in headers
265 285 devel-peer-request: finished in *.???? seconds (200) (glob)
266 286 searching for changes
267 287 all remote heads known locally
268 288 preparing listkeys for "phases"
269 289 sending listkeys command
270 290 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
271 291 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
272 292 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
273 293 devel-peer-request: 16 bytes of commands arguments in headers
274 294 devel-peer-request: finished in *.???? seconds (200) (glob)
275 295 received listkey for "phases": 58 bytes
276 296 checking for updated bookmarks
277 297 preparing listkeys for "bookmarks"
278 298 sending listkeys command
279 299 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
280 300 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
281 301 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
282 302 devel-peer-request: 19 bytes of commands arguments in headers
283 303 devel-peer-request: finished in *.???? seconds (200) (glob)
284 304 received listkey for "bookmarks": 0 bytes
285 305 sending branchmap command
286 306 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=branchmap
287 307 devel-peer-request: Vary X-HgProto-1
288 308 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
289 309 devel-peer-request: finished in *.???? seconds (200) (glob)
290 310 preparing listkeys for "bookmarks"
291 311 sending listkeys command
292 312 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
293 313 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
294 314 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
295 315 devel-peer-request: 19 bytes of commands arguments in headers
296 316 devel-peer-request: finished in *.???? seconds (200) (glob)
297 317 received listkey for "bookmarks": 0 bytes
298 318 1 changesets found
299 319 list of changesets:
300 320 7f4e523d01f2cc3765ac8934da3d14db775ff872
301 321 bundle2-output-bundle: "HG20", 5 parts total
302 322 bundle2-output-part: "replycaps" 205 bytes payload
303 323 bundle2-output-part: "check:phases" 24 bytes payload
304 324 bundle2-output-part: "check:heads" streamed payload
305 325 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
306 326 bundle2-output-part: "phase-heads" 24 bytes payload
307 327 sending unbundle command
308 328 sending 1013 bytes
309 329 devel-peer-request: POST http://localhost:$HGPORT2/?cmd=unbundle
310 330 devel-peer-request: Content-length 1013
311 331 devel-peer-request: Content-type application/mercurial-0.1
312 332 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
313 333 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
314 334 devel-peer-request: 16 bytes of commands arguments in headers
315 335 devel-peer-request: 1013 bytes of data
316 336 devel-peer-request: finished in *.???? seconds (200) (glob)
317 337 bundle2-input-bundle: no-transaction
318 338 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
319 339 bundle2-input-part: "output" (advisory) (params: 0 advisory) supported
320 340 bundle2-input-part: total payload size 100
321 341 remote: adding changesets
322 342 remote: adding manifests
323 343 remote: adding file changes
324 344 remote: added 1 changesets with 1 changes to 1 files
325 345 bundle2-input-part: "output" (advisory) supported
326 346 bundle2-input-bundle: 2 parts total
327 347 preparing listkeys for "phases"
328 348 sending listkeys command
329 349 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
330 350 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
331 351 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
332 352 devel-peer-request: 16 bytes of commands arguments in headers
333 353 devel-peer-request: finished in *.???? seconds (200) (glob)
334 354 received listkey for "phases": 15 bytes
335 355 $ hg rollback -q
336 356
337 357 $ sed 's/.*] "/"/' < ../access.log
338 358 "GET /?cmd=capabilities HTTP/1.1" 401 -
339 359 "GET /?cmd=capabilities HTTP/1.1" 401 -
340 360 "GET /?cmd=capabilities HTTP/1.1" 401 -
341 361 "GET /?cmd=capabilities HTTP/1.1" 200 -
342 362 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
343 363 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
344 364 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
345 365 "GET /?cmd=capabilities HTTP/1.1" 401 -
346 366 "GET /?cmd=capabilities HTTP/1.1" 200 -
347 367 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
348 368 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
349 369 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
350 370 "GET /?cmd=capabilities HTTP/1.1" 401 -
351 371 "GET /?cmd=capabilities HTTP/1.1" 200 -
352 372 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
353 373 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
354 374 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
355 375 "GET /?cmd=capabilities HTTP/1.1" 401 -
356 376 "GET /?cmd=capabilities HTTP/1.1" 200 -
357 377 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
358 378 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
359 379 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
360 380 "GET /?cmd=capabilities HTTP/1.1" 401 -
361 381 "GET /?cmd=capabilities HTTP/1.1" 200 -
362 382 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
363 383 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
364 384 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
385 "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest
386 "GET /?cmd=capabilities HTTP/1.1" 403 - x-hgtest-authtype:Digest (py3 !)
387 "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (no-py3 !)
388 "GET /?cmd=lookup HTTP/1.1" 401 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
389 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
390 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
391 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
392 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
393 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
365 394 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
366 395 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
367 396 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (no-reposimplestore !)
368 397 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&stream=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (no-reposimplestore !)
369 398 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
370 399 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
371 400 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
372 401 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
373 402 "GET /?cmd=capabilities HTTP/1.1" 401 -
374 403 "GET /?cmd=capabilities HTTP/1.1" 401 -
375 404 "GET /?cmd=capabilities HTTP/1.1" 403 -
376 405 "GET /?cmd=capabilities HTTP/1.1" 401 -
377 406 "GET /?cmd=capabilities HTTP/1.1" 200 -
378 407 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
379 408 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
380 409 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
381 410 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
382 411 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
383 412 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
384 413 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
385 414 "GET /?cmd=capabilities HTTP/1.1" 401 -
386 415 "GET /?cmd=capabilities HTTP/1.1" 200 -
387 416 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
388 417 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
389 418 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
390 419 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
391 420 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
392 421 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
393 422 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
394 423
395 424 $ cd ..
396 425
397 426 clone of serve with repo in root and unserved subrepo (issue2970)
398 427
399 428 $ hg --cwd test init sub
400 429 $ echo empty > test/sub/empty
401 430 $ hg --cwd test/sub add empty
402 431 $ hg --cwd test/sub commit -qm 'add empty'
403 432 $ hg --cwd test/sub tag -r 0 something
404 433 $ echo sub = sub > test/.hgsub
405 434 $ hg --cwd test add .hgsub
406 435 $ hg --cwd test commit -qm 'add subrepo'
407 436 $ hg clone http://localhost:$HGPORT noslash-clone
408 437 requesting all changes
409 438 adding changesets
410 439 adding manifests
411 440 adding file changes
412 441 added 3 changesets with 7 changes to 7 files
413 442 new changesets 8b6053c928fe:56f9bc90cce6
414 443 updating to branch default
415 444 cloning subrepo sub from http://localhost:$HGPORT/sub
416 445 abort: HTTP Error 404: Not Found
417 446 [255]
418 447 $ hg clone http://localhost:$HGPORT/ slash-clone
419 448 requesting all changes
420 449 adding changesets
421 450 adding manifests
422 451 adding file changes
423 452 added 3 changesets with 7 changes to 7 files
424 453 new changesets 8b6053c928fe:56f9bc90cce6
425 454 updating to branch default
426 455 cloning subrepo sub from http://localhost:$HGPORT/sub
427 456 abort: HTTP Error 404: Not Found
428 457 [255]
429 458
430 459 check error log
431 460
432 461 $ cat error.log
433 462
463 $ cat errors2.log
464 $LOCALIP - - [$ERRDATE$] HG error: No hash found for user/realm "b'user'/mercurial" (glob) (py3 !)
465
434 466 check abort error reporting while pulling/cloning
435 467
436 468 $ $RUNTESTDIR/killdaemons.py
437 469 $ hg serve -R test -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py
438 470 $ cat hg3.pid >> $DAEMON_PIDS
439 471 $ hg clone http://localhost:$HGPORT/ abort-clone
440 472 requesting all changes
441 473 remote: abort: this is an exercise
442 474 abort: pull failed on remote
443 475 [255]
444 476 $ cat error.log
445 477
446 478 disable pull-based clones
447 479
448 480 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg4.pid -E error.log --config server.disablefullbundle=True
449 481 $ cat hg4.pid >> $DAEMON_PIDS
450 482 $ hg clone http://localhost:$HGPORT1/ disable-pull-clone
451 483 requesting all changes
452 484 remote: abort: server has pull-based clones disabled
453 485 abort: pull failed on remote
454 486 (remove --pull if specified or upgrade Mercurial)
455 487 [255]
456 488
457 489 #if no-reposimplestore
458 490 ... but keep stream clones working
459 491
460 492 $ hg clone --stream --noupdate http://localhost:$HGPORT1/ test-stream-clone
461 493 streaming all changes
462 494 * files to transfer, * of data (glob)
463 495 transferred * in * seconds (*/sec) (glob)
464 496 $ cat error.log
465 497 #endif
466 498
467 499 ... and also keep partial clones and pulls working
468 500 $ hg clone http://localhost:$HGPORT1 --rev 0 test/partial/clone
469 501 adding changesets
470 502 adding manifests
471 503 adding file changes
472 504 added 1 changesets with 4 changes to 4 files
473 505 new changesets 8b6053c928fe
474 506 updating to branch default
475 507 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
476 508 $ hg pull -R test/partial/clone
477 509 pulling from http://localhost:$HGPORT1/
478 510 searching for changes
479 511 adding changesets
480 512 adding manifests
481 513 adding file changes
482 514 added 2 changesets with 3 changes to 3 files
483 515 new changesets 5fed3813f7f5:56f9bc90cce6
484 516 (run 'hg update' to get a working copy)
485 517
486 518 $ hg clone -U -r 0 test/partial/clone test/another/clone
487 519 adding changesets
488 520 adding manifests
489 521 adding file changes
490 522 added 1 changesets with 4 changes to 4 files
491 523 new changesets 8b6053c928fe
492 524
493 525 corrupt cookies file should yield a warning
494 526
495 527 $ cat > $TESTTMP/cookies.txt << EOF
496 528 > bad format
497 529 > EOF
498 530
499 531 $ hg --config auth.cookiefile=$TESTTMP/cookies.txt id http://localhost:$HGPORT/
500 532 (error loading cookie file $TESTTMP/cookies.txt: '*/cookies.txt' does not look like a Netscape format cookies file; continuing without cookies) (glob)
501 533 56f9bc90cce6
502 534
503 535 $ killdaemons.py
504 536
505 537 Create dummy authentication handler that looks for cookies. It doesn't do anything
506 538 useful. It just raises an HTTP 500 with details about the Cookie request header.
507 539 We raise HTTP 500 because its message is printed in the abort message.
508 540
509 541 $ cat > cookieauth.py << EOF
510 542 > from mercurial import util
511 543 > from mercurial.hgweb import common
512 544 > def perform_authentication(hgweb, req, op):
513 545 > cookie = req.headers.get(b'Cookie')
514 546 > if not cookie:
515 547 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'no-cookie')
516 548 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'Cookie: %s' % cookie)
517 549 > def extsetup(ui):
518 550 > common.permhooks.insert(0, perform_authentication)
519 551 > EOF
520 552
521 553 $ hg serve --config extensions.cookieauth=cookieauth.py -R test -p $HGPORT -d --pid-file=pid
522 554 $ cat pid > $DAEMON_PIDS
523 555
524 556 Request without cookie sent should fail due to lack of cookie
525 557
526 558 $ hg id http://localhost:$HGPORT
527 559 abort: HTTP Error 500: no-cookie
528 560 [255]
529 561
530 562 Populate a cookies file
531 563
532 564 $ cat > cookies.txt << EOF
533 565 > # HTTP Cookie File
534 566 > # Expiration is 2030-01-01 at midnight
535 567 > .example.com TRUE / FALSE 1893456000 hgkey examplevalue
536 568 > EOF
537 569
538 570 Should not send a cookie for another domain
539 571
540 572 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
541 573 abort: HTTP Error 500: no-cookie
542 574 [255]
543 575
544 576 Add a cookie entry for our test server and verify it is sent
545 577
546 578 $ cat >> cookies.txt << EOF
547 579 > localhost.local FALSE / FALSE 1893456000 hgkey localhostvalue
548 580 > EOF
549 581
550 582 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
551 583 abort: HTTP Error 500: Cookie: hgkey=localhostvalue
552 584 [255]
General Comments 0
You need to be logged in to leave comments. Login now