Show More
@@ -14,6 +14,7 b' import errno' | |||||
14 | import operator |
|
14 | import operator | |
15 | import os |
|
15 | import os | |
16 | import random |
|
16 | import random | |
|
17 | import re | |||
17 | import socket |
|
18 | import socket | |
18 | import ssl |
|
19 | import ssl | |
19 | import stat |
|
20 | import stat | |
@@ -2692,6 +2693,24 b' def debugwireproto(ui, repo, path=None, ' | |||||
2692 |
|
2693 | |||
2693 | This action MUST be paired with a ``batchbegin`` action. |
|
2694 | This action MUST be paired with a ``batchbegin`` action. | |
2694 |
|
2695 | |||
|
2696 | httprequest <method> <path> | |||
|
2697 | --------------------------- | |||
|
2698 | ||||
|
2699 | (HTTP peer only) | |||
|
2700 | ||||
|
2701 | Send an HTTP request to the peer. | |||
|
2702 | ||||
|
2703 | The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``. | |||
|
2704 | ||||
|
2705 | Arguments of the form ``<key>: <value>`` are interpreted as HTTP request | |||
|
2706 | headers to add to the request. e.g. ``Accept: foo``. | |||
|
2707 | ||||
|
2708 | The following arguments are special: | |||
|
2709 | ||||
|
2710 | ``BODYFILE`` | |||
|
2711 | The content of the file defined as the value to this argument will be | |||
|
2712 | transferred verbatim as the HTTP request body. | |||
|
2713 | ||||
2695 | close |
|
2714 | close | |
2696 | ----- |
|
2715 | ----- | |
2697 |
|
2716 | |||
@@ -2754,6 +2773,7 b' def debugwireproto(ui, repo, path=None, ' | |||||
2754 | stdin = None |
|
2773 | stdin = None | |
2755 | stdout = None |
|
2774 | stdout = None | |
2756 | stderr = None |
|
2775 | stderr = None | |
|
2776 | opener = None | |||
2757 |
|
2777 | |||
2758 | if opts['localssh']: |
|
2778 | if opts['localssh']: | |
2759 | # We start the SSH server in its own process so there is process |
|
2779 | # We start the SSH server in its own process so there is process | |
@@ -2909,6 +2929,42 b' def debugwireproto(ui, repo, path=None, ' | |||||
2909 | ui.status(_('response #%d: %s\n') % (i, util.escapedata(chunk))) |
|
2929 | ui.status(_('response #%d: %s\n') % (i, util.escapedata(chunk))) | |
2910 |
|
2930 | |||
2911 | batchedcommands = None |
|
2931 | batchedcommands = None | |
|
2932 | ||||
|
2933 | elif action.startswith('httprequest '): | |||
|
2934 | if not opener: | |||
|
2935 | raise error.Abort(_('cannot use httprequest without an HTTP ' | |||
|
2936 | 'peer')) | |||
|
2937 | ||||
|
2938 | request = action.split(' ', 2) | |||
|
2939 | if len(request) != 3: | |||
|
2940 | raise error.Abort(_('invalid httprequest: expected format is ' | |||
|
2941 | '"httprequest <method> <path>')) | |||
|
2942 | ||||
|
2943 | method, httppath = request[1:] | |||
|
2944 | headers = {} | |||
|
2945 | body = None | |||
|
2946 | for line in lines: | |||
|
2947 | line = line.lstrip() | |||
|
2948 | m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line) | |||
|
2949 | if m: | |||
|
2950 | headers[m.group(1)] = m.group(2) | |||
|
2951 | continue | |||
|
2952 | ||||
|
2953 | if line.startswith(b'BODYFILE '): | |||
|
2954 | with open(line.split(b' ', 1), 'rb') as fh: | |||
|
2955 | body = fh.read() | |||
|
2956 | else: | |||
|
2957 | raise error.Abort(_('unknown argument to httprequest: %s') % | |||
|
2958 | line) | |||
|
2959 | ||||
|
2960 | url = path + httppath | |||
|
2961 | req = urlmod.urlreq.request(pycompat.strurl(url), body, headers) | |||
|
2962 | ||||
|
2963 | try: | |||
|
2964 | opener.open(req).read() | |||
|
2965 | except util.urlerr.urlerror as e: | |||
|
2966 | e.read() | |||
|
2967 | ||||
2912 | elif action == 'close': |
|
2968 | elif action == 'close': | |
2913 | peer.close() |
|
2969 | peer.close() | |
2914 | elif action == 'readavailable': |
|
2970 | elif action == 'readavailable': |
@@ -226,4 +226,39 b' Test listkeys for listing namespaces' | |||||
226 | s> phases |
|
226 | s> phases | |
227 | response: bookmarks \nnamespaces \nphases |
|
227 | response: bookmarks \nnamespaces \nphases | |
228 |
|
228 | |||
|
229 | Same thing, but with "httprequest" command | |||
|
230 | ||||
|
231 | $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF | |||
|
232 | > httprequest GET ?cmd=listkeys | |||
|
233 | > accept: application/mercurial-0.1 | |||
|
234 | > user-agent: mercurial/proto-1.0 (Mercurial 42) | |||
|
235 | > x-hgarg-1: namespace=namespaces | |||
|
236 | > EOF | |||
|
237 | using raw connection to peer | |||
|
238 | s> sendall(*, 0): (glob) | |||
|
239 | s> GET /?cmd=listkeys HTTP/1.1\r\n | |||
|
240 | s> Accept-Encoding: identity\r\n | |||
|
241 | s> accept: application/mercurial-0.1\r\n | |||
|
242 | s> user-agent: mercurial/proto-1.0 (Mercurial 42)\r\n (glob) | |||
|
243 | s> x-hgarg-1: namespace=namespaces\r\n | |||
|
244 | s> host: $LOCALIP:$HGPORT\r\n (glob) | |||
|
245 | s> \r\n | |||
|
246 | s> makefile('rb', None) | |||
|
247 | s> readline() -> 36: | |||
|
248 | s> HTTP/1.1 200 Script output follows\r\n | |||
|
249 | s> readline() -> 28: | |||
|
250 | s> Server: testing stub value\r\n | |||
|
251 | s> readline() -> *: (glob) | |||
|
252 | s> Date: $HTTP_DATE$\r\n | |||
|
253 | s> readline() -> 41: | |||
|
254 | s> Content-Type: application/mercurial-0.1\r\n | |||
|
255 | s> readline() -> 20: | |||
|
256 | s> Content-Length: 30\r\n | |||
|
257 | s> readline() -> 2: | |||
|
258 | s> \r\n | |||
|
259 | s> read(30) -> 30: | |||
|
260 | s> bookmarks \n | |||
|
261 | s> namespaces \n | |||
|
262 | s> phases | |||
|
263 | ||||
229 | $ killdaemons.py |
|
264 | $ killdaemons.py |
General Comments 0
You need to be logged in to leave comments.
Login now