##// END OF EJS Templates
merge with stable...
Gregory Szorc -
r36778:7bf80d9d merge default
parent child Browse files
Show More
This diff has been collapsed as it changes many lines, (1502 lines changed) Show them Hide them
@@ -0,0 +1,1502 b''
1 #require killdaemons
2
3 $ cat > fakeremoteuser.py << EOF
4 > import os
5 > from mercurial.hgweb import hgweb_mod
6 > from mercurial import wireproto
7 > class testenvhgweb(hgweb_mod.hgweb):
8 > def __call__(self, env, respond):
9 > # Allow REMOTE_USER to define authenticated user.
10 > if r'REMOTE_USER' in os.environ:
11 > env[r'REMOTE_USER'] = os.environ[r'REMOTE_USER']
12 > # Allow REQUEST_METHOD to override HTTP method
13 > if r'REQUEST_METHOD' in os.environ:
14 > env[r'REQUEST_METHOD'] = os.environ[r'REQUEST_METHOD']
15 > return super(testenvhgweb, self).__call__(env, respond)
16 > hgweb_mod.hgweb = testenvhgweb
17 >
18 > @wireproto.wireprotocommand('customreadnoperm')
19 > def customread(repo, proto):
20 > return b'read-only command no defined permissions\n'
21 > @wireproto.wireprotocommand('customwritenoperm')
22 > def customwritenoperm(repo, proto):
23 > return b'write command no defined permissions\n'
24 > wireproto.permissions['customreadwithperm'] = 'pull'
25 > @wireproto.wireprotocommand('customreadwithperm')
26 > def customreadwithperm(repo, proto):
27 > return b'read-only command w/ defined permissions\n'
28 > wireproto.permissions['customwritewithperm'] = 'push'
29 > @wireproto.wireprotocommand('customwritewithperm')
30 > def customwritewithperm(repo, proto):
31 > return b'write command w/ defined permissions\n'
32 > EOF
33
34 $ cat >> $HGRCPATH << EOF
35 > [extensions]
36 > fakeremoteuser = $TESTTMP/fakeremoteuser.py
37 > strip =
38 > EOF
39
40 $ hg init test
41 $ cd test
42 $ echo a > a
43 $ hg ci -Ama
44 adding a
45 $ cd ..
46 $ hg clone test test2
47 updating to branch default
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 $ cd test2
50 $ echo a >> a
51 $ hg ci -mb
52 $ hg book bm -r 0
53 $ cd ../test
54
55 web.deny_read=* prevents access to wire protocol for all users
56
57 $ cat > .hg/hgrc <<EOF
58 > [web]
59 > deny_read = *
60 > EOF
61
62 $ hg serve -p $HGPORT -d --pid-file hg.pid
63 $ cat hg.pid > $DAEMON_PIDS
64
65 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities'
66 401 read not authorized
67
68 0
69 read not authorized
70 [1]
71
72 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out'
73 401 read not authorized
74
75 0
76 read not authorized
77 [1]
78
79 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
80 401 read not authorized
81
82 0
83 read not authorized
84 [1]
85
86 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
87 401 read not authorized
88
89 0
90 read not authorized
91 [1]
92
93 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
94 401 read not authorized
95
96 0
97 read not authorized
98 [1]
99
100 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
101 401 read not authorized
102
103 0
104 read not authorized
105 [1]
106
107 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
108 401 read not authorized
109
110 0
111 read not authorized
112 [1]
113
114 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
115 401 read not authorized
116
117 0
118 read not authorized
119 [1]
120
121 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
122 pulling from http://localhost:$HGPORT/
123 abort: authorization failed
124 [255]
125
126 $ killdaemons.py
127
128 web.deny_read=* with REMOTE_USER set still locks out clients
129
130 $ REMOTE_USER=authed_user hg serve -p $HGPORT -d --pid-file hg.pid
131 $ cat hg.pid > $DAEMON_PIDS
132
133 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities'
134 401 read not authorized
135
136 0
137 read not authorized
138 [1]
139
140 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out'
141 401 read not authorized
142
143 0
144 read not authorized
145 [1]
146
147 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
148 401 read not authorized
149
150 0
151 read not authorized
152 [1]
153
154 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
155 401 read not authorized
156
157 0
158 read not authorized
159 [1]
160
161 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
162 401 read not authorized
163
164 0
165 read not authorized
166 [1]
167
168 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
169 401 read not authorized
170
171 0
172 read not authorized
173 [1]
174
175 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
176 401 read not authorized
177
178 0
179 read not authorized
180 [1]
181
182 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
183 pulling from http://localhost:$HGPORT/
184 abort: authorization failed
185 [255]
186
187 $ killdaemons.py
188
189 web.deny_read=<user> denies access to unauthenticated user
190
191 $ cat > .hg/hgrc <<EOF
192 > [web]
193 > deny_read = baduser1,baduser2
194 > EOF
195
196 $ hg serve -p $HGPORT -d --pid-file hg.pid
197 $ cat hg.pid > $DAEMON_PIDS
198
199 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
200 401 read not authorized
201
202 0
203 read not authorized
204 [1]
205
206 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
207 401 read not authorized
208
209 0
210 read not authorized
211 [1]
212
213 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
214 401 read not authorized
215
216 0
217 read not authorized
218 [1]
219
220 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
221 401 read not authorized
222
223 0
224 read not authorized
225 [1]
226
227 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
228 401 read not authorized
229
230 0
231 read not authorized
232 [1]
233
234 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
235 401 read not authorized
236
237 0
238 read not authorized
239 [1]
240
241 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
242 pulling from http://localhost:$HGPORT/
243 abort: authorization failed
244 [255]
245
246 $ killdaemons.py
247
248 web.deny_read=<user> denies access to users in deny list
249
250 $ REMOTE_USER=baduser2 hg serve -p $HGPORT -d --pid-file hg.pid
251 $ cat hg.pid > $DAEMON_PIDS
252
253 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
254 401 read not authorized
255
256 0
257 read not authorized
258 [1]
259
260 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
261 401 read not authorized
262
263 0
264 read not authorized
265 [1]
266
267 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
268 401 read not authorized
269
270 0
271 read not authorized
272 [1]
273
274 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
275 401 read not authorized
276
277 0
278 read not authorized
279 [1]
280
281 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
282 401 read not authorized
283
284 0
285 read not authorized
286 [1]
287
288 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
289 401 read not authorized
290
291 0
292 read not authorized
293 [1]
294
295 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
296 pulling from http://localhost:$HGPORT/
297 abort: authorization failed
298 [255]
299
300 $ killdaemons.py
301
302 web.deny_read=<user> allows access to authenticated users not in list
303
304 $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
305 $ cat hg.pid > $DAEMON_PIDS
306
307 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
308 200 Script output follows
309
310 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
311 publishing True (no-eol)
312
313 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
314 200 Script output follows
315
316 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
317 publishing True (no-eol)
318
319 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
320 405 push requires POST request
321
322 0
323 push requires POST request
324 [1]
325
326 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
327 200 Script output follows
328
329 read-only command w/ defined permissions
330
331 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
332 405 push requires POST request
333
334 0
335 push requires POST request
336 [1]
337
338 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
339 405 push requires POST request
340
341 0
342 push requires POST request
343 [1]
344
345 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
346 pulling from http://localhost:$HGPORT/
347 searching for changes
348 no changes found
349
350 $ killdaemons.py
351
352 web.allow_read=* allows reads for unauthenticated users
353
354 $ cat > .hg/hgrc <<EOF
355 > [web]
356 > allow_read = *
357 > EOF
358
359 $ hg serve -p $HGPORT -d --pid-file hg.pid
360 $ cat hg.pid > $DAEMON_PIDS
361
362 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
363 200 Script output follows
364
365 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
366 publishing True (no-eol)
367
368 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
369 200 Script output follows
370
371 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
372 publishing True (no-eol)
373
374 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
375 405 push requires POST request
376
377 0
378 push requires POST request
379 [1]
380
381 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
382 200 Script output follows
383
384 read-only command w/ defined permissions
385
386 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
387 405 push requires POST request
388
389 0
390 push requires POST request
391 [1]
392
393 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
394 405 push requires POST request
395
396 0
397 push requires POST request
398 [1]
399
400 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
401 pulling from http://localhost:$HGPORT/
402 searching for changes
403 no changes found
404
405 $ killdaemons.py
406
407 web.allow_read=* allows read for authenticated user
408
409 $ REMOTE_USER=authed_user hg serve -p $HGPORT -d --pid-file hg.pid
410 $ cat hg.pid > $DAEMON_PIDS
411
412 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
413 200 Script output follows
414
415 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
416 publishing True (no-eol)
417
418 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
419 200 Script output follows
420
421 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
422 publishing True (no-eol)
423
424 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
425 405 push requires POST request
426
427 0
428 push requires POST request
429 [1]
430
431 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
432 200 Script output follows
433
434 read-only command w/ defined permissions
435
436 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
437 405 push requires POST request
438
439 0
440 push requires POST request
441 [1]
442
443 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
444 405 push requires POST request
445
446 0
447 push requires POST request
448 [1]
449
450 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
451 pulling from http://localhost:$HGPORT/
452 searching for changes
453 no changes found
454
455 $ killdaemons.py
456
457 web.allow_read=<user> does not allow unauthenticated users to read
458
459 $ cat > .hg/hgrc <<EOF
460 > [web]
461 > allow_read = gooduser
462 > EOF
463
464 $ hg serve -p $HGPORT -d --pid-file hg.pid
465 $ cat hg.pid > $DAEMON_PIDS
466
467 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
468 401 read not authorized
469
470 0
471 read not authorized
472 [1]
473
474 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
475 401 read not authorized
476
477 0
478 read not authorized
479 [1]
480
481 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
482 401 read not authorized
483
484 0
485 read not authorized
486 [1]
487
488 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
489 401 read not authorized
490
491 0
492 read not authorized
493 [1]
494
495 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
496 401 read not authorized
497
498 0
499 read not authorized
500 [1]
501
502 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
503 401 read not authorized
504
505 0
506 read not authorized
507 [1]
508
509 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
510 pulling from http://localhost:$HGPORT/
511 abort: authorization failed
512 [255]
513
514 $ killdaemons.py
515
516 web.allow_read=<user> does not allow user not in list to read
517
518 $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
519 $ cat hg.pid > $DAEMON_PIDS
520
521 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
522 401 read not authorized
523
524 0
525 read not authorized
526 [1]
527
528 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
529 401 read not authorized
530
531 0
532 read not authorized
533 [1]
534
535 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
536 401 read not authorized
537
538 0
539 read not authorized
540 [1]
541
542 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
543 401 read not authorized
544
545 0
546 read not authorized
547 [1]
548
549 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
550 401 read not authorized
551
552 0
553 read not authorized
554 [1]
555
556 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
557 401 read not authorized
558
559 0
560 read not authorized
561 [1]
562
563 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
564 pulling from http://localhost:$HGPORT/
565 abort: authorization failed
566 [255]
567
568 $ killdaemons.py
569
570 web.allow_read=<user> allows read from user in list
571
572 $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
573 $ cat hg.pid > $DAEMON_PIDS
574
575 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
576 200 Script output follows
577
578 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
579 publishing True (no-eol)
580
581 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
582 200 Script output follows
583
584 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1
585 publishing True (no-eol)
586
587 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
588 405 push requires POST request
589
590 0
591 push requires POST request
592 [1]
593
594 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
595 200 Script output follows
596
597 read-only command w/ defined permissions
598
599 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
600 405 push requires POST request
601
602 0
603 push requires POST request
604 [1]
605
606 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
607 405 push requires POST request
608
609 0
610 push requires POST request
611 [1]
612
613 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
614 pulling from http://localhost:$HGPORT/
615 searching for changes
616 no changes found
617
618 $ killdaemons.py
619
620 web.deny_read takes precedence over web.allow_read
621
622 $ cat > .hg/hgrc <<EOF
623 > [web]
624 > allow_read = baduser
625 > deny_read = baduser
626 > EOF
627
628 $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
629 $ cat hg.pid > $DAEMON_PIDS
630
631 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
632 401 read not authorized
633
634 0
635 read not authorized
636 [1]
637
638 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
639 401 read not authorized
640
641 0
642 read not authorized
643 [1]
644
645 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
646 401 read not authorized
647
648 0
649 read not authorized
650 [1]
651
652 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
653 401 read not authorized
654
655 0
656 read not authorized
657 [1]
658
659 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
660 401 read not authorized
661
662 0
663 read not authorized
664 [1]
665
666 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
667 401 read not authorized
668
669 0
670 read not authorized
671 [1]
672
673 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
674 pulling from http://localhost:$HGPORT/
675 abort: authorization failed
676 [255]
677
678 $ killdaemons.py
679
680 web.allow-pull=false denies read access to repo
681
682 $ cat > .hg/hgrc <<EOF
683 > [web]
684 > allow-pull = false
685 > EOF
686
687 $ hg serve -p $HGPORT -d --pid-file hg.pid
688 $ cat hg.pid > $DAEMON_PIDS
689
690 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities'
691 401 pull not authorized
692
693 0
694 pull not authorized
695 [1]
696
697 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
698 401 pull not authorized
699
700 0
701 pull not authorized
702 [1]
703
704 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
705 401 pull not authorized
706
707 0
708 pull not authorized
709 [1]
710
711 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
712 405 push requires POST request
713
714 0
715 push requires POST request
716 [1]
717
718 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
719 401 pull not authorized
720
721 0
722 pull not authorized
723 [1]
724
725 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
726 405 push requires POST request
727
728 0
729 push requires POST request
730 [1]
731
732 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
733 405 push requires POST request
734
735 0
736 push requires POST request
737 [1]
738
739 $ hg --cwd ../test2 pull http://localhost:$HGPORT/
740 pulling from http://localhost:$HGPORT/
741 abort: authorization failed
742 [255]
743
744 $ killdaemons.py
745
746 Attempting a write command with HTTP GET fails
747
748 $ cat > .hg/hgrc <<EOF
749 > EOF
750
751 $ REQUEST_METHOD=GET hg serve -p $HGPORT -d --pid-file hg.pid
752 $ cat hg.pid > $DAEMON_PIDS
753
754 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
755 405 push requires POST request
756
757 0
758 push requires POST request
759 [1]
760
761 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
762 405 push requires POST request
763
764 0
765 push requires POST request
766 [1]
767
768 $ hg bookmarks
769 no bookmarks set
770 $ hg bookmark -d bm
771 abort: bookmark 'bm' does not exist
772 [255]
773
774 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
775 405 push requires POST request
776
777 0
778 push requires POST request
779 [1]
780
781 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
782 405 push requires POST request
783
784 0
785 push requires POST request
786 [1]
787
788 $ killdaemons.py
789
790 Attempting a write command with an unknown HTTP verb fails
791
792 $ REQUEST_METHOD=someverb hg serve -p $HGPORT -d --pid-file hg.pid
793 $ cat hg.pid > $DAEMON_PIDS
794
795 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
796 405 push requires POST request
797
798 0
799 push requires POST request
800 [1]
801
802 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
803 405 push requires POST request
804
805 0
806 push requires POST request
807 [1]
808
809 $ hg bookmarks
810 no bookmarks set
811 $ hg bookmark -d bm
812 abort: bookmark 'bm' does not exist
813 [255]
814
815 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
816 405 push requires POST request
817
818 0
819 push requires POST request
820 [1]
821
822 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
823 405 push requires POST request
824
825 0
826 push requires POST request
827 [1]
828
829 $ killdaemons.py
830
831 Pushing on a plaintext channel is disabled by default
832
833 $ cat > .hg/hgrc <<EOF
834 > EOF
835
836 $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
837 $ cat hg.pid > $DAEMON_PIDS
838
839 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
840 403 ssl required
841
842 0
843 ssl required
844 [1]
845
846 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
847 403 ssl required
848
849 0
850 ssl required
851 [1]
852
853 $ hg bookmarks
854 no bookmarks set
855
856 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
857 403 ssl required
858
859 0
860 ssl required
861 [1]
862
863 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
864 403 ssl required
865
866 0
867 ssl required
868 [1]
869
870 Reset server to remove REQUEST_METHOD hack to test hg client
871
872 $ killdaemons.py
873 $ hg serve -p $HGPORT -d --pid-file hg.pid
874 $ cat hg.pid > $DAEMON_PIDS
875
876 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
877 pushing to http://localhost:$HGPORT/
878 searching for changes
879 no changes found
880 abort: HTTP Error 403: ssl required
881 [255]
882
883 $ hg --cwd ../test2 push http://localhost:$HGPORT/
884 pushing to http://localhost:$HGPORT/
885 searching for changes
886 abort: HTTP Error 403: ssl required
887 [255]
888
889 $ killdaemons.py
890
891 web.deny_push=* denies pushing to unauthenticated users
892
893 $ cat > .hg/hgrc <<EOF
894 > [web]
895 > push_ssl = false
896 > deny_push = *
897 > EOF
898
899 $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
900 $ cat hg.pid > $DAEMON_PIDS
901
902 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
903 401 push not authorized
904
905 0
906 push not authorized
907 [1]
908
909 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
910 401 push not authorized
911
912 0
913 push not authorized
914 [1]
915
916 $ hg bookmarks
917 no bookmarks set
918
919 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
920 401 push not authorized
921
922 0
923 push not authorized
924 [1]
925
926 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
927 401 push not authorized
928
929 0
930 push not authorized
931 [1]
932
933 Reset server to remove REQUEST_METHOD hack to test hg client
934
935 $ killdaemons.py
936 $ hg serve -p $HGPORT -d --pid-file hg.pid
937 $ cat hg.pid > $DAEMON_PIDS
938
939 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
940 pushing to http://localhost:$HGPORT/
941 searching for changes
942 no changes found
943 abort: authorization failed
944 [255]
945
946 $ hg --cwd ../test2 push http://localhost:$HGPORT/
947 pushing to http://localhost:$HGPORT/
948 searching for changes
949 abort: authorization failed
950 [255]
951
952 $ killdaemons.py
953
954 web.deny_push=* denies pushing to authenticated users
955
956 $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
957 $ cat hg.pid > $DAEMON_PIDS
958
959 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
960 401 push not authorized
961
962 0
963 push not authorized
964 [1]
965
966 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
967 401 push not authorized
968
969 0
970 push not authorized
971 [1]
972
973 $ hg bookmarks
974 no bookmarks set
975
976 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
977 401 push not authorized
978
979 0
980 push not authorized
981 [1]
982
983 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
984 401 push not authorized
985
986 0
987 push not authorized
988 [1]
989
990 Reset server to remove REQUEST_METHOD hack to test hg client
991
992 $ killdaemons.py
993 $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
994 $ cat hg.pid > $DAEMON_PIDS
995
996 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
997 pushing to http://localhost:$HGPORT/
998 searching for changes
999 no changes found
1000 abort: authorization failed
1001 [255]
1002
1003 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1004 pushing to http://localhost:$HGPORT/
1005 searching for changes
1006 abort: authorization failed
1007 [255]
1008
1009 $ killdaemons.py
1010
1011 web.deny_push=<user> denies pushing to user in list
1012
1013 $ cat > .hg/hgrc <<EOF
1014 > [web]
1015 > push_ssl = false
1016 > deny_push = baduser
1017 > EOF
1018
1019 $ REMOTE_USER=baduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
1020 $ cat hg.pid > $DAEMON_PIDS
1021
1022 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1023 401 push not authorized
1024
1025 0
1026 push not authorized
1027 [1]
1028
1029 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1030 401 push not authorized
1031
1032 0
1033 push not authorized
1034 [1]
1035
1036 $ hg bookmarks
1037 no bookmarks set
1038
1039 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1040 401 push not authorized
1041
1042 0
1043 push not authorized
1044 [1]
1045
1046 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1047 401 push not authorized
1048
1049 0
1050 push not authorized
1051 [1]
1052
1053 Reset server to remove REQUEST_METHOD hack to test hg client
1054
1055 $ killdaemons.py
1056 $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
1057 $ cat hg.pid > $DAEMON_PIDS
1058
1059 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1060 pushing to http://localhost:$HGPORT/
1061 searching for changes
1062 no changes found
1063 abort: authorization failed
1064 [255]
1065
1066 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1067 pushing to http://localhost:$HGPORT/
1068 searching for changes
1069 abort: authorization failed
1070 [255]
1071
1072 $ killdaemons.py
1073
1074 web.deny_push=<user> denies pushing to user not in list because allow-push isn't set
1075
1076 $ REMOTE_USER=gooduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
1077 $ cat hg.pid > $DAEMON_PIDS
1078
1079 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1080 401 push not authorized
1081
1082 0
1083 push not authorized
1084 [1]
1085
1086 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1087 401 push not authorized
1088
1089 0
1090 push not authorized
1091 [1]
1092
1093 $ hg bookmarks
1094 no bookmarks set
1095
1096 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1097 401 push not authorized
1098
1099 0
1100 push not authorized
1101 [1]
1102
1103 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1104 401 push not authorized
1105
1106 0
1107 push not authorized
1108 [1]
1109
1110 Reset server to remove REQUEST_METHOD hack to test hg client
1111
1112 $ killdaemons.py
1113 $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
1114 $ cat hg.pid > $DAEMON_PIDS
1115
1116 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1117 pushing to http://localhost:$HGPORT/
1118 searching for changes
1119 no changes found
1120 abort: authorization failed
1121 [255]
1122
1123 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1124 pushing to http://localhost:$HGPORT/
1125 searching for changes
1126 abort: authorization failed
1127 [255]
1128
1129 $ killdaemons.py
1130
1131 web.allow-push=* allows pushes from unauthenticated users
1132
1133 $ cat > .hg/hgrc <<EOF
1134 > [web]
1135 > push_ssl = false
1136 > allow-push = *
1137 > EOF
1138
1139 $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
1140 $ cat hg.pid > $DAEMON_PIDS
1141
1142 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1143 200 Script output follows
1144
1145 1
1146
1147 $ hg bookmarks
1148 bm 0:cb9a9f314b8b
1149 $ hg book -d bm
1150
1151 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1152 200 Script output follows
1153
1154 write command no defined permissions
1155
1156 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1157 200 Script output follows
1158
1159 write command w/ defined permissions
1160
1161 Reset server to remove REQUEST_METHOD hack to test hg client
1162
1163 $ killdaemons.py
1164 $ hg serve -p $HGPORT -d --pid-file hg.pid
1165 $ cat hg.pid > $DAEMON_PIDS
1166
1167 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1168 pushing to http://localhost:$HGPORT/
1169 searching for changes
1170 no changes found
1171 exporting bookmark bm
1172 [1]
1173
1174 $ hg book -d bm
1175
1176 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1177 pushing to http://localhost:$HGPORT/
1178 searching for changes
1179 remote: adding changesets
1180 remote: adding manifests
1181 remote: adding file changes
1182 remote: added 1 changesets with 1 changes to 1 files
1183
1184 $ hg strip -r 1:
1185 saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg
1186
1187 $ killdaemons.py
1188
1189 web.allow-push=* allows pushes from authenticated users
1190
1191 $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
1192 $ cat hg.pid > $DAEMON_PIDS
1193
1194 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1195 200 Script output follows
1196
1197 1
1198
1199 $ hg bookmarks
1200 bm 0:cb9a9f314b8b
1201 $ hg book -d bm
1202
1203 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1204 200 Script output follows
1205
1206 write command no defined permissions
1207
1208 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1209 200 Script output follows
1210
1211 write command w/ defined permissions
1212
1213 Reset server to remove REQUEST_METHOD hack to test hg client
1214
1215 $ killdaemons.py
1216 $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
1217 $ cat hg.pid > $DAEMON_PIDS
1218
1219 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1220 pushing to http://localhost:$HGPORT/
1221 searching for changes
1222 no changes found
1223 exporting bookmark bm
1224 [1]
1225
1226 $ hg book -d bm
1227
1228 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1229 pushing to http://localhost:$HGPORT/
1230 searching for changes
1231 remote: adding changesets
1232 remote: adding manifests
1233 remote: adding file changes
1234 remote: added 1 changesets with 1 changes to 1 files
1235
1236 $ hg strip -r 1:
1237 saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg
1238
1239 $ killdaemons.py
1240
1241 web.allow-push=<user> denies push to user not in list
1242
1243 $ cat > .hg/hgrc <<EOF
1244 > [web]
1245 > push_ssl = false
1246 > allow-push = gooduser
1247 > EOF
1248
1249 $ REMOTE_USER=baduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
1250 $ cat hg.pid > $DAEMON_PIDS
1251
1252 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1253 401 push not authorized
1254
1255 0
1256 push not authorized
1257 [1]
1258
1259 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1260 401 push not authorized
1261
1262 0
1263 push not authorized
1264 [1]
1265
1266 $ hg bookmarks
1267 no bookmarks set
1268
1269 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1270 401 push not authorized
1271
1272 0
1273 push not authorized
1274 [1]
1275
1276 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1277 401 push not authorized
1278
1279 0
1280 push not authorized
1281 [1]
1282
1283 Reset server to remove REQUEST_METHOD hack to test hg client
1284
1285 $ killdaemons.py
1286 $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
1287 $ cat hg.pid > $DAEMON_PIDS
1288
1289 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1290 pushing to http://localhost:$HGPORT/
1291 searching for changes
1292 no changes found
1293 abort: authorization failed
1294 [255]
1295
1296 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1297 pushing to http://localhost:$HGPORT/
1298 searching for changes
1299 abort: authorization failed
1300 [255]
1301
1302 $ killdaemons.py
1303
1304 web.allow-push=<user> allows push from user in list
1305
1306 $ REMOTE_USER=gooduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
1307 $ cat hg.pid > $DAEMON_PIDS
1308
1309 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1310 200 Script output follows
1311
1312 1
1313
1314 $ hg bookmarks
1315 bm 0:cb9a9f314b8b
1316 $ hg book -d bm
1317
1318 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1319 200 Script output follows
1320
1321 1
1322
1323 $ hg bookmarks
1324 bm 0:cb9a9f314b8b
1325 $ hg book -d bm
1326
1327 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1328 200 Script output follows
1329
1330 write command no defined permissions
1331
1332 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1333 200 Script output follows
1334
1335 write command w/ defined permissions
1336
1337 Reset server to remove REQUEST_METHOD hack to test hg client
1338
1339 $ killdaemons.py
1340 $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
1341 $ cat hg.pid > $DAEMON_PIDS
1342
1343 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1344 pushing to http://localhost:$HGPORT/
1345 searching for changes
1346 no changes found
1347 exporting bookmark bm
1348 [1]
1349
1350 $ hg book -d bm
1351
1352 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1353 pushing to http://localhost:$HGPORT/
1354 searching for changes
1355 remote: adding changesets
1356 remote: adding manifests
1357 remote: adding file changes
1358 remote: added 1 changesets with 1 changes to 1 files
1359
1360 $ hg strip -r 1:
1361 saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg
1362
1363 $ killdaemons.py
1364
1365 web.deny_push takes precedence over web.allow_push
1366
1367 $ cat > .hg/hgrc <<EOF
1368 > [web]
1369 > push_ssl = false
1370 > allow-push = someuser
1371 > deny_push = someuser
1372 > EOF
1373
1374 $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
1375 $ cat hg.pid > $DAEMON_PIDS
1376
1377 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1378 401 push not authorized
1379
1380 0
1381 push not authorized
1382 [1]
1383
1384 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1385 401 push not authorized
1386
1387 0
1388 push not authorized
1389 [1]
1390
1391 $ hg bookmarks
1392 no bookmarks set
1393
1394 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1395 401 push not authorized
1396
1397 0
1398 push not authorized
1399 [1]
1400
1401 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1402 401 push not authorized
1403
1404 0
1405 push not authorized
1406 [1]
1407
1408 Reset server to remove REQUEST_METHOD hack to test hg client
1409
1410 $ killdaemons.py
1411 $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
1412 $ cat hg.pid > $DAEMON_PIDS
1413
1414 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1415 pushing to http://localhost:$HGPORT/
1416 searching for changes
1417 no changes found
1418 abort: authorization failed
1419 [255]
1420
1421 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1422 pushing to http://localhost:$HGPORT/
1423 searching for changes
1424 abort: authorization failed
1425 [255]
1426
1427 $ killdaemons.py
1428
1429 web.allow-push has no effect if web.deny_read is set
1430
1431 $ cat > .hg/hgrc <<EOF
1432 > [web]
1433 > push_ssl = false
1434 > allow-push = *
1435 > deny_read = *
1436 > EOF
1437
1438 $ REQUEST_METHOD=POST REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
1439 $ cat hg.pid > $DAEMON_PIDS
1440
1441 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1442 401 read not authorized
1443
1444 0
1445 read not authorized
1446 [1]
1447
1448 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
1449 401 read not authorized
1450
1451 0
1452 read not authorized
1453 [1]
1454
1455 $ hg bookmarks
1456 no bookmarks set
1457
1458 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm'
1459 401 read not authorized
1460
1461 0
1462 read not authorized
1463 [1]
1464
1465 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm'
1466 401 read not authorized
1467
1468 0
1469 read not authorized
1470 [1]
1471
1472 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm'
1473 401 read not authorized
1474
1475 0
1476 read not authorized
1477 [1]
1478
1479 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm'
1480 401 read not authorized
1481
1482 0
1483 read not authorized
1484 [1]
1485
1486 Reset server to remove REQUEST_METHOD hack to test hg client
1487
1488 $ killdaemons.py
1489 $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
1490 $ cat hg.pid > $DAEMON_PIDS
1491
1492 $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
1493 pushing to http://localhost:$HGPORT/
1494 abort: authorization failed
1495 [255]
1496
1497 $ hg --cwd ../test2 push http://localhost:$HGPORT/
1498 pushing to http://localhost:$HGPORT/
1499 abort: authorization failed
1500 [255]
1501
1502 $ killdaemons.py
@@ -0,0 +1,97 b''
1 In this test, we want to test LFS bundle application on both LFS and non-LFS
2 repos.
3
4 To make it more interesting, the file revisions will contain hg filelog
5 metadata ('\1\n'). The bundle will have 1 file revision overlapping with the
6 destination repo.
7
8 # rev 1 2 3
9 # repo: yes yes no
10 # bundle: no (base) yes yes (deltabase: 2 if possible)
11
12 It is interesting because rev 2 could have been stored as LFS in the repo, and
13 non-LFS in the bundle; or vice-versa.
14
15 Init
16
17 $ cat >> $HGRCPATH << EOF
18 > [extensions]
19 > lfs=
20 > drawdag=$TESTDIR/drawdag.py
21 > [lfs]
22 > url=file:$TESTTMP/lfs-remote
23 > EOF
24
25 Helper functions
26
27 $ commitxy() {
28 > hg debugdrawdag "$@" <<'EOS'
29 > Y # Y/X=\1\nAAAA\nE\nF
30 > | # Y/Y=\1\nAAAA\nG\nH
31 > X # X/X=\1\nAAAA\nC\n
32 > # X/Y=\1\nAAAA\nD\n
33 > EOS
34 > }
35
36 $ commitz() {
37 > hg debugdrawdag "$@" <<'EOS'
38 > Z # Z/X=\1\nAAAA\nI\n
39 > | # Z/Y=\1\nAAAA\nJ\n
40 > | # Z/Z=\1\nZ
41 > Y
42 > EOS
43 > }
44
45 $ enablelfs() {
46 > cat >> .hg/hgrc <<EOF
47 > [lfs]
48 > track=all()
49 > EOF
50 > }
51
52 Generate bundles
53
54 $ for i in normal lfs; do
55 > NAME=src-$i
56 > hg init $TESTTMP/$NAME
57 > cd $TESTTMP/$NAME
58 > [ $i = lfs ] && enablelfs
59 > commitxy
60 > commitz
61 > hg bundle -q --base X -r Y+Z $TESTTMP/$NAME.bundle
62 > SRCNAMES="$SRCNAMES $NAME"
63 > done
64
65 Prepare destination repos
66
67 $ for i in normal lfs; do
68 > NAME=dst-$i
69 > hg init $TESTTMP/$NAME
70 > cd $TESTTMP/$NAME
71 > [ $i = lfs ] && enablelfs
72 > commitxy
73 > DSTNAMES="$DSTNAMES $NAME"
74 > done
75
76 Apply bundles
77
78 $ for i in $SRCNAMES; do
79 > for j in $DSTNAMES; do
80 > echo ---- Applying $i.bundle to $j ----
81 > cp -R $TESTTMP/$j $TESTTMP/tmp-$i-$j
82 > cd $TESTTMP/tmp-$i-$j
83 > if hg unbundle $TESTTMP/$i.bundle -q 2>/dev/null; then
84 > hg verify -q && echo OK
85 > else
86 > echo CRASHED
87 > fi
88 > done
89 > done
90 ---- Applying src-normal.bundle to dst-normal ----
91 OK
92 ---- Applying src-normal.bundle to dst-lfs ----
93 OK
94 ---- Applying src-lfs.bundle to dst-normal ----
95 OK
96 ---- Applying src-lfs.bundle to dst-lfs ----
97 OK
@@ -158,3 +158,5 b' cabc840ffdee8a72f3689fb77dd74d04fdc2bc04'
158 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
@@ -171,3 +171,5 b' cabc840ffdee8a72f3689fb77dd74d04fdc2bc04'
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
174 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1
175 8bba684efde7f45add05f737952093bb2aa07155 4.5.2
@@ -12,7 +12,6 b' from __future__ import absolute_import'
12 from mercurial.i18n import _
12 from mercurial.i18n import _
13
13
14 from mercurial.hgweb import (
14 from mercurial.hgweb import (
15 hgweb_mod,
16 webcommands,
15 webcommands,
17 )
16 )
18
17
@@ -175,9 +174,10 b' def uisetup(ui):'
175
174
176 # make putlfile behave the same as push and {get,stat}lfile behave
175 # make putlfile behave the same as push and {get,stat}lfile behave
177 # the same as pull w.r.t. permissions checks
176 # the same as pull w.r.t. permissions checks
178 hgweb_mod.perms['putlfile'] = 'push'
177 wireproto.permissions['putlfile'] = 'push'
179 hgweb_mod.perms['getlfile'] = 'pull'
178 wireproto.permissions['getlfile'] = 'pull'
180 hgweb_mod.perms['statlfile'] = 'pull'
179 wireproto.permissions['statlfile'] = 'pull'
180 wireproto.permissions['lheads'] = 'pull'
181
181
182 extensions.wrapfunction(webcommands, 'decodepath', overrides.decodepath)
182 extensions.wrapfunction(webcommands, 'decodepath', overrides.decodepath)
183
183
@@ -774,6 +774,8 b' class cg1packer(object):'
774 progress(msgbundling, None)
774 progress(msgbundling, None)
775
775
776 def deltaparent(self, revlog, rev, p1, p2, prev):
776 def deltaparent(self, revlog, rev, p1, p2, prev):
777 if not revlog.candelta(prev, rev):
778 raise error.ProgrammingError('cg1 should not be used in this case')
777 return prev
779 return prev
778
780
779 def revchunk(self, revlog, rev, prev, linknode):
781 def revchunk(self, revlog, rev, prev, linknode):
@@ -833,16 +835,19 b' class cg2packer(cg1packer):'
833 # expensive. The revlog caches should have prev cached, meaning
835 # expensive. The revlog caches should have prev cached, meaning
834 # less CPU for changegroup generation. There is likely room to add
836 # less CPU for changegroup generation. There is likely room to add
835 # a flag and/or config option to control this behavior.
837 # a flag and/or config option to control this behavior.
836 return prev
838 base = prev
837 elif dp == nullrev:
839 elif dp == nullrev:
838 # revlog is configured to use full snapshot for a reason,
840 # revlog is configured to use full snapshot for a reason,
839 # stick to full snapshot.
841 # stick to full snapshot.
840 return nullrev
842 base = nullrev
841 elif dp not in (p1, p2, prev):
843 elif dp not in (p1, p2, prev):
842 # Pick prev when we can't be sure remote has the base revision.
844 # Pick prev when we can't be sure remote has the base revision.
843 return prev
845 return prev
844 else:
846 else:
845 return dp
847 base = dp
848 if base != nullrev and not revlog.candelta(base, rev):
849 base = nullrev
850 return base
846
851
847 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
852 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
848 # Do nothing with flags, it is implicitly 0 in cg1 and cg2
853 # Do nothing with flags, it is implicitly 0 in cg1 and cg2
@@ -37,6 +37,7 b' from .. import ('
37 templater,
37 templater,
38 ui as uimod,
38 ui as uimod,
39 util,
39 util,
40 wireproto,
40 wireprotoserver,
41 wireprotoserver,
41 )
42 )
42
43
@@ -46,15 +47,8 b' from . import ('
46 wsgicgi,
47 wsgicgi,
47 )
48 )
48
49
49 perms = {
50 # Aliased for API compatibility.
50 'changegroup': 'pull',
51 perms = wireproto.permissions
51 'changegroupsubset': 'pull',
52 'getbundle': 'pull',
53 'stream_out': 'pull',
54 'listkeys': 'pull',
55 'unbundle': 'push',
56 'pushkey': 'push',
57 }
58
52
59 archivespecs = util.sortdict((
53 archivespecs = util.sortdict((
60 ('zip', ('application/zip', 'zip', '.zip', None)),
54 ('zip', ('application/zip', 'zip', '.zip', None)),
@@ -367,13 +361,21 b' class hgweb(object):'
367 try:
361 try:
368 if query:
362 if query:
369 raise ErrorResponse(HTTP_NOT_FOUND)
363 raise ErrorResponse(HTTP_NOT_FOUND)
370 if cmd in perms:
364
371 self.check_perm(rctx, req, perms[cmd])
365 # TODO fold this into parsehttprequest
366 req.checkperm = lambda op: self.check_perm(rctx, req, op)
367 protohandler['proto'].checkperm = req.checkperm
368
369 # Assume commands with no defined permissions are writes /
370 # for pushes. This is the safest from a security perspective
371 # because it doesn't allow commands with undefined semantics
372 # from bypassing permissions checks.
373 req.checkperm(perms.get(cmd, 'push'))
374
375 return protohandler['dispatch']()
372 except ErrorResponse as inst:
376 except ErrorResponse as inst:
373 return protohandler['handleerror'](inst)
377 return protohandler['handleerror'](inst)
374
378
375 return protohandler['dispatch']()
376
377 # translate user-visible url structure to internal structure
379 # translate user-visible url structure to internal structure
378
380
379 args = query.split('/', 2)
381 args = query.split('/', 2)
@@ -77,6 +77,8 b' REVIDX_FLAGS_ORDER = ['
77 REVIDX_EXTSTORED,
77 REVIDX_EXTSTORED,
78 ]
78 ]
79 REVIDX_KNOWN_FLAGS = util.bitsfrom(REVIDX_FLAGS_ORDER)
79 REVIDX_KNOWN_FLAGS = util.bitsfrom(REVIDX_FLAGS_ORDER)
80 # bitmark for flags that could cause rawdata content change
81 REVIDX_RAWTEXT_CHANGING_FLAGS = REVIDX_ISCENSORED | REVIDX_EXTSTORED
80
82
81 # max size of revlog with inline data
83 # max size of revlog with inline data
82 _maxinline = 131072
84 _maxinline = 131072
@@ -96,7 +98,8 b' def addflagprocessor(flag, processor):'
96 """Register a flag processor on a revision data flag.
98 """Register a flag processor on a revision data flag.
97
99
98 Invariant:
100 Invariant:
99 - Flags need to be defined in REVIDX_KNOWN_FLAGS and REVIDX_FLAGS_ORDER.
101 - Flags need to be defined in REVIDX_KNOWN_FLAGS and REVIDX_FLAGS_ORDER,
102 and REVIDX_RAWTEXT_CHANGING_FLAGS if they can alter rawtext.
100 - Only one flag processor can be registered on a specific flag.
103 - Only one flag processor can be registered on a specific flag.
101 - flagprocessors must be 3-tuples of functions (read, write, raw) with the
104 - flagprocessors must be 3-tuples of functions (read, write, raw) with the
102 following signatures:
105 following signatures:
@@ -333,7 +336,9 b' class _deltacomputer(object):'
333 len(delta) - hlen):
336 len(delta) - hlen):
334 btext[0] = delta[hlen:]
337 btext[0] = delta[hlen:]
335 else:
338 else:
336 basetext = revlog.revision(baserev, _df=fh, raw=True)
339 # deltabase is rawtext before changed by flag processors, which is
340 # equivalent to non-raw text
341 basetext = revlog.revision(baserev, _df=fh, raw=False)
337 btext[0] = mdiff.patch(basetext, delta)
342 btext[0] = mdiff.patch(basetext, delta)
338
343
339 try:
344 try:
@@ -404,6 +409,9 b' class _deltacomputer(object):'
404 for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta):
409 for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta):
405 nominateddeltas = []
410 nominateddeltas = []
406 for candidaterev in candidaterevs:
411 for candidaterev in candidaterevs:
412 # no delta for rawtext-changing revs (see "candelta" for why)
413 if revlog.flags(candidaterev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
414 continue
407 candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh)
415 candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh)
408 if revlog._isgooddeltainfo(candidatedelta, revinfo.textlen):
416 if revlog._isgooddeltainfo(candidatedelta, revinfo.textlen):
409 nominateddeltas.append(candidatedelta)
417 nominateddeltas.append(candidatedelta)
@@ -738,6 +746,18 b' class revlog(object):'
738 except KeyError:
746 except KeyError:
739 return False
747 return False
740
748
749 def candelta(self, baserev, rev):
750 """whether two revisions (baserev, rev) can be delta-ed or not"""
751 # Disable delta if either rev requires a content-changing flag
752 # processor (ex. LFS). This is because such flag processor can alter
753 # the rawtext content that the delta will be based on, and two clients
754 # could have a same revlog node with different flags (i.e. different
755 # rawtext contents) and the delta could be incompatible.
756 if ((self.flags(baserev) & REVIDX_RAWTEXT_CHANGING_FLAGS)
757 or (self.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS)):
758 return False
759 return True
760
741 def clearcaches(self):
761 def clearcaches(self):
742 self._cache = None
762 self._cache = None
743 self._chainbasecache.clear()
763 self._chainbasecache.clear()
@@ -2078,7 +2098,10 b' class revlog(object):'
2078 # full versions are inserted when the needed deltas
2098 # full versions are inserted when the needed deltas
2079 # become comparable to the uncompressed text
2099 # become comparable to the uncompressed text
2080 if rawtext is None:
2100 if rawtext is None:
2081 textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]),
2101 # need rawtext size, before changed by flag processors, which is
2102 # the non-raw size. use revlog explicitly to avoid filelog's extra
2103 # logic that might remove metadata size.
2104 textlen = mdiff.patchedsize(revlog.size(self, cachedelta[0]),
2082 cachedelta[1])
2105 cachedelta[1])
2083 else:
2106 else:
2084 textlen = len(rawtext)
2107 textlen = len(rawtext)
@@ -2087,7 +2110,14 b' class revlog(object):'
2087 deltacomputer = _deltacomputer(self)
2110 deltacomputer = _deltacomputer(self)
2088
2111
2089 revinfo = _revisioninfo(node, p1, p2, btext, textlen, cachedelta, flags)
2112 revinfo = _revisioninfo(node, p1, p2, btext, textlen, cachedelta, flags)
2090 deltainfo = deltacomputer.finddeltainfo(revinfo, fh)
2113
2114 # no delta for flag processor revision (see "candelta" for why)
2115 # not calling candelta since only one revision needs test, also to
2116 # avoid overhead fetching flags again.
2117 if flags & REVIDX_RAWTEXT_CHANGING_FLAGS:
2118 deltainfo = None
2119 else:
2120 deltainfo = deltacomputer.finddeltainfo(revinfo, fh)
2091
2121
2092 if deltainfo is not None:
2122 if deltainfo is not None:
2093 base = deltainfo.base
2123 base = deltainfo.base
@@ -672,6 +672,11 b" POLICY_V2_ONLY = 'v2-only'"
672
672
673 commands = commanddict()
673 commands = commanddict()
674
674
675 # Maps wire protocol name to operation type. This is used for permissions
676 # checking. All defined @wireiprotocommand should have an entry in this
677 # dict.
678 permissions = {}
679
675 def wireprotocommand(name, args='', transportpolicy=POLICY_ALL):
680 def wireprotocommand(name, args='', transportpolicy=POLICY_ALL):
676 """Decorator to declare a wire protocol command.
681 """Decorator to declare a wire protocol command.
677
682
@@ -701,6 +706,8 b" def wireprotocommand(name, args='', tran"
701 return func
706 return func
702 return register
707 return register
703
708
709 # TODO define a more appropriate permissions type to use for this.
710 permissions['batch'] = 'pull'
704 @wireprotocommand('batch', 'cmds *')
711 @wireprotocommand('batch', 'cmds *')
705 def batch(repo, proto, cmds, others):
712 def batch(repo, proto, cmds, others):
706 repo = repo.filtered("served")
713 repo = repo.filtered("served")
@@ -713,6 +720,17 b' def batch(repo, proto, cmds, others):'
713 n, v = a.split('=')
720 n, v = a.split('=')
714 vals[unescapearg(n)] = unescapearg(v)
721 vals[unescapearg(n)] = unescapearg(v)
715 func, spec = commands[op]
722 func, spec = commands[op]
723
724 # If the protocol supports permissions checking, perform that
725 # checking on each batched command.
726 # TODO formalize permission checking as part of protocol interface.
727 if util.safehasattr(proto, 'checkperm'):
728 # Assume commands with no defined permissions are writes / for
729 # pushes. This is the safest from a security perspective because
730 # it doesn't allow commands with undefined semantics from
731 # bypassing permissions checks.
732 proto.checkperm(permissions.get(op, 'push'))
733
716 if spec:
734 if spec:
717 keys = spec.split()
735 keys = spec.split()
718 data = {}
736 data = {}
@@ -740,6 +758,7 b' def batch(repo, proto, cmds, others):'
740
758
741 return bytesresponse(';'.join(res))
759 return bytesresponse(';'.join(res))
742
760
761 permissions['between'] = 'pull'
743 @wireprotocommand('between', 'pairs', transportpolicy=POLICY_V1_ONLY)
762 @wireprotocommand('between', 'pairs', transportpolicy=POLICY_V1_ONLY)
744 def between(repo, proto, pairs):
763 def between(repo, proto, pairs):
745 pairs = [decodelist(p, '-') for p in pairs.split(" ")]
764 pairs = [decodelist(p, '-') for p in pairs.split(" ")]
@@ -749,6 +768,7 b' def between(repo, proto, pairs):'
749
768
750 return bytesresponse(''.join(r))
769 return bytesresponse(''.join(r))
751
770
771 permissions['branchmap'] = 'pull'
752 @wireprotocommand('branchmap')
772 @wireprotocommand('branchmap')
753 def branchmap(repo, proto):
773 def branchmap(repo, proto):
754 branchmap = repo.branchmap()
774 branchmap = repo.branchmap()
@@ -760,6 +780,7 b' def branchmap(repo, proto):'
760
780
761 return bytesresponse('\n'.join(heads))
781 return bytesresponse('\n'.join(heads))
762
782
783 permissions['branches'] = 'pull'
763 @wireprotocommand('branches', 'nodes', transportpolicy=POLICY_V1_ONLY)
784 @wireprotocommand('branches', 'nodes', transportpolicy=POLICY_V1_ONLY)
764 def branches(repo, proto, nodes):
785 def branches(repo, proto, nodes):
765 nodes = decodelist(nodes)
786 nodes = decodelist(nodes)
@@ -769,6 +790,7 b' def branches(repo, proto, nodes):'
769
790
770 return bytesresponse(''.join(r))
791 return bytesresponse(''.join(r))
771
792
793 permissions['clonebundles'] = 'pull'
772 @wireprotocommand('clonebundles', '')
794 @wireprotocommand('clonebundles', '')
773 def clonebundles(repo, proto):
795 def clonebundles(repo, proto):
774 """Server command for returning info for available bundles to seed clones.
796 """Server command for returning info for available bundles to seed clones.
@@ -821,10 +843,12 b' def _capabilities(repo, proto):'
821
843
822 # If you are writing an extension and consider wrapping this function. Wrap
844 # If you are writing an extension and consider wrapping this function. Wrap
823 # `_capabilities` instead.
845 # `_capabilities` instead.
846 permissions['capabilities'] = 'pull'
824 @wireprotocommand('capabilities')
847 @wireprotocommand('capabilities')
825 def capabilities(repo, proto):
848 def capabilities(repo, proto):
826 return bytesresponse(' '.join(_capabilities(repo, proto)))
849 return bytesresponse(' '.join(_capabilities(repo, proto)))
827
850
851 permissions['changegroup'] = 'pull'
828 @wireprotocommand('changegroup', 'roots', transportpolicy=POLICY_V1_ONLY)
852 @wireprotocommand('changegroup', 'roots', transportpolicy=POLICY_V1_ONLY)
829 def changegroup(repo, proto, roots):
853 def changegroup(repo, proto, roots):
830 nodes = decodelist(roots)
854 nodes = decodelist(roots)
@@ -834,6 +858,7 b' def changegroup(repo, proto, roots):'
834 gen = iter(lambda: cg.read(32768), '')
858 gen = iter(lambda: cg.read(32768), '')
835 return streamres(gen=gen)
859 return streamres(gen=gen)
836
860
861 permissions['changegroupsubset'] = 'pull'
837 @wireprotocommand('changegroupsubset', 'bases heads',
862 @wireprotocommand('changegroupsubset', 'bases heads',
838 transportpolicy=POLICY_V1_ONLY)
863 transportpolicy=POLICY_V1_ONLY)
839 def changegroupsubset(repo, proto, bases, heads):
864 def changegroupsubset(repo, proto, bases, heads):
@@ -845,6 +870,7 b' def changegroupsubset(repo, proto, bases'
845 gen = iter(lambda: cg.read(32768), '')
870 gen = iter(lambda: cg.read(32768), '')
846 return streamres(gen=gen)
871 return streamres(gen=gen)
847
872
873 permissions['debugwireargs'] = 'pull'
848 @wireprotocommand('debugwireargs', 'one two *')
874 @wireprotocommand('debugwireargs', 'one two *')
849 def debugwireargs(repo, proto, one, two, others):
875 def debugwireargs(repo, proto, one, two, others):
850 # only accept optional args from the known set
876 # only accept optional args from the known set
@@ -852,6 +878,7 b' def debugwireargs(repo, proto, one, two,'
852 return bytesresponse(repo.debugwireargs(one, two,
878 return bytesresponse(repo.debugwireargs(one, two,
853 **pycompat.strkwargs(opts)))
879 **pycompat.strkwargs(opts)))
854
880
881 permissions['getbundle'] = 'pull'
855 @wireprotocommand('getbundle', '*')
882 @wireprotocommand('getbundle', '*')
856 def getbundle(repo, proto, others):
883 def getbundle(repo, proto, others):
857 opts = options('getbundle', gboptsmap.keys(), others)
884 opts = options('getbundle', gboptsmap.keys(), others)
@@ -918,11 +945,13 b' def getbundle(repo, proto, others):'
918
945
919 return streamres(gen=chunks, prefer_uncompressed=not prefercompressed)
946 return streamres(gen=chunks, prefer_uncompressed=not prefercompressed)
920
947
948 permissions['heads'] = 'pull'
921 @wireprotocommand('heads')
949 @wireprotocommand('heads')
922 def heads(repo, proto):
950 def heads(repo, proto):
923 h = repo.heads()
951 h = repo.heads()
924 return bytesresponse(encodelist(h) + '\n')
952 return bytesresponse(encodelist(h) + '\n')
925
953
954 permissions['hello'] = 'pull'
926 @wireprotocommand('hello')
955 @wireprotocommand('hello')
927 def hello(repo, proto):
956 def hello(repo, proto):
928 """Called as part of SSH handshake to obtain server info.
957 """Called as part of SSH handshake to obtain server info.
@@ -938,11 +967,13 b' def hello(repo, proto):'
938 caps = capabilities(repo, proto).data
967 caps = capabilities(repo, proto).data
939 return bytesresponse('capabilities: %s\n' % caps)
968 return bytesresponse('capabilities: %s\n' % caps)
940
969
970 permissions['listkeys'] = 'pull'
941 @wireprotocommand('listkeys', 'namespace')
971 @wireprotocommand('listkeys', 'namespace')
942 def listkeys(repo, proto, namespace):
972 def listkeys(repo, proto, namespace):
943 d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
973 d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
944 return bytesresponse(pushkeymod.encodekeys(d))
974 return bytesresponse(pushkeymod.encodekeys(d))
945
975
976 permissions['lookup'] = 'pull'
946 @wireprotocommand('lookup', 'key')
977 @wireprotocommand('lookup', 'key')
947 def lookup(repo, proto, key):
978 def lookup(repo, proto, key):
948 try:
979 try:
@@ -955,11 +986,13 b' def lookup(repo, proto, key):'
955 success = 0
986 success = 0
956 return bytesresponse('%d %s\n' % (success, r))
987 return bytesresponse('%d %s\n' % (success, r))
957
988
989 permissions['known'] = 'pull'
958 @wireprotocommand('known', 'nodes *')
990 @wireprotocommand('known', 'nodes *')
959 def known(repo, proto, nodes, others):
991 def known(repo, proto, nodes, others):
960 v = ''.join(b and '1' or '0' for b in repo.known(decodelist(nodes)))
992 v = ''.join(b and '1' or '0' for b in repo.known(decodelist(nodes)))
961 return bytesresponse(v)
993 return bytesresponse(v)
962
994
995 permissions['pushkey'] = 'push'
963 @wireprotocommand('pushkey', 'namespace key old new')
996 @wireprotocommand('pushkey', 'namespace key old new')
964 def pushkey(repo, proto, namespace, key, old, new):
997 def pushkey(repo, proto, namespace, key, old, new):
965 # compatibility with pre-1.8 clients which were accidentally
998 # compatibility with pre-1.8 clients which were accidentally
@@ -981,6 +1014,7 b' def pushkey(repo, proto, namespace, key,'
981 output = output.getvalue() if output else ''
1014 output = output.getvalue() if output else ''
982 return bytesresponse('%d\n%s' % (int(r), output))
1015 return bytesresponse('%d\n%s' % (int(r), output))
983
1016
1017 permissions['stream_out'] = 'pull'
984 @wireprotocommand('stream_out')
1018 @wireprotocommand('stream_out')
985 def stream(repo, proto):
1019 def stream(repo, proto):
986 '''If the server supports streaming clone, it advertises the "stream"
1020 '''If the server supports streaming clone, it advertises the "stream"
@@ -989,6 +1023,7 b' def stream(repo, proto):'
989 '''
1023 '''
990 return streamres_legacy(streamclone.generatev1wireproto(repo))
1024 return streamres_legacy(streamclone.generatev1wireproto(repo))
991
1025
1026 permissions['unbundle'] = 'push'
992 @wireprotocommand('unbundle', 'heads')
1027 @wireprotocommand('unbundle', 'heads')
993 def unbundle(repo, proto, heads):
1028 def unbundle(repo, proto, heads):
994 their_heads = decodelist(heads)
1029 their_heads = decodelist(heads)
@@ -371,7 +371,8 b' def debugdrawdag(ui, repo, **opts):'
371 comments = list(_getcomments(text))
371 comments = list(_getcomments(text))
372 filere = re.compile(br'^(\w+)/([\w/]+)\s*=\s*(.*)$', re.M)
372 filere = re.compile(br'^(\w+)/([\w/]+)\s*=\s*(.*)$', re.M)
373 for name, path, content in filere.findall(b'\n'.join(comments)):
373 for name, path, content in filere.findall(b'\n'.join(comments)):
374 files[name][path] = content.replace(br'\n', b'\n')
374 content = content.replace(br'\n', b'\n').replace(br'\1', b'\1')
375 files[name][path] = content
375
376
376 committed = {None: node.nullid} # {name: node}
377 committed = {None: node.nullid} # {name: node}
377
378
@@ -903,9 +903,15 b' Annotate with orphaned CR (issue5798)'
903 $ hg init repo-cr
903 $ hg init repo-cr
904 $ cd repo-cr
904 $ cd repo-cr
905
905
906 $ substcr() {
906 $ cat <<'EOF' >> "$TESTTMP/substcr.py"
907 > sed 's/\r/[CR]/g'
907 > import sys
908 > }
908 > from mercurial import util
909 > util.setbinary(sys.stdin)
910 > util.setbinary(sys.stdout)
911 > stdin = getattr(sys.stdin, 'buffer', sys.stdin)
912 > stdout = getattr(sys.stdout, 'buffer', sys.stdout)
913 > stdout.write(stdin.read().replace(b'\r', b'[CR]'))
914 > EOF
909
915
910 >>> with open('a', 'wb') as f:
916 >>> with open('a', 'wb') as f:
911 ... f.write(b'0a\r0b\r\n0c\r0d\r\n0e\n0f\n0g')
917 ... f.write(b'0a\r0b\r\n0c\r0d\r\n0e\n0f\n0g')
@@ -914,13 +920,13 b' Annotate with orphaned CR (issue5798)'
914 ... f.write(b'0a\r0b\r\n1c\r1d\r\n0e\n1f\n0g')
920 ... f.write(b'0a\r0b\r\n1c\r1d\r\n0e\n1f\n0g')
915 $ hg ci -m1
921 $ hg ci -m1
916
922
917 $ hg annotate -r0 a | substcr
923 $ hg annotate -r0 a | $PYTHON "$TESTTMP/substcr.py"
918 0: 0a[CR]0b[CR]
924 0: 0a[CR]0b[CR]
919 0: 0c[CR]0d[CR]
925 0: 0c[CR]0d[CR]
920 0: 0e
926 0: 0e
921 0: 0f
927 0: 0f
922 0: 0g
928 0: 0g
923 $ hg annotate -r1 a | substcr
929 $ hg annotate -r1 a | $PYTHON "$TESTTMP/substcr.py"
924 0: 0a[CR]0b[CR]
930 0: 0a[CR]0b[CR]
925 1: 1c[CR]1d[CR]
931 1: 1c[CR]1d[CR]
926 0: 0e
932 0: 0e
@@ -260,60 +260,52 b' test http authentication'
260 $ hg rollback -q
260 $ hg rollback -q
261
261
262 $ sed 's/.*] "/"/' < ../access.log
262 $ sed 's/.*] "/"/' < ../access.log
263 "GET /?cmd=capabilities HTTP/1.1" 200 -
263 "GET /?cmd=capabilities HTTP/1.1" 401 -
264 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
264 "GET /?cmd=capabilities HTTP/1.1" 401 -
265 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
265 "GET /?cmd=capabilities HTTP/1.1" 401 -
266 "GET /?cmd=capabilities HTTP/1.1" 200 -
266 "GET /?cmd=capabilities HTTP/1.1" 200 -
267 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
267 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
268 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
268 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
269 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
270 "GET /?cmd=capabilities HTTP/1.1" 401 -
269 "GET /?cmd=capabilities HTTP/1.1" 200 -
271 "GET /?cmd=capabilities HTTP/1.1" 200 -
270 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
272 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
271 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
272 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
273 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
274 "GET /?cmd=capabilities HTTP/1.1" 200 -
275 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
276 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
277 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
273 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
278 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
274 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
275 "GET /?cmd=capabilities HTTP/1.1" 401 -
279 "GET /?cmd=capabilities HTTP/1.1" 200 -
276 "GET /?cmd=capabilities HTTP/1.1" 200 -
280 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
277 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
281 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
282 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
278 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
283 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
279 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
280 "GET /?cmd=capabilities HTTP/1.1" 401 -
284 "GET /?cmd=capabilities HTTP/1.1" 200 -
281 "GET /?cmd=capabilities HTTP/1.1" 200 -
285 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
282 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
286 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
287 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
283 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
288 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
284 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
285 "GET /?cmd=capabilities HTTP/1.1" 401 -
289 "GET /?cmd=capabilities HTTP/1.1" 200 -
286 "GET /?cmd=capabilities HTTP/1.1" 200 -
290 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
287 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
291 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
292 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
288 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
293 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
289 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
290 "GET /?cmd=capabilities HTTP/1.1" 401 -
294 "GET /?cmd=capabilities HTTP/1.1" 200 -
291 "GET /?cmd=capabilities HTTP/1.1" 200 -
295 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
292 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
296 "GET /?cmd=stream_out HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
297 "GET /?cmd=stream_out HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
293 "GET /?cmd=stream_out HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
298 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
294 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
299 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
295 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
300 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
296 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
297 "GET /?cmd=capabilities HTTP/1.1" 401 -
301 "GET /?cmd=capabilities HTTP/1.1" 200 -
298 "GET /?cmd=capabilities HTTP/1.1" 200 -
302 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
303 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
299 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
304 "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$
300 "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$
305 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
301 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
306 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
302 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
307 "GET /?cmd=capabilities HTTP/1.1" 200 -
303 "GET /?cmd=capabilities HTTP/1.1" 401 -
308 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
304 "GET /?cmd=capabilities HTTP/1.1" 401 -
309 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
305 "GET /?cmd=capabilities HTTP/1.1" 403 -
310 "GET /?cmd=capabilities HTTP/1.1" 200 -
306 "GET /?cmd=capabilities HTTP/1.1" 401 -
311 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
312 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
313 "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
314 "GET /?cmd=capabilities HTTP/1.1" 200 -
307 "GET /?cmd=capabilities HTTP/1.1" 200 -
315 "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$
308 "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$
316 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
317 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
309 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
318 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
310 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
319 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
311 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
@@ -254,6 +254,7 b' test http authentication'
254 http auth: user user, password ****
254 http auth: user user, password ****
255 sending capabilities command
255 sending capabilities command
256 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=capabilities
256 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=capabilities
257 http auth: user user, password ****
257 devel-peer-request: finished in *.???? seconds (200) (glob)
258 devel-peer-request: finished in *.???? seconds (200) (glob)
258 query 1; heads
259 query 1; heads
259 sending batch command
260 sending batch command
@@ -270,7 +271,6 b' test http authentication'
270 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
271 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
271 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$
272 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$
272 devel-peer-request: 16 bytes of commands arguments in headers
273 devel-peer-request: 16 bytes of commands arguments in headers
273 http auth: user user, password ****
274 devel-peer-request: finished in *.???? seconds (200) (glob)
274 devel-peer-request: finished in *.???? seconds (200) (glob)
275 received listkey for "phases": 58 bytes
275 received listkey for "phases": 58 bytes
276 checking for updated bookmarks
276 checking for updated bookmarks
@@ -340,57 +340,49 b' test http authentication'
340 $ hg rollback -q
340 $ hg rollback -q
341
341
342 $ sed 's/.*] "/"/' < ../access.log
342 $ sed 's/.*] "/"/' < ../access.log
343 "GET /?cmd=capabilities HTTP/1.1" 200 -
343 "GET /?cmd=capabilities HTTP/1.1" 401 -
344 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
344 "GET /?cmd=capabilities HTTP/1.1" 401 -
345 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
345 "GET /?cmd=capabilities HTTP/1.1" 401 -
346 "GET /?cmd=capabilities HTTP/1.1" 200 -
346 "GET /?cmd=capabilities HTTP/1.1" 200 -
347 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
347 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
348 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
348 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
349 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
350 "GET /?cmd=capabilities HTTP/1.1" 401 -
349 "GET /?cmd=capabilities HTTP/1.1" 200 -
351 "GET /?cmd=capabilities HTTP/1.1" 200 -
350 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
352 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
351 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
352 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
353 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
354 "GET /?cmd=capabilities HTTP/1.1" 200 -
355 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
356 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
357 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
353 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
358 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
354 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
355 "GET /?cmd=capabilities HTTP/1.1" 401 -
359 "GET /?cmd=capabilities HTTP/1.1" 200 -
356 "GET /?cmd=capabilities HTTP/1.1" 200 -
360 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
357 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
361 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
362 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
358 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
363 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
359 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
360 "GET /?cmd=capabilities HTTP/1.1" 401 -
364 "GET /?cmd=capabilities HTTP/1.1" 200 -
361 "GET /?cmd=capabilities HTTP/1.1" 200 -
365 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
362 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
366 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
367 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
363 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
368 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
364 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
365 "GET /?cmd=capabilities HTTP/1.1" 401 -
369 "GET /?cmd=capabilities HTTP/1.1" 200 -
366 "GET /?cmd=capabilities HTTP/1.1" 200 -
370 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
367 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
371 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
372 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
368 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
373 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
369 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
370 "GET /?cmd=capabilities HTTP/1.1" 401 -
374 "GET /?cmd=capabilities HTTP/1.1" 200 -
371 "GET /?cmd=capabilities HTTP/1.1" 200 -
375 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
372 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
376 "GET /?cmd=stream_out HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
377 "GET /?cmd=stream_out HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
373 "GET /?cmd=stream_out HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
378 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
374 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
379 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
375 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
376 "GET /?cmd=capabilities HTTP/1.1" 401 -
380 "GET /?cmd=capabilities HTTP/1.1" 200 -
377 "GET /?cmd=capabilities HTTP/1.1" 200 -
381 "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$
378 "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$
382 "GET /?cmd=getbundle HTTP/1.1" 401 - 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$
383 "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$
379 "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$
384 "GET /?cmd=capabilities HTTP/1.1" 200 -
380 "GET /?cmd=capabilities HTTP/1.1" 401 -
385 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
381 "GET /?cmd=capabilities HTTP/1.1" 401 -
386 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
382 "GET /?cmd=capabilities HTTP/1.1" 403 -
387 "GET /?cmd=capabilities HTTP/1.1" 200 -
383 "GET /?cmd=capabilities HTTP/1.1" 401 -
388 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
389 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
390 "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
391 "GET /?cmd=capabilities HTTP/1.1" 200 -
384 "GET /?cmd=capabilities HTTP/1.1" 200 -
392 "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$
385 "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$
393 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
394 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
386 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
395 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
387 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
396 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
388 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
@@ -398,9 +390,9 b' test http authentication'
398 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
390 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
399 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
391 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
400 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
392 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
393 "GET /?cmd=capabilities HTTP/1.1" 401 -
401 "GET /?cmd=capabilities HTTP/1.1" 200 -
394 "GET /?cmd=capabilities HTTP/1.1" 200 -
402 "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$
395 "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$
403 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
404 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
396 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
405 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
397 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
406 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
398 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$
@@ -444,11 +444,11 b' a large file from the server rather than'
444 > EOF
444 > EOF
445 $ hg clone --config ui.interactive=true --config extensions.getpass=get_pass.py \
445 $ hg clone --config ui.interactive=true --config extensions.getpass=get_pass.py \
446 > http://user@localhost:$HGPORT credentialclone
446 > http://user@localhost:$HGPORT credentialclone
447 requesting all changes
448 http authorization required for http://localhost:$HGPORT/
447 http authorization required for http://localhost:$HGPORT/
449 realm: mercurial
448 realm: mercurial
450 user: user
449 user: user
451 password: adding changesets
450 password: requesting all changes
451 adding changesets
452 adding manifests
452 adding manifests
453 adding file changes
453 adding file changes
454 added 1 changesets with 1 changes to 1 files
454 added 1 changesets with 1 changes to 1 files
@@ -371,7 +371,7 b' enabled adds the lfs requirement'
371 uncompressed size of bundle content:
371 uncompressed size of bundle content:
372 * (changelog) (glob)
372 * (changelog) (glob)
373 * (manifests) (glob)
373 * (manifests) (glob)
374 * a (glob)
374 * a (glob)
375 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
375 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
376 $ hg -R bundle.hg log -p -T '{rev} {desc}\n' a
376 $ hg -R bundle.hg log -p -T '{rev} {desc}\n' a
377 5 branching
377 5 branching
@@ -50,7 +50,6 b' expect error, cloning not allowed'
50 $ hg serve -p $HGPORT -d --pid-file=hg.pid -E errors.log
50 $ hg serve -p $HGPORT -d --pid-file=hg.pid -E errors.log
51 $ cat hg.pid >> $DAEMON_PIDS
51 $ cat hg.pid >> $DAEMON_PIDS
52 $ hg clone http://localhost:$HGPORT/ test4 # bundle2+
52 $ hg clone http://localhost:$HGPORT/ test4 # bundle2+
53 requesting all changes
54 abort: authorization failed
53 abort: authorization failed
55 [255]
54 [255]
56 $ hg clone http://localhost:$HGPORT/ test4 --config devel.legacy.exchange=bundle1
55 $ hg clone http://localhost:$HGPORT/ test4 --config devel.legacy.exchange=bundle1
@@ -74,7 +73,6 b' expect error, pulling not allowed'
74
73
75 $ req
74 $ req
76 pulling from http://localhost:$HGPORT/
75 pulling from http://localhost:$HGPORT/
77 searching for changes
78 abort: authorization failed
76 abort: authorization failed
79 % serve errors
77 % serve errors
80
78
@@ -307,28 +307,6 b' Make phases updates work'
307 $ hg --config extensions.strip= strip -r 1:
307 $ hg --config extensions.strip= strip -r 1:
308 saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg
308 saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg
309
309
310 expect authorization error: all users denied
311
312 $ echo '[web]' > .hg/hgrc
313 $ echo 'push_ssl = false' >> .hg/hgrc
314 $ echo 'deny_push = *' >> .hg/hgrc
315 $ req
316 pushing to http://localhost:$HGPORT/
317 searching for changes
318 abort: authorization failed
319 % serve errors
320 [255]
321
322 expect authorization error: some users denied, users must be authenticated
323
324 $ echo 'deny_push = unperson' >> .hg/hgrc
325 $ req
326 pushing to http://localhost:$HGPORT/
327 searching for changes
328 abort: authorization failed
329 % serve errors
330 [255]
331
332 #if bundle2
310 #if bundle2
333
311
334 $ cat > .hg/hgrc <<EOF
312 $ cat > .hg/hgrc <<EOF
@@ -114,6 +114,8 b" def addgroupcopy(rlog, tr, destname=b'_d"
114 else:
114 else:
115 # suboptimal deltaparent
115 # suboptimal deltaparent
116 deltaparent = min(0, parentrev)
116 deltaparent = min(0, parentrev)
117 if not rlog.candelta(deltaparent, r):
118 deltaparent = -1
117 return {'node': rlog.node(r), 'p1': pnode, 'p2': node.nullid,
119 return {'node': rlog.node(r), 'p1': pnode, 'p2': node.nullid,
118 'cs': rlog.node(rlog.linkrev(r)), 'flags': rlog.flags(r),
120 'cs': rlog.node(rlog.linkrev(r)), 'flags': rlog.flags(r),
119 'deltabase': rlog.node(deltaparent),
121 'deltabase': rlog.node(deltaparent),
@@ -151,12 +153,14 b" def lowlevelcopy(rlog, tr, destname=b'_d"
151 for r in rlog:
153 for r in rlog:
152 p1 = rlog.node(r - 1)
154 p1 = rlog.node(r - 1)
153 p2 = node.nullid
155 p2 = node.nullid
154 if r == 0:
156 if r == 0 or (rlog.flags(r) & revlog.REVIDX_EXTSTORED):
155 text = rlog.revision(r, raw=True)
157 text = rlog.revision(r, raw=True)
156 cachedelta = None
158 cachedelta = None
157 else:
159 else:
158 # deltaparent is more interesting if it has the EXTSTORED flag.
160 # deltaparent cannot have EXTSTORED flag.
159 deltaparent = max([0] + [p for p in range(r - 2) if rlog.flags(p)])
161 deltaparent = max([-1] +
162 [p for p in range(r)
163 if rlog.flags(p) & revlog.REVIDX_EXTSTORED == 0])
160 text = None
164 text = None
161 cachedelta = (deltaparent, rlog.revdiff(deltaparent, r))
165 cachedelta = (deltaparent, rlog.revdiff(deltaparent, r))
162 flags = rlog.flags(r)
166 flags = rlog.flags(r)
@@ -262,8 +266,9 b' def writecases(rlog, tr):'
262 result.append((text, rawtext))
266 result.append((text, rawtext))
263
267
264 # Verify flags like isdelta, isext work as expected
268 # Verify flags like isdelta, isext work as expected
265 if bool(rlog.deltaparent(rev) > -1) != isdelta:
269 # isdelta can be overridden to False if this or p1 has isext set
266 abort('rev %d: isdelta is ineffective' % rev)
270 if bool(rlog.deltaparent(rev) > -1) and not isdelta:
271 abort('rev %d: isdelta is unexpected' % rev)
267 if bool(rlog.flags(rev)) != isext:
272 if bool(rlog.flags(rev)) != isext:
268 abort('rev %d: isext is ineffective' % rev)
273 abort('rev %d: isext is ineffective' % rev)
269 return result
274 return result
General Comments 0
You need to be logged in to leave comments. Login now