Show More
@@ -48,6 +48,7 b' from . import (' | |||
|
48 | 48 | fileset, |
|
49 | 49 | formatter, |
|
50 | 50 | hg, |
|
51 | httppeer, | |
|
51 | 52 | localrepo, |
|
52 | 53 | lock as lockmod, |
|
53 | 54 | logcmdutil, |
@@ -2602,9 +2603,9 b' def _parsewirelangblocks(fh):' | |||
|
2602 | 2603 | ('', 'peer', '', _('construct a specific version of the peer')), |
|
2603 | 2604 | ('', 'noreadstderr', False, _('do not read from stderr of the remote')), |
|
2604 | 2605 | ] + cmdutil.remoteopts, |
|
2605 |
_('[ |
|
|
2606 | _('[PATH]'), | |
|
2606 | 2607 | optionalrepo=True) |
|
2607 | def debugwireproto(ui, repo, **opts): | |
|
2608 | def debugwireproto(ui, repo, path=None, **opts): | |
|
2608 | 2609 | """send wire protocol commands to a server |
|
2609 | 2610 | |
|
2610 | 2611 | This command can be used to issue wire protocol commands to remote |
@@ -2740,12 +2741,19 b' def debugwireproto(ui, repo, **opts):' | |||
|
2740 | 2741 | raise error.Abort(_('invalid value for --peer'), |
|
2741 | 2742 | hint=_('valid values are "raw", "ssh1", and "ssh2"')) |
|
2742 | 2743 | |
|
2744 | if path and opts['localssh']: | |
|
2745 | raise error.Abort(_('cannot specify --localssh with an explicit ' | |
|
2746 | 'path')) | |
|
2747 | ||
|
2743 | 2748 | if ui.interactive(): |
|
2744 | 2749 | ui.write(_('(waiting for commands on stdin)\n')) |
|
2745 | 2750 | |
|
2746 | 2751 | blocks = list(_parsewirelangblocks(ui.fin)) |
|
2747 | 2752 | |
|
2748 | 2753 | proc = None |
|
2754 | stdin = None | |
|
2755 | stdout = None | |
|
2756 | stderr = None | |
|
2749 | 2757 | |
|
2750 | 2758 | if opts['localssh']: |
|
2751 | 2759 | # We start the SSH server in its own process so there is process |
@@ -2793,14 +2801,51 b' def debugwireproto(ui, repo, **opts):' | |||
|
2793 | 2801 | peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr, |
|
2794 | 2802 | autoreadstderr=autoreadstderr) |
|
2795 | 2803 | |
|
2804 | elif path: | |
|
2805 | # We bypass hg.peer() so we can proxy the sockets. | |
|
2806 | # TODO consider not doing this because we skip | |
|
2807 | # ``hg.wirepeersetupfuncs`` and potentially other useful functionality. | |
|
2808 | u = util.url(path) | |
|
2809 | if u.scheme != 'http': | |
|
2810 | raise error.Abort(_('only http:// paths are currently supported')) | |
|
2811 | ||
|
2812 | url, authinfo = u.authinfo() | |
|
2813 | openerargs = {} | |
|
2814 | ||
|
2815 | # Turn pipes/sockets into observers so we can log I/O. | |
|
2816 | if ui.verbose: | |
|
2817 | openerargs = { | |
|
2818 | r'loggingfh': ui, | |
|
2819 | r'loggingname': b's', | |
|
2820 | r'loggingopts': { | |
|
2821 | r'logdata': True, | |
|
2822 | }, | |
|
2823 | } | |
|
2824 | ||
|
2825 | opener = urlmod.opener(ui, authinfo, **openerargs) | |
|
2826 | ||
|
2827 | if opts['peer'] == 'raw': | |
|
2828 | ui.write(_('using raw connection to peer\n')) | |
|
2829 | peer = None | |
|
2830 | elif opts['peer']: | |
|
2831 | raise error.Abort(_('--peer %s not supported with HTTP peers') % | |
|
2832 | opts['peer']) | |
|
2833 | else: | |
|
2834 | peer = httppeer.httppeer(ui, path, url, opener) | |
|
2835 | peer._fetchcaps() | |
|
2836 | ||
|
2837 | # We /could/ populate stdin/stdout with sock.makefile()... | |
|
2796 | 2838 | else: |
|
2797 |
raise error.Abort(_(' |
|
|
2839 | raise error.Abort(_('unsupported connection configuration')) | |
|
2798 | 2840 | |
|
2799 | 2841 | batchedcommands = None |
|
2800 | 2842 | |
|
2801 | 2843 | # Now perform actions based on the parsed wire language instructions. |
|
2802 | 2844 | for action, lines in blocks: |
|
2803 | 2845 | if action in ('raw', 'raw+'): |
|
2846 | if not stdin: | |
|
2847 | raise error.Abort(_('cannot call raw/raw+ on this peer')) | |
|
2848 | ||
|
2804 | 2849 | # Concatenate the data together. |
|
2805 | 2850 | data = ''.join(l.lstrip() for l in lines) |
|
2806 | 2851 | data = util.unescapestr(data) |
@@ -2809,6 +2854,8 b' def debugwireproto(ui, repo, **opts):' | |||
|
2809 | 2854 | if action == 'raw+': |
|
2810 | 2855 | stdin.flush() |
|
2811 | 2856 | elif action == 'flush': |
|
2857 | if not stdin: | |
|
2858 | raise error.Abort(_('cannot call flush on this peer')) | |
|
2812 | 2859 | stdin.flush() |
|
2813 | 2860 | elif action.startswith('command'): |
|
2814 | 2861 | if not peer: |
@@ -2865,18 +2912,30 b' def debugwireproto(ui, repo, **opts):' | |||
|
2865 | 2912 | elif action == 'close': |
|
2866 | 2913 | peer.close() |
|
2867 | 2914 | elif action == 'readavailable': |
|
2915 | if not stdout or not stderr: | |
|
2916 | raise error.Abort(_('readavailable not available on this peer')) | |
|
2917 | ||
|
2868 | 2918 | stdin.close() |
|
2869 | 2919 | stdout.read() |
|
2870 | 2920 | stderr.read() |
|
2921 | ||
|
2871 | 2922 | elif action == 'readline': |
|
2923 | if not stdout: | |
|
2924 | raise error.Abort(_('readline not available on this peer')) | |
|
2872 | 2925 | stdout.readline() |
|
2873 | 2926 | elif action == 'ereadline': |
|
2927 | if not stderr: | |
|
2928 | raise error.Abort(_('ereadline not available on this peer')) | |
|
2874 | 2929 | stderr.readline() |
|
2875 | 2930 | elif action.startswith('read '): |
|
2876 | 2931 | count = int(action.split(' ', 1)[1]) |
|
2932 | if not stdout: | |
|
2933 | raise error.Abort(_('read not available on this peer')) | |
|
2877 | 2934 | stdout.read(count) |
|
2878 | 2935 | elif action.startswith('eread '): |
|
2879 | 2936 | count = int(action.split(' ', 1)[1]) |
|
2937 | if not stderr: | |
|
2938 | raise error.Abort(_('eread not available on this peer')) | |
|
2880 | 2939 | stderr.read(count) |
|
2881 | 2940 | else: |
|
2882 | 2941 | raise error.Abort(_('unknown action: %s') % action) |
@@ -161,3 +161,69 b' Client receives only supported format ev' | |||
|
161 | 161 | 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu| |
|
162 | 162 | 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib| |
|
163 | 163 | 0020: 78 |x| |
|
164 | ||
|
165 | $ killdaemons.py | |
|
166 | $ cd .. | |
|
167 | ||
|
168 | Test listkeys for listing namespaces | |
|
169 | ||
|
170 | $ hg init empty | |
|
171 | $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid | |
|
172 | $ cat hg.pid > $DAEMON_PIDS | |
|
173 | ||
|
174 | $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF | |
|
175 | > command listkeys | |
|
176 | > namespace namespaces | |
|
177 | > EOF | |
|
178 | s> sendall(*, 0): (glob) | |
|
179 | s> GET /?cmd=capabilities HTTP/1.1\r\n | |
|
180 | s> Accept-Encoding: identity\r\n | |
|
181 | s> accept: application/mercurial-0.1\r\n | |
|
182 | s> host: $LOCALIP:$HGPORT\r\n (glob) | |
|
183 | s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) | |
|
184 | s> \r\n | |
|
185 | s> makefile('rb', None) | |
|
186 | s> readline() -> 36: | |
|
187 | s> HTTP/1.1 200 Script output follows\r\n | |
|
188 | s> readline() -> 28: | |
|
189 | s> Server: testing stub value\r\n | |
|
190 | s> readline() -> *: (glob) | |
|
191 | s> Date: $HTTP_DATE$\r\n | |
|
192 | s> readline() -> 41: | |
|
193 | s> Content-Type: application/mercurial-0.1\r\n | |
|
194 | s> readline() -> 21: | |
|
195 | s> Content-Length: *\r\n (glob) | |
|
196 | s> readline() -> 2: | |
|
197 | s> \r\n | |
|
198 | s> read(*) -> *: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (glob) | |
|
199 | sending listkeys command | |
|
200 | s> sendall(*, 0): (glob) | |
|
201 | s> GET /?cmd=listkeys HTTP/1.1\r\n | |
|
202 | s> Accept-Encoding: identity\r\n | |
|
203 | s> vary: X-HgArg-1,X-HgProto-1\r\n | |
|
204 | s> x-hgarg-1: namespace=namespaces\r\n | |
|
205 | s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$\r\n | |
|
206 | s> accept: application/mercurial-0.1\r\n | |
|
207 | s> host: $LOCALIP:$HGPORT\r\n (glob) | |
|
208 | s> user-agent: mercurial/proto-1.0 (Mercurial *)\r\n (glob) | |
|
209 | s> \r\n | |
|
210 | s> makefile('rb', None) | |
|
211 | s> readline() -> 36: | |
|
212 | s> HTTP/1.1 200 Script output follows\r\n | |
|
213 | s> readline() -> 28: | |
|
214 | s> Server: testing stub value\r\n | |
|
215 | s> readline() -> *: (glob) | |
|
216 | s> Date: $HTTP_DATE$\r\n | |
|
217 | s> readline() -> 41: | |
|
218 | s> Content-Type: application/mercurial-0.1\r\n | |
|
219 | s> readline() -> 20: | |
|
220 | s> Content-Length: 30\r\n | |
|
221 | s> readline() -> 2: | |
|
222 | s> \r\n | |
|
223 | s> read(30) -> 30: | |
|
224 | s> bookmarks \n | |
|
225 | s> namespaces \n | |
|
226 | s> phases | |
|
227 | response: bookmarks \nnamespaces \nphases | |
|
228 | ||
|
229 | $ killdaemons.py |
General Comments 0
You need to be logged in to leave comments.
Login now