Show More
@@ -1658,6 +1658,10 b' Controls generic server settings.' | |||||
1658 | the write lock while determining what data to transfer. |
|
1658 | the write lock while determining what data to transfer. | |
1659 | (default: True) |
|
1659 | (default: True) | |
1660 |
|
1660 | |||
|
1661 | ``uncompressedallowsecret`` | |||
|
1662 | Whether to allow stream clones when the repository contains secret | |||
|
1663 | changesets. (default: False) | |||
|
1664 | ||||
1661 | ``preferuncompressed`` |
|
1665 | ``preferuncompressed`` | |
1662 | When set, clients will try to use the uncompressed streaming |
|
1666 | When set, clients will try to use the uncompressed streaming | |
1663 | protocol. (default: False) |
|
1667 | protocol. (default: False) |
@@ -13,6 +13,7 b' from .i18n import _' | |||||
13 | from . import ( |
|
13 | from . import ( | |
14 | branchmap, |
|
14 | branchmap, | |
15 | error, |
|
15 | error, | |
|
16 | phases, | |||
16 | store, |
|
17 | store, | |
17 | util, |
|
18 | util, | |
18 | ) |
|
19 | ) | |
@@ -162,9 +163,18 b' def maybeperformlegacystreamclone(pullop' | |||||
162 |
|
163 | |||
163 | repo.invalidate() |
|
164 | repo.invalidate() | |
164 |
|
165 | |||
165 |
def allowservergeneration( |
|
166 | def allowservergeneration(repo): | |
166 | """Whether streaming clones are allowed from the server.""" |
|
167 | """Whether streaming clones are allowed from the server.""" | |
167 |
|
|
168 | if not repo.ui.configbool('server', 'uncompressed', True, untrusted=True): | |
|
169 | return False | |||
|
170 | ||||
|
171 | # The way stream clone works makes it impossible to hide secret changesets. | |||
|
172 | # So don't allow this by default. | |||
|
173 | secret = phases.hassecret(repo) | |||
|
174 | if secret: | |||
|
175 | return repo.ui.configbool('server', 'uncompressedallowsecret', False) | |||
|
176 | ||||
|
177 | return True | |||
168 |
|
178 | |||
169 | # This is it's own function so extensions can override it. |
|
179 | # This is it's own function so extensions can override it. | |
170 | def _walkstreamfiles(repo): |
|
180 | def _walkstreamfiles(repo): |
@@ -754,7 +754,7 b' def _capabilities(repo, proto):' | |||||
754 | """ |
|
754 | """ | |
755 | # copy to prevent modification of the global list |
|
755 | # copy to prevent modification of the global list | |
756 | caps = list(wireprotocaps) |
|
756 | caps = list(wireprotocaps) | |
757 |
if streamclone.allowservergeneration(repo |
|
757 | if streamclone.allowservergeneration(repo): | |
758 | if repo.ui.configbool('server', 'preferuncompressed', False): |
|
758 | if repo.ui.configbool('server', 'preferuncompressed', False): | |
759 | caps.append('stream-preferred') |
|
759 | caps.append('stream-preferred') | |
760 | requiredformats = repo.requirements & repo.supportedformats |
|
760 | requiredformats = repo.requirements & repo.supportedformats | |
@@ -946,7 +946,7 b' def stream(repo, proto):' | |||||
946 | capability with a value representing the version and flags of the repo |
|
946 | capability with a value representing the version and flags of the repo | |
947 | it is serving. Client checks to see if it understands the format. |
|
947 | it is serving. Client checks to see if it understands the format. | |
948 | ''' |
|
948 | ''' | |
949 |
if not streamclone.allowservergeneration(repo |
|
949 | if not streamclone.allowservergeneration(repo): | |
950 | return '1\n' |
|
950 | return '1\n' | |
951 |
|
951 | |||
952 | def getstream(it): |
|
952 | def getstream(it): |
@@ -49,6 +49,77 b' Clone with background file closing enabl' | |||||
49 | bundle2-input-bundle: 1 parts total |
|
49 | bundle2-input-bundle: 1 parts total | |
50 | checking for updated bookmarks |
|
50 | checking for updated bookmarks | |
51 |
|
51 | |||
|
52 | Cannot stream clone when there are secret changesets | |||
|
53 | ||||
|
54 | $ hg -R server phase --force --secret -r tip | |||
|
55 | $ hg clone --uncompressed -U http://localhost:$HGPORT secret-denied | |||
|
56 | warning: stream clone requested but server has them disabled | |||
|
57 | requesting all changes | |||
|
58 | adding changesets | |||
|
59 | adding manifests | |||
|
60 | adding file changes | |||
|
61 | added 1 changesets with 1 changes to 1 files | |||
|
62 | ||||
|
63 | $ killdaemons.py | |||
|
64 | ||||
|
65 | Streaming of secrets can be overridden by server config | |||
|
66 | ||||
|
67 | $ cd server | |||
|
68 | $ hg --config server.uncompressedallowsecret=true serve -p $HGPORT -d --pid-file=hg.pid | |||
|
69 | $ cat hg.pid > $DAEMON_PIDS | |||
|
70 | $ cd .. | |||
|
71 | ||||
|
72 | $ hg clone --uncompressed -U http://localhost:$HGPORT secret-allowed | |||
|
73 | streaming all changes | |||
|
74 | 1027 files to transfer, 96.3 KB of data | |||
|
75 | transferred 96.3 KB in * seconds (*/sec) (glob) | |||
|
76 | searching for changes | |||
|
77 | no changes found | |||
|
78 | ||||
|
79 | $ killdaemons.py | |||
|
80 | ||||
|
81 | Verify interaction between preferuncompressed and secret presence | |||
|
82 | ||||
|
83 | $ cd server | |||
|
84 | $ hg --config server.preferuncompressed=true serve -p $HGPORT -d --pid-file=hg.pid | |||
|
85 | $ cat hg.pid > $DAEMON_PIDS | |||
|
86 | $ cd .. | |||
|
87 | ||||
|
88 | $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret | |||
|
89 | requesting all changes | |||
|
90 | adding changesets | |||
|
91 | adding manifests | |||
|
92 | adding file changes | |||
|
93 | added 1 changesets with 1 changes to 1 files | |||
|
94 | ||||
|
95 | $ killdaemons.py | |||
|
96 | ||||
|
97 | Clone not allowed when full bundles disabled and can't serve secrets | |||
|
98 | ||||
|
99 | $ cd server | |||
|
100 | $ hg --config server.disablefullbundle=true serve -p $HGPORT -d --pid-file=hg.pid | |||
|
101 | $ cat hg.pid > $DAEMON_PIDS | |||
|
102 | $ cd .. | |||
|
103 | ||||
|
104 | $ hg clone --uncompressed http://localhost:$HGPORT secret-full-disabled | |||
|
105 | warning: stream clone requested but server has them disabled | |||
|
106 | requesting all changes | |||
|
107 | remote: abort: server has pull-based clones disabled | |||
|
108 | abort: pull failed on remote | |||
|
109 | (remove --pull if specified or upgrade Mercurial) | |||
|
110 | [255] | |||
|
111 | ||||
|
112 | Local stream clone with secrets involved | |||
|
113 | (This is just a test over behavior: if you have access to the repo's files, | |||
|
114 | there is no security so it isn't important to prevent a clone here.) | |||
|
115 | ||||
|
116 | $ hg clone -U --uncompressed server local-secret | |||
|
117 | warning: stream clone requested but server has them disabled | |||
|
118 | requesting all changes | |||
|
119 | adding changesets | |||
|
120 | adding manifests | |||
|
121 | adding file changes | |||
|
122 | added 1 changesets with 1 changes to 1 files | |||
52 |
|
123 | |||
53 | Stream clone while repo is changing: |
|
124 | Stream clone while repo is changing: | |
54 |
|
125 |
General Comments 0
You need to be logged in to leave comments.
Login now