Show More
@@ -48,6 +48,7 b' from . import (' | |||||
48 | fileset, |
|
48 | fileset, | |
49 | formatter, |
|
49 | formatter, | |
50 | hg, |
|
50 | hg, | |
|
51 | httppeer, | |||
51 | localrepo, |
|
52 | localrepo, | |
52 | lock as lockmod, |
|
53 | lock as lockmod, | |
53 | logcmdutil, |
|
54 | logcmdutil, | |
@@ -2602,9 +2603,9 b' def _parsewirelangblocks(fh):' | |||||
2602 | ('', 'peer', '', _('construct a specific version of the peer')), |
|
2603 | ('', 'peer', '', _('construct a specific version of the peer')), | |
2603 | ('', 'noreadstderr', False, _('do not read from stderr of the remote')), |
|
2604 | ('', 'noreadstderr', False, _('do not read from stderr of the remote')), | |
2604 | ] + cmdutil.remoteopts, |
|
2605 | ] + cmdutil.remoteopts, | |
2605 |
_('[ |
|
2606 | _('[PATH]'), | |
2606 | optionalrepo=True) |
|
2607 | optionalrepo=True) | |
2607 | def debugwireproto(ui, repo, **opts): |
|
2608 | def debugwireproto(ui, repo, path=None, **opts): | |
2608 | """send wire protocol commands to a server |
|
2609 | """send wire protocol commands to a server | |
2609 |
|
2610 | |||
2610 | This command can be used to issue wire protocol commands to remote |
|
2611 | This command can be used to issue wire protocol commands to remote | |
@@ -2740,12 +2741,19 b' def debugwireproto(ui, repo, **opts):' | |||||
2740 | raise error.Abort(_('invalid value for --peer'), |
|
2741 | raise error.Abort(_('invalid value for --peer'), | |
2741 | hint=_('valid values are "raw", "ssh1", and "ssh2"')) |
|
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 | if ui.interactive(): |
|
2748 | if ui.interactive(): | |
2744 | ui.write(_('(waiting for commands on stdin)\n')) |
|
2749 | ui.write(_('(waiting for commands on stdin)\n')) | |
2745 |
|
2750 | |||
2746 | blocks = list(_parsewirelangblocks(ui.fin)) |
|
2751 | blocks = list(_parsewirelangblocks(ui.fin)) | |
2747 |
|
2752 | |||
2748 | proc = None |
|
2753 | proc = None | |
|
2754 | stdin = None | |||
|
2755 | stdout = None | |||
|
2756 | stderr = None | |||
2749 |
|
2757 | |||
2750 | if opts['localssh']: |
|
2758 | if opts['localssh']: | |
2751 | # We start the SSH server in its own process so there is process |
|
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 | peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr, |
|
2801 | peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr, | |
2794 | autoreadstderr=autoreadstderr) |
|
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 | else: |
|
2838 | else: | |
2797 |
raise error.Abort(_(' |
|
2839 | raise error.Abort(_('unsupported connection configuration')) | |
2798 |
|
2840 | |||
2799 | batchedcommands = None |
|
2841 | batchedcommands = None | |
2800 |
|
2842 | |||
2801 | # Now perform actions based on the parsed wire language instructions. |
|
2843 | # Now perform actions based on the parsed wire language instructions. | |
2802 | for action, lines in blocks: |
|
2844 | for action, lines in blocks: | |
2803 | if action in ('raw', 'raw+'): |
|
2845 | if action in ('raw', 'raw+'): | |
|
2846 | if not stdin: | |||
|
2847 | raise error.Abort(_('cannot call raw/raw+ on this peer')) | |||
|
2848 | ||||
2804 | # Concatenate the data together. |
|
2849 | # Concatenate the data together. | |
2805 | data = ''.join(l.lstrip() for l in lines) |
|
2850 | data = ''.join(l.lstrip() for l in lines) | |
2806 | data = util.unescapestr(data) |
|
2851 | data = util.unescapestr(data) | |
@@ -2809,6 +2854,8 b' def debugwireproto(ui, repo, **opts):' | |||||
2809 | if action == 'raw+': |
|
2854 | if action == 'raw+': | |
2810 | stdin.flush() |
|
2855 | stdin.flush() | |
2811 | elif action == 'flush': |
|
2856 | elif action == 'flush': | |
|
2857 | if not stdin: | |||
|
2858 | raise error.Abort(_('cannot call flush on this peer')) | |||
2812 | stdin.flush() |
|
2859 | stdin.flush() | |
2813 | elif action.startswith('command'): |
|
2860 | elif action.startswith('command'): | |
2814 | if not peer: |
|
2861 | if not peer: | |
@@ -2865,18 +2912,30 b' def debugwireproto(ui, repo, **opts):' | |||||
2865 | elif action == 'close': |
|
2912 | elif action == 'close': | |
2866 | peer.close() |
|
2913 | peer.close() | |
2867 | elif action == 'readavailable': |
|
2914 | elif action == 'readavailable': | |
|
2915 | if not stdout or not stderr: | |||
|
2916 | raise error.Abort(_('readavailable not available on this peer')) | |||
|
2917 | ||||
2868 | stdin.close() |
|
2918 | stdin.close() | |
2869 | stdout.read() |
|
2919 | stdout.read() | |
2870 | stderr.read() |
|
2920 | stderr.read() | |
|
2921 | ||||
2871 | elif action == 'readline': |
|
2922 | elif action == 'readline': | |
|
2923 | if not stdout: | |||
|
2924 | raise error.Abort(_('readline not available on this peer')) | |||
2872 | stdout.readline() |
|
2925 | stdout.readline() | |
2873 | elif action == 'ereadline': |
|
2926 | elif action == 'ereadline': | |
|
2927 | if not stderr: | |||
|
2928 | raise error.Abort(_('ereadline not available on this peer')) | |||
2874 | stderr.readline() |
|
2929 | stderr.readline() | |
2875 | elif action.startswith('read '): |
|
2930 | elif action.startswith('read '): | |
2876 | count = int(action.split(' ', 1)[1]) |
|
2931 | count = int(action.split(' ', 1)[1]) | |
|
2932 | if not stdout: | |||
|
2933 | raise error.Abort(_('read not available on this peer')) | |||
2877 | stdout.read(count) |
|
2934 | stdout.read(count) | |
2878 | elif action.startswith('eread '): |
|
2935 | elif action.startswith('eread '): | |
2879 | count = int(action.split(' ', 1)[1]) |
|
2936 | count = int(action.split(' ', 1)[1]) | |
|
2937 | if not stderr: | |||
|
2938 | raise error.Abort(_('eread not available on this peer')) | |||
2880 | stderr.read(count) |
|
2939 | stderr.read(count) | |
2881 | else: |
|
2940 | else: | |
2882 | raise error.Abort(_('unknown action: %s') % action) |
|
2941 | raise error.Abort(_('unknown action: %s') % action) |
@@ -161,3 +161,69 b' Client receives only supported format ev' | |||||
161 | 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu| |
|
161 | 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu| | |
162 | 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib| |
|
162 | 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib| | |
163 | 0020: 78 |x| |
|
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