Show More
@@ -1,70 +1,70 b'' | |||
|
1 | 1 | # streamclone.py - streaming clone server support for mercurial |
|
2 | 2 | # |
|
3 | 3 | # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
|
4 | 4 | # |
|
5 | 5 | # This software may be used and distributed according to the terms of the |
|
6 | 6 | # GNU General Public License version 2 or any later version. |
|
7 | 7 | |
|
8 | 8 | import util, error |
|
9 | 9 | from i18n import _ |
|
10 | 10 | |
|
11 | 11 | from mercurial import store |
|
12 | 12 | |
|
13 | 13 | class StreamException(Exception): |
|
14 | 14 | def __init__(self, code): |
|
15 | 15 | Exception.__init__(self) |
|
16 | 16 | self.code = code |
|
17 | 17 | def __str__(self): |
|
18 | 18 | return '%i\n' % self.code |
|
19 | 19 | |
|
20 | 20 | # if server supports streaming clone, it advertises "stream" |
|
21 | 21 | # capability with value that is version+flags of repo it is serving. |
|
22 | 22 | # client only streams if it can read that repo format. |
|
23 | 23 | |
|
24 | 24 | # stream file format is simple. |
|
25 | 25 | # |
|
26 | 26 | # server writes out line that says how many files, how many total |
|
27 | 27 | # bytes. separator is ascii space, byte counts are strings. |
|
28 | 28 | # |
|
29 | 29 | # then for each file: |
|
30 | 30 | # |
|
31 | 31 | # server writes out line that says filename, how many bytes in |
|
32 | 32 | # file. separator is ascii nul, byte count is string. |
|
33 | 33 | # |
|
34 | 34 | # server writes out raw file data. |
|
35 | 35 | |
|
36 | 36 | def allowed(ui): |
|
37 | return ui.configbool('server', 'uncompressed', untrusted=True) | |
|
37 | return ui.configbool('server', 'uncompressed', True, untrusted=True) | |
|
38 | 38 | |
|
39 | 39 | def stream_out(repo): |
|
40 | 40 | '''stream out all metadata files in repository. |
|
41 | 41 | writes to file-like object, must support write() and optional flush().''' |
|
42 | 42 | |
|
43 | 43 | if not allowed(repo.ui): |
|
44 | 44 | raise StreamException(1) |
|
45 | 45 | |
|
46 | 46 | entries = [] |
|
47 | 47 | total_bytes = 0 |
|
48 | 48 | try: |
|
49 | 49 | # get consistent snapshot of repo, lock during scan |
|
50 | 50 | lock = repo.lock() |
|
51 | 51 | try: |
|
52 | 52 | repo.ui.debug('scanning\n') |
|
53 | 53 | for name, ename, size in repo.store.walk(): |
|
54 | 54 | entries.append((name, size)) |
|
55 | 55 | total_bytes += size |
|
56 | 56 | finally: |
|
57 | 57 | lock.release() |
|
58 | 58 | except error.LockError: |
|
59 | 59 | raise StreamException(2) |
|
60 | 60 | |
|
61 | 61 | yield '0\n' |
|
62 | 62 | repo.ui.debug('%d files, %d bytes to transfer\n' % |
|
63 | 63 | (len(entries), total_bytes)) |
|
64 | 64 | yield '%d %d\n' % (len(entries), total_bytes) |
|
65 | 65 | for name, size in entries: |
|
66 | 66 | repo.ui.debug('sending %s (%d bytes)\n' % (name, size)) |
|
67 | 67 | # partially encode name over the wire for backwards compat |
|
68 | 68 | yield '%s\0%d\n' % (store.encodedir(name), size) |
|
69 | 69 | for chunk in util.filechunkiter(repo.sopener(name), limit=size): |
|
70 | 70 | yield chunk |
@@ -1,64 +1,64 b'' | |||
|
1 | 1 | #!/bin/sh |
|
2 | 2 | # An attempt at more fully testing the hgweb web interface. |
|
3 | 3 | # The following things are tested elsewhere and are therefore omitted: |
|
4 | 4 | # - archive, tested in test-archive |
|
5 | 5 | # - unbundle, tested in test-push-http |
|
6 | 6 | # - changegroupsubset, tested in test-pull |
|
7 | 7 | |
|
8 | 8 | echo % Set up the repo |
|
9 | 9 | hg init test |
|
10 | 10 | cd test |
|
11 | 11 | mkdir da |
|
12 | 12 | echo foo > da/foo |
|
13 | 13 | echo foo > foo |
|
14 | 14 | hg ci -Ambase |
|
15 | 15 | hg tag 1.0 |
|
16 | 16 | echo another > foo |
|
17 | 17 | hg branch stable |
|
18 | 18 | hg ci -Ambranch |
|
19 | hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log | |
|
19 | hg serve --config server.uncompressed=False -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log | |
|
20 | 20 | cat hg.pid >> $DAEMON_PIDS |
|
21 | 21 | |
|
22 | 22 | echo % Logs and changes |
|
23 | 23 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//" |
|
24 | 24 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//" |
|
25 | 25 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//" |
|
26 | 26 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/' |
|
27 | 27 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/' |
|
28 | 28 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw' |
|
29 | 29 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base' |
|
30 | 30 | |
|
31 | 31 | echo % File-related |
|
32 | 32 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw' |
|
33 | 33 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw' |
|
34 | 34 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw' |
|
35 | 35 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo' |
|
36 | 36 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw' |
|
37 | 37 | |
|
38 | 38 | echo % Overviews |
|
39 | 39 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags' |
|
40 | 40 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches' |
|
41 | 41 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb' |
|
42 | 42 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb' |
|
43 | 43 | |
|
44 | 44 | echo % capabilities |
|
45 | 45 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities' |
|
46 | 46 | echo % heads |
|
47 | 47 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads' |
|
48 | 48 | echo % lookup |
|
49 | 49 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=lookup&node=1' |
|
50 | 50 | echo % branches |
|
51 | 51 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches' |
|
52 | 52 | echo % changegroup |
|
53 | 53 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup' \ |
|
54 | 54 | | $TESTDIR/printrepr.py |
|
55 | 55 | echo % stream_out |
|
56 | 56 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out' |
|
57 | 57 | echo % failing unbundle, requires POST request |
|
58 | 58 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle' |
|
59 | 59 | |
|
60 | 60 | echo % Static files |
|
61 | 61 | "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css' |
|
62 | 62 | |
|
63 | 63 | echo % ERRORS ENCOUNTERED |
|
64 | 64 | cat errors.log |
@@ -1,43 +1,43 b'' | |||
|
1 | 1 | #!/bin/sh |
|
2 | 2 | |
|
3 | 3 | cp "$TESTDIR"/printenv.py . |
|
4 | 4 | |
|
5 | 5 | hg init test |
|
6 | 6 | cd test |
|
7 | 7 | echo foo>foo |
|
8 | 8 | mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg |
|
9 | 9 | echo foo>foo.d/foo |
|
10 | 10 | echo bar>foo.d/bAr.hg.d/BaR |
|
11 | 11 | echo bar>foo.d/baR.d.hg/bAR |
|
12 | 12 | |
|
13 | 13 | hg commit -A -m 1 |
|
14 |
hg |
|
|
15 | hg serve -p $HGPORT1 -d --pid-file=../hg2.pid | |
|
14 | hg serve -p $HGPORT -d --pid-file=../hg1.pid | |
|
15 | hg --config server.uncompressed=False serve -p $HGPORT1 -d --pid-file=../hg2.pid | |
|
16 | 16 | # Test server address cannot be reused |
|
17 | 17 | hg serve -p $HGPORT1 2>&1 | sed -e "s/abort: cannot start server at ':$HGPORT1':.*/abort: cannot start server at ':\$HGPORT1':/" |
|
18 | 18 | cd .. |
|
19 | 19 | cat hg1.pid hg2.pid >> $DAEMON_PIDS |
|
20 | 20 | |
|
21 | 21 | echo % clone via stream |
|
22 | 22 | hg clone --uncompressed http://localhost:$HGPORT/ copy 2>&1 | \ |
|
23 | 23 | sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/[KM]\(B\/sec\)/X\1/' |
|
24 | 24 | hg verify -R copy |
|
25 | 25 | |
|
26 | 26 | echo % try to clone via stream, should use pull instead |
|
27 | 27 | hg clone --uncompressed http://localhost:$HGPORT1/ copy2 |
|
28 | 28 | |
|
29 | 29 | echo % clone via pull |
|
30 | 30 | hg clone http://localhost:$HGPORT1/ copy-pull |
|
31 | 31 | hg verify -R copy-pull |
|
32 | 32 | |
|
33 | 33 | cd test |
|
34 | 34 | echo bar > bar |
|
35 | 35 | hg commit -A -d '1 0' -m 2 |
|
36 | 36 | cd .. |
|
37 | 37 | |
|
38 | 38 | echo % pull |
|
39 | 39 | cd copy-pull |
|
40 | 40 | echo '[hooks]' >> .hg/hgrc |
|
41 | 41 | echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc |
|
42 | 42 | hg pull | sed -e "s,:$HGPORT1/,:\$HGPORT1/," |
|
43 | 43 | cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now