##// END OF EJS Templates
wireprotov2: declare command arguments richly...
Gregory Szorc -
r39835:0b61d21f default
parent child Browse files
Show More
@@ -1,921 +1,1058
1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 #
3 #
4 # This software may be used and distributed according to the terms of the
4 # This software may be used and distributed according to the terms of the
5 # GNU General Public License version 2 or any later version.
5 # GNU General Public License version 2 or any later version.
6
6
7 from __future__ import absolute_import
7 from __future__ import absolute_import
8
8
9 import contextlib
9 import contextlib
10
10
11 from .i18n import _
11 from .i18n import _
12 from .node import (
12 from .node import (
13 hex,
13 hex,
14 nullid,
14 nullid,
15 nullrev,
15 nullrev,
16 )
16 )
17 from . import (
17 from . import (
18 changegroup,
18 changegroup,
19 dagop,
19 dagop,
20 discovery,
20 discovery,
21 encoding,
21 encoding,
22 error,
22 error,
23 pycompat,
23 pycompat,
24 streamclone,
24 streamclone,
25 util,
25 util,
26 wireprotoframing,
26 wireprotoframing,
27 wireprototypes,
27 wireprototypes,
28 )
28 )
29 from .utils import (
29 from .utils import (
30 interfaceutil,
30 interfaceutil,
31 )
31 )
32
32
33 FRAMINGTYPE = b'application/mercurial-exp-framing-0005'
33 FRAMINGTYPE = b'application/mercurial-exp-framing-0005'
34
34
35 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
35 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
36
36
37 COMMANDS = wireprototypes.commanddict()
37 COMMANDS = wireprototypes.commanddict()
38
38
39 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
39 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
40 from .hgweb import common as hgwebcommon
40 from .hgweb import common as hgwebcommon
41
41
42 # URL space looks like: <permissions>/<command>, where <permission> can
42 # URL space looks like: <permissions>/<command>, where <permission> can
43 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
43 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
44
44
45 # Root URL does nothing meaningful... yet.
45 # Root URL does nothing meaningful... yet.
46 if not urlparts:
46 if not urlparts:
47 res.status = b'200 OK'
47 res.status = b'200 OK'
48 res.headers[b'Content-Type'] = b'text/plain'
48 res.headers[b'Content-Type'] = b'text/plain'
49 res.setbodybytes(_('HTTP version 2 API handler'))
49 res.setbodybytes(_('HTTP version 2 API handler'))
50 return
50 return
51
51
52 if len(urlparts) == 1:
52 if len(urlparts) == 1:
53 res.status = b'404 Not Found'
53 res.status = b'404 Not Found'
54 res.headers[b'Content-Type'] = b'text/plain'
54 res.headers[b'Content-Type'] = b'text/plain'
55 res.setbodybytes(_('do not know how to process %s\n') %
55 res.setbodybytes(_('do not know how to process %s\n') %
56 req.dispatchpath)
56 req.dispatchpath)
57 return
57 return
58
58
59 permission, command = urlparts[0:2]
59 permission, command = urlparts[0:2]
60
60
61 if permission not in (b'ro', b'rw'):
61 if permission not in (b'ro', b'rw'):
62 res.status = b'404 Not Found'
62 res.status = b'404 Not Found'
63 res.headers[b'Content-Type'] = b'text/plain'
63 res.headers[b'Content-Type'] = b'text/plain'
64 res.setbodybytes(_('unknown permission: %s') % permission)
64 res.setbodybytes(_('unknown permission: %s') % permission)
65 return
65 return
66
66
67 if req.method != 'POST':
67 if req.method != 'POST':
68 res.status = b'405 Method Not Allowed'
68 res.status = b'405 Method Not Allowed'
69 res.headers[b'Allow'] = b'POST'
69 res.headers[b'Allow'] = b'POST'
70 res.setbodybytes(_('commands require POST requests'))
70 res.setbodybytes(_('commands require POST requests'))
71 return
71 return
72
72
73 # At some point we'll want to use our own API instead of recycling the
73 # At some point we'll want to use our own API instead of recycling the
74 # behavior of version 1 of the wire protocol...
74 # behavior of version 1 of the wire protocol...
75 # TODO return reasonable responses - not responses that overload the
75 # TODO return reasonable responses - not responses that overload the
76 # HTTP status line message for error reporting.
76 # HTTP status line message for error reporting.
77 try:
77 try:
78 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
78 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
79 except hgwebcommon.ErrorResponse as e:
79 except hgwebcommon.ErrorResponse as e:
80 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
80 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
81 for k, v in e.headers:
81 for k, v in e.headers:
82 res.headers[k] = v
82 res.headers[k] = v
83 res.setbodybytes('permission denied')
83 res.setbodybytes('permission denied')
84 return
84 return
85
85
86 # We have a special endpoint to reflect the request back at the client.
86 # We have a special endpoint to reflect the request back at the client.
87 if command == b'debugreflect':
87 if command == b'debugreflect':
88 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
88 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
89 return
89 return
90
90
91 # Extra commands that we handle that aren't really wire protocol
91 # Extra commands that we handle that aren't really wire protocol
92 # commands. Think extra hard before making this hackery available to
92 # commands. Think extra hard before making this hackery available to
93 # extension.
93 # extension.
94 extracommands = {'multirequest'}
94 extracommands = {'multirequest'}
95
95
96 if command not in COMMANDS and command not in extracommands:
96 if command not in COMMANDS and command not in extracommands:
97 res.status = b'404 Not Found'
97 res.status = b'404 Not Found'
98 res.headers[b'Content-Type'] = b'text/plain'
98 res.headers[b'Content-Type'] = b'text/plain'
99 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
99 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
100 return
100 return
101
101
102 repo = rctx.repo
102 repo = rctx.repo
103 ui = repo.ui
103 ui = repo.ui
104
104
105 proto = httpv2protocolhandler(req, ui)
105 proto = httpv2protocolhandler(req, ui)
106
106
107 if (not COMMANDS.commandavailable(command, proto)
107 if (not COMMANDS.commandavailable(command, proto)
108 and command not in extracommands):
108 and command not in extracommands):
109 res.status = b'404 Not Found'
109 res.status = b'404 Not Found'
110 res.headers[b'Content-Type'] = b'text/plain'
110 res.headers[b'Content-Type'] = b'text/plain'
111 res.setbodybytes(_('invalid wire protocol command: %s') % command)
111 res.setbodybytes(_('invalid wire protocol command: %s') % command)
112 return
112 return
113
113
114 # TODO consider cases where proxies may add additional Accept headers.
114 # TODO consider cases where proxies may add additional Accept headers.
115 if req.headers.get(b'Accept') != FRAMINGTYPE:
115 if req.headers.get(b'Accept') != FRAMINGTYPE:
116 res.status = b'406 Not Acceptable'
116 res.status = b'406 Not Acceptable'
117 res.headers[b'Content-Type'] = b'text/plain'
117 res.headers[b'Content-Type'] = b'text/plain'
118 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
118 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
119 % FRAMINGTYPE)
119 % FRAMINGTYPE)
120 return
120 return
121
121
122 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
122 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
123 res.status = b'415 Unsupported Media Type'
123 res.status = b'415 Unsupported Media Type'
124 # TODO we should send a response with appropriate media type,
124 # TODO we should send a response with appropriate media type,
125 # since client does Accept it.
125 # since client does Accept it.
126 res.headers[b'Content-Type'] = b'text/plain'
126 res.headers[b'Content-Type'] = b'text/plain'
127 res.setbodybytes(_('client MUST send Content-Type header with '
127 res.setbodybytes(_('client MUST send Content-Type header with '
128 'value: %s\n') % FRAMINGTYPE)
128 'value: %s\n') % FRAMINGTYPE)
129 return
129 return
130
130
131 _processhttpv2request(ui, repo, req, res, permission, command, proto)
131 _processhttpv2request(ui, repo, req, res, permission, command, proto)
132
132
133 def _processhttpv2reflectrequest(ui, repo, req, res):
133 def _processhttpv2reflectrequest(ui, repo, req, res):
134 """Reads unified frame protocol request and dumps out state to client.
134 """Reads unified frame protocol request and dumps out state to client.
135
135
136 This special endpoint can be used to help debug the wire protocol.
136 This special endpoint can be used to help debug the wire protocol.
137
137
138 Instead of routing the request through the normal dispatch mechanism,
138 Instead of routing the request through the normal dispatch mechanism,
139 we instead read all frames, decode them, and feed them into our state
139 we instead read all frames, decode them, and feed them into our state
140 tracker. We then dump the log of all that activity back out to the
140 tracker. We then dump the log of all that activity back out to the
141 client.
141 client.
142 """
142 """
143 import json
143 import json
144
144
145 # Reflection APIs have a history of being abused, accidentally disclosing
145 # Reflection APIs have a history of being abused, accidentally disclosing
146 # sensitive data, etc. So we have a config knob.
146 # sensitive data, etc. So we have a config knob.
147 if not ui.configbool('experimental', 'web.api.debugreflect'):
147 if not ui.configbool('experimental', 'web.api.debugreflect'):
148 res.status = b'404 Not Found'
148 res.status = b'404 Not Found'
149 res.headers[b'Content-Type'] = b'text/plain'
149 res.headers[b'Content-Type'] = b'text/plain'
150 res.setbodybytes(_('debugreflect service not available'))
150 res.setbodybytes(_('debugreflect service not available'))
151 return
151 return
152
152
153 # We assume we have a unified framing protocol request body.
153 # We assume we have a unified framing protocol request body.
154
154
155 reactor = wireprotoframing.serverreactor()
155 reactor = wireprotoframing.serverreactor()
156 states = []
156 states = []
157
157
158 while True:
158 while True:
159 frame = wireprotoframing.readframe(req.bodyfh)
159 frame = wireprotoframing.readframe(req.bodyfh)
160
160
161 if not frame:
161 if not frame:
162 states.append(b'received: <no frame>')
162 states.append(b'received: <no frame>')
163 break
163 break
164
164
165 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
165 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
166 frame.requestid,
166 frame.requestid,
167 frame.payload))
167 frame.payload))
168
168
169 action, meta = reactor.onframerecv(frame)
169 action, meta = reactor.onframerecv(frame)
170 states.append(json.dumps((action, meta), sort_keys=True,
170 states.append(json.dumps((action, meta), sort_keys=True,
171 separators=(', ', ': ')))
171 separators=(', ', ': ')))
172
172
173 action, meta = reactor.oninputeof()
173 action, meta = reactor.oninputeof()
174 meta['action'] = action
174 meta['action'] = action
175 states.append(json.dumps(meta, sort_keys=True, separators=(', ',': ')))
175 states.append(json.dumps(meta, sort_keys=True, separators=(', ',': ')))
176
176
177 res.status = b'200 OK'
177 res.status = b'200 OK'
178 res.headers[b'Content-Type'] = b'text/plain'
178 res.headers[b'Content-Type'] = b'text/plain'
179 res.setbodybytes(b'\n'.join(states))
179 res.setbodybytes(b'\n'.join(states))
180
180
181 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
181 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
182 """Post-validation handler for HTTPv2 requests.
182 """Post-validation handler for HTTPv2 requests.
183
183
184 Called when the HTTP request contains unified frame-based protocol
184 Called when the HTTP request contains unified frame-based protocol
185 frames for evaluation.
185 frames for evaluation.
186 """
186 """
187 # TODO Some HTTP clients are full duplex and can receive data before
187 # TODO Some HTTP clients are full duplex and can receive data before
188 # the entire request is transmitted. Figure out a way to indicate support
188 # the entire request is transmitted. Figure out a way to indicate support
189 # for that so we can opt into full duplex mode.
189 # for that so we can opt into full duplex mode.
190 reactor = wireprotoframing.serverreactor(deferoutput=True)
190 reactor = wireprotoframing.serverreactor(deferoutput=True)
191 seencommand = False
191 seencommand = False
192
192
193 outstream = reactor.makeoutputstream()
193 outstream = reactor.makeoutputstream()
194
194
195 while True:
195 while True:
196 frame = wireprotoframing.readframe(req.bodyfh)
196 frame = wireprotoframing.readframe(req.bodyfh)
197 if not frame:
197 if not frame:
198 break
198 break
199
199
200 action, meta = reactor.onframerecv(frame)
200 action, meta = reactor.onframerecv(frame)
201
201
202 if action == 'wantframe':
202 if action == 'wantframe':
203 # Need more data before we can do anything.
203 # Need more data before we can do anything.
204 continue
204 continue
205 elif action == 'runcommand':
205 elif action == 'runcommand':
206 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
206 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
207 reqcommand, reactor, outstream,
207 reqcommand, reactor, outstream,
208 meta, issubsequent=seencommand)
208 meta, issubsequent=seencommand)
209
209
210 if sentoutput:
210 if sentoutput:
211 return
211 return
212
212
213 seencommand = True
213 seencommand = True
214
214
215 elif action == 'error':
215 elif action == 'error':
216 # TODO define proper error mechanism.
216 # TODO define proper error mechanism.
217 res.status = b'200 OK'
217 res.status = b'200 OK'
218 res.headers[b'Content-Type'] = b'text/plain'
218 res.headers[b'Content-Type'] = b'text/plain'
219 res.setbodybytes(meta['message'] + b'\n')
219 res.setbodybytes(meta['message'] + b'\n')
220 return
220 return
221 else:
221 else:
222 raise error.ProgrammingError(
222 raise error.ProgrammingError(
223 'unhandled action from frame processor: %s' % action)
223 'unhandled action from frame processor: %s' % action)
224
224
225 action, meta = reactor.oninputeof()
225 action, meta = reactor.oninputeof()
226 if action == 'sendframes':
226 if action == 'sendframes':
227 # We assume we haven't started sending the response yet. If we're
227 # We assume we haven't started sending the response yet. If we're
228 # wrong, the response type will raise an exception.
228 # wrong, the response type will raise an exception.
229 res.status = b'200 OK'
229 res.status = b'200 OK'
230 res.headers[b'Content-Type'] = FRAMINGTYPE
230 res.headers[b'Content-Type'] = FRAMINGTYPE
231 res.setbodygen(meta['framegen'])
231 res.setbodygen(meta['framegen'])
232 elif action == 'noop':
232 elif action == 'noop':
233 pass
233 pass
234 else:
234 else:
235 raise error.ProgrammingError('unhandled action from frame processor: %s'
235 raise error.ProgrammingError('unhandled action from frame processor: %s'
236 % action)
236 % action)
237
237
238 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
238 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
239 outstream, command, issubsequent):
239 outstream, command, issubsequent):
240 """Dispatch a wire protocol command made from HTTPv2 requests.
240 """Dispatch a wire protocol command made from HTTPv2 requests.
241
241
242 The authenticated permission (``authedperm``) along with the original
242 The authenticated permission (``authedperm``) along with the original
243 command from the URL (``reqcommand``) are passed in.
243 command from the URL (``reqcommand``) are passed in.
244 """
244 """
245 # We already validated that the session has permissions to perform the
245 # We already validated that the session has permissions to perform the
246 # actions in ``authedperm``. In the unified frame protocol, the canonical
246 # actions in ``authedperm``. In the unified frame protocol, the canonical
247 # command to run is expressed in a frame. However, the URL also requested
247 # command to run is expressed in a frame. However, the URL also requested
248 # to run a specific command. We need to be careful that the command we
248 # to run a specific command. We need to be careful that the command we
249 # run doesn't have permissions requirements greater than what was granted
249 # run doesn't have permissions requirements greater than what was granted
250 # by ``authedperm``.
250 # by ``authedperm``.
251 #
251 #
252 # Our rule for this is we only allow one command per HTTP request and
252 # Our rule for this is we only allow one command per HTTP request and
253 # that command must match the command in the URL. However, we make
253 # that command must match the command in the URL. However, we make
254 # an exception for the ``multirequest`` URL. This URL is allowed to
254 # an exception for the ``multirequest`` URL. This URL is allowed to
255 # execute multiple commands. We double check permissions of each command
255 # execute multiple commands. We double check permissions of each command
256 # as it is invoked to ensure there is no privilege escalation.
256 # as it is invoked to ensure there is no privilege escalation.
257 # TODO consider allowing multiple commands to regular command URLs
257 # TODO consider allowing multiple commands to regular command URLs
258 # iff each command is the same.
258 # iff each command is the same.
259
259
260 proto = httpv2protocolhandler(req, ui, args=command['args'])
260 proto = httpv2protocolhandler(req, ui, args=command['args'])
261
261
262 if reqcommand == b'multirequest':
262 if reqcommand == b'multirequest':
263 if not COMMANDS.commandavailable(command['command'], proto):
263 if not COMMANDS.commandavailable(command['command'], proto):
264 # TODO proper error mechanism
264 # TODO proper error mechanism
265 res.status = b'200 OK'
265 res.status = b'200 OK'
266 res.headers[b'Content-Type'] = b'text/plain'
266 res.headers[b'Content-Type'] = b'text/plain'
267 res.setbodybytes(_('wire protocol command not available: %s') %
267 res.setbodybytes(_('wire protocol command not available: %s') %
268 command['command'])
268 command['command'])
269 return True
269 return True
270
270
271 # TODO don't use assert here, since it may be elided by -O.
271 # TODO don't use assert here, since it may be elided by -O.
272 assert authedperm in (b'ro', b'rw')
272 assert authedperm in (b'ro', b'rw')
273 wirecommand = COMMANDS[command['command']]
273 wirecommand = COMMANDS[command['command']]
274 assert wirecommand.permission in ('push', 'pull')
274 assert wirecommand.permission in ('push', 'pull')
275
275
276 if authedperm == b'ro' and wirecommand.permission != 'pull':
276 if authedperm == b'ro' and wirecommand.permission != 'pull':
277 # TODO proper error mechanism
277 # TODO proper error mechanism
278 res.status = b'403 Forbidden'
278 res.status = b'403 Forbidden'
279 res.headers[b'Content-Type'] = b'text/plain'
279 res.headers[b'Content-Type'] = b'text/plain'
280 res.setbodybytes(_('insufficient permissions to execute '
280 res.setbodybytes(_('insufficient permissions to execute '
281 'command: %s') % command['command'])
281 'command: %s') % command['command'])
282 return True
282 return True
283
283
284 # TODO should we also call checkperm() here? Maybe not if we're going
284 # TODO should we also call checkperm() here? Maybe not if we're going
285 # to overhaul that API. The granted scope from the URL check should
285 # to overhaul that API. The granted scope from the URL check should
286 # be good enough.
286 # be good enough.
287
287
288 else:
288 else:
289 # Don't allow multiple commands outside of ``multirequest`` URL.
289 # Don't allow multiple commands outside of ``multirequest`` URL.
290 if issubsequent:
290 if issubsequent:
291 # TODO proper error mechanism
291 # TODO proper error mechanism
292 res.status = b'200 OK'
292 res.status = b'200 OK'
293 res.headers[b'Content-Type'] = b'text/plain'
293 res.headers[b'Content-Type'] = b'text/plain'
294 res.setbodybytes(_('multiple commands cannot be issued to this '
294 res.setbodybytes(_('multiple commands cannot be issued to this '
295 'URL'))
295 'URL'))
296 return True
296 return True
297
297
298 if reqcommand != command['command']:
298 if reqcommand != command['command']:
299 # TODO define proper error mechanism
299 # TODO define proper error mechanism
300 res.status = b'200 OK'
300 res.status = b'200 OK'
301 res.headers[b'Content-Type'] = b'text/plain'
301 res.headers[b'Content-Type'] = b'text/plain'
302 res.setbodybytes(_('command in frame must match command in URL'))
302 res.setbodybytes(_('command in frame must match command in URL'))
303 return True
303 return True
304
304
305 res.status = b'200 OK'
305 res.status = b'200 OK'
306 res.headers[b'Content-Type'] = FRAMINGTYPE
306 res.headers[b'Content-Type'] = FRAMINGTYPE
307
307
308 try:
308 try:
309 objs = dispatch(repo, proto, command['command'])
309 objs = dispatch(repo, proto, command['command'])
310
310
311 action, meta = reactor.oncommandresponsereadyobjects(
311 action, meta = reactor.oncommandresponsereadyobjects(
312 outstream, command['requestid'], objs)
312 outstream, command['requestid'], objs)
313
313
314 except error.WireprotoCommandError as e:
315 action, meta = reactor.oncommanderror(
316 outstream, command['requestid'], e.message, e.messageargs)
317
314 except Exception as e:
318 except Exception as e:
315 action, meta = reactor.onservererror(
319 action, meta = reactor.onservererror(
316 outstream, command['requestid'],
320 outstream, command['requestid'],
317 _('exception when invoking command: %s') % e)
321 _('exception when invoking command: %s') % e)
318
322
319 if action == 'sendframes':
323 if action == 'sendframes':
320 res.setbodygen(meta['framegen'])
324 res.setbodygen(meta['framegen'])
321 return True
325 return True
322 elif action == 'noop':
326 elif action == 'noop':
323 return False
327 return False
324 else:
328 else:
325 raise error.ProgrammingError('unhandled event from reactor: %s' %
329 raise error.ProgrammingError('unhandled event from reactor: %s' %
326 action)
330 action)
327
331
328 def getdispatchrepo(repo, proto, command):
332 def getdispatchrepo(repo, proto, command):
329 return repo.filtered('served')
333 return repo.filtered('served')
330
334
331 def dispatch(repo, proto, command):
335 def dispatch(repo, proto, command):
332 repo = getdispatchrepo(repo, proto, command)
336 repo = getdispatchrepo(repo, proto, command)
333
337
334 func, spec = COMMANDS[command]
338 func, spec = COMMANDS[command]
335 args = proto.getargs(spec)
339 args = proto.getargs(spec)
336
340
337 return func(repo, proto, **args)
341 return func(repo, proto, **args)
338
342
339 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
343 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
340 class httpv2protocolhandler(object):
344 class httpv2protocolhandler(object):
341 def __init__(self, req, ui, args=None):
345 def __init__(self, req, ui, args=None):
342 self._req = req
346 self._req = req
343 self._ui = ui
347 self._ui = ui
344 self._args = args
348 self._args = args
345
349
346 @property
350 @property
347 def name(self):
351 def name(self):
348 return HTTP_WIREPROTO_V2
352 return HTTP_WIREPROTO_V2
349
353
350 def getargs(self, args):
354 def getargs(self, args):
355 # First look for args that were passed but aren't registered on this
356 # command.
357 extra = set(self._args) - set(args)
358 if extra:
359 raise error.WireprotoCommandError(
360 'unsupported argument to command: %s' %
361 ', '.join(sorted(extra)))
362
363 # And look for required arguments that are missing.
364 missing = {a for a in args if args[a]['required']} - set(self._args)
365
366 if missing:
367 raise error.WireprotoCommandError(
368 'missing required arguments: %s' % ', '.join(sorted(missing)))
369
370 # Now derive the arguments to pass to the command, taking into
371 # account the arguments specified by the client.
351 data = {}
372 data = {}
352 for k, typ in args.items():
373 for k, meta in sorted(args.items()):
353 if k == '*':
374 # This argument wasn't passed by the client.
354 raise NotImplementedError('do not support * args')
375 if k not in self._args:
355 elif k in self._args:
376 data[k] = meta['default']()
356 # TODO consider validating value types.
377 continue
357 data[k] = self._args[k]
378
379 v = self._args[k]
380
381 # Sets may be expressed as lists. Silently normalize.
382 if meta['type'] == 'set' and isinstance(v, list):
383 v = set(v)
384
385 # TODO consider more/stronger type validation.
386
387 data[k] = v
358
388
359 return data
389 return data
360
390
361 def getprotocaps(self):
391 def getprotocaps(self):
362 # Protocol capabilities are currently not implemented for HTTP V2.
392 # Protocol capabilities are currently not implemented for HTTP V2.
363 return set()
393 return set()
364
394
365 def getpayload(self):
395 def getpayload(self):
366 raise NotImplementedError
396 raise NotImplementedError
367
397
368 @contextlib.contextmanager
398 @contextlib.contextmanager
369 def mayberedirectstdio(self):
399 def mayberedirectstdio(self):
370 raise NotImplementedError
400 raise NotImplementedError
371
401
372 def client(self):
402 def client(self):
373 raise NotImplementedError
403 raise NotImplementedError
374
404
375 def addcapabilities(self, repo, caps):
405 def addcapabilities(self, repo, caps):
376 return caps
406 return caps
377
407
378 def checkperm(self, perm):
408 def checkperm(self, perm):
379 raise NotImplementedError
409 raise NotImplementedError
380
410
381 def httpv2apidescriptor(req, repo):
411 def httpv2apidescriptor(req, repo):
382 proto = httpv2protocolhandler(req, repo.ui)
412 proto = httpv2protocolhandler(req, repo.ui)
383
413
384 return _capabilitiesv2(repo, proto)
414 return _capabilitiesv2(repo, proto)
385
415
386 def _capabilitiesv2(repo, proto):
416 def _capabilitiesv2(repo, proto):
387 """Obtain the set of capabilities for version 2 transports.
417 """Obtain the set of capabilities for version 2 transports.
388
418
389 These capabilities are distinct from the capabilities for version 1
419 These capabilities are distinct from the capabilities for version 1
390 transports.
420 transports.
391 """
421 """
392 compression = []
422 compression = []
393 for engine in wireprototypes.supportedcompengines(repo.ui, util.SERVERROLE):
423 for engine in wireprototypes.supportedcompengines(repo.ui, util.SERVERROLE):
394 compression.append({
424 compression.append({
395 b'name': engine.wireprotosupport().name,
425 b'name': engine.wireprotosupport().name,
396 })
426 })
397
427
398 caps = {
428 caps = {
399 'commands': {},
429 'commands': {},
400 'compression': compression,
430 'compression': compression,
401 'framingmediatypes': [FRAMINGTYPE],
431 'framingmediatypes': [FRAMINGTYPE],
402 }
432 }
403
433
404 # TODO expose available changesetdata fields.
434 # TODO expose available changesetdata fields.
405
435
406 for command, entry in COMMANDS.items():
436 for command, entry in COMMANDS.items():
437 args = {arg: meta['example'] for arg, meta in entry.args.items()}
438
407 caps['commands'][command] = {
439 caps['commands'][command] = {
408 'args': entry.args,
440 'args': args,
409 'permissions': [entry.permission],
441 'permissions': [entry.permission],
410 }
442 }
411
443
412 if streamclone.allowservergeneration(repo):
444 if streamclone.allowservergeneration(repo):
413 caps['rawrepoformats'] = sorted(repo.requirements &
445 caps['rawrepoformats'] = sorted(repo.requirements &
414 repo.supportedformats)
446 repo.supportedformats)
415
447
416 return proto.addcapabilities(repo, caps)
448 return proto.addcapabilities(repo, caps)
417
449
418 def builddeltarequests(store, nodes, haveparents):
450 def builddeltarequests(store, nodes, haveparents):
419 """Build a series of revision delta requests against a backend store.
451 """Build a series of revision delta requests against a backend store.
420
452
421 Returns a list of revision numbers in the order they should be sent
453 Returns a list of revision numbers in the order they should be sent
422 and a list of ``irevisiondeltarequest`` instances to be made against
454 and a list of ``irevisiondeltarequest`` instances to be made against
423 the backend store.
455 the backend store.
424 """
456 """
425 # We sort and send nodes in DAG order because this is optimal for
457 # We sort and send nodes in DAG order because this is optimal for
426 # storage emission.
458 # storage emission.
427 # TODO we may want a better storage API here - one where we can throw
459 # TODO we may want a better storage API here - one where we can throw
428 # a list of nodes and delta preconditions over a figurative wall and
460 # a list of nodes and delta preconditions over a figurative wall and
429 # have the storage backend figure it out for us.
461 # have the storage backend figure it out for us.
430 revs = dagop.linearize({store.rev(n) for n in nodes}, store.parentrevs)
462 revs = dagop.linearize({store.rev(n) for n in nodes}, store.parentrevs)
431
463
432 requests = []
464 requests = []
433 seenrevs = set()
465 seenrevs = set()
434
466
435 for rev in revs:
467 for rev in revs:
436 node = store.node(rev)
468 node = store.node(rev)
437 parentnodes = store.parents(node)
469 parentnodes = store.parents(node)
438 parentrevs = [store.rev(n) for n in parentnodes]
470 parentrevs = [store.rev(n) for n in parentnodes]
439 deltabaserev = store.deltaparent(rev)
471 deltabaserev = store.deltaparent(rev)
440 deltabasenode = store.node(deltabaserev)
472 deltabasenode = store.node(deltabaserev)
441
473
442 # The choice of whether to send a fulltext revision or a delta and
474 # The choice of whether to send a fulltext revision or a delta and
443 # what delta to send is governed by a few factors.
475 # what delta to send is governed by a few factors.
444 #
476 #
445 # To send a delta, we need to ensure the receiver is capable of
477 # To send a delta, we need to ensure the receiver is capable of
446 # decoding it. And that requires the receiver to have the base
478 # decoding it. And that requires the receiver to have the base
447 # revision the delta is against.
479 # revision the delta is against.
448 #
480 #
449 # We can only guarantee the receiver has the base revision if
481 # We can only guarantee the receiver has the base revision if
450 # a) we've already sent the revision as part of this group
482 # a) we've already sent the revision as part of this group
451 # b) the receiver has indicated they already have the revision.
483 # b) the receiver has indicated they already have the revision.
452 # And the mechanism for "b" is the client indicating they have
484 # And the mechanism for "b" is the client indicating they have
453 # parent revisions. So this means we can only send the delta if
485 # parent revisions. So this means we can only send the delta if
454 # it is sent before or it is against a delta and the receiver says
486 # it is sent before or it is against a delta and the receiver says
455 # they have a parent.
487 # they have a parent.
456
488
457 # We can send storage delta if it is against a revision we've sent
489 # We can send storage delta if it is against a revision we've sent
458 # in this group.
490 # in this group.
459 if deltabaserev != nullrev and deltabaserev in seenrevs:
491 if deltabaserev != nullrev and deltabaserev in seenrevs:
460 basenode = deltabasenode
492 basenode = deltabasenode
461
493
462 # We can send storage delta if it is against a parent revision and
494 # We can send storage delta if it is against a parent revision and
463 # the receiver indicates they have the parents.
495 # the receiver indicates they have the parents.
464 elif (deltabaserev != nullrev and deltabaserev in parentrevs
496 elif (deltabaserev != nullrev and deltabaserev in parentrevs
465 and haveparents):
497 and haveparents):
466 basenode = deltabasenode
498 basenode = deltabasenode
467
499
468 # Otherwise the storage delta isn't appropriate. Fall back to
500 # Otherwise the storage delta isn't appropriate. Fall back to
469 # using another delta, if possible.
501 # using another delta, if possible.
470
502
471 # Use p1 if we've emitted it or receiver says they have it.
503 # Use p1 if we've emitted it or receiver says they have it.
472 elif parentrevs[0] != nullrev and (
504 elif parentrevs[0] != nullrev and (
473 parentrevs[0] in seenrevs or haveparents):
505 parentrevs[0] in seenrevs or haveparents):
474 basenode = parentnodes[0]
506 basenode = parentnodes[0]
475
507
476 # Use p2 if we've emitted it or receiver says they have it.
508 # Use p2 if we've emitted it or receiver says they have it.
477 elif parentrevs[1] != nullrev and (
509 elif parentrevs[1] != nullrev and (
478 parentrevs[1] in seenrevs or haveparents):
510 parentrevs[1] in seenrevs or haveparents):
479 basenode = parentnodes[1]
511 basenode = parentnodes[1]
480
512
481 # Nothing appropriate to delta against. Send the full revision.
513 # Nothing appropriate to delta against. Send the full revision.
482 else:
514 else:
483 basenode = nullid
515 basenode = nullid
484
516
485 requests.append(changegroup.revisiondeltarequest(
517 requests.append(changegroup.revisiondeltarequest(
486 node=node,
518 node=node,
487 p1node=parentnodes[0],
519 p1node=parentnodes[0],
488 p2node=parentnodes[1],
520 p2node=parentnodes[1],
489 # Receiver deals with linknode resolution.
521 # Receiver deals with linknode resolution.
490 linknode=nullid,
522 linknode=nullid,
491 basenode=basenode,
523 basenode=basenode,
492 ))
524 ))
493
525
494 seenrevs.add(rev)
526 seenrevs.add(rev)
495
527
496 return revs, requests
528 return revs, requests
497
529
498 def wireprotocommand(name, args=None, permission='push'):
530 def wireprotocommand(name, args=None, permission='push'):
499 """Decorator to declare a wire protocol command.
531 """Decorator to declare a wire protocol command.
500
532
501 ``name`` is the name of the wire protocol command being provided.
533 ``name`` is the name of the wire protocol command being provided.
502
534
503 ``args`` is a dict of argument names to example values.
535 ``args`` is a dict defining arguments accepted by the command. Keys are
536 the argument name. Values are dicts with the following keys:
537
538 ``type``
539 The argument data type. Must be one of the following string
540 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
541 or ``bool``.
542
543 ``default``
544 A callable returning the default value for this argument. If not
545 specified, ``None`` will be the default value.
546
547 ``required``
548 Bool indicating whether the argument is required.
549
550 ``example``
551 An example value for this argument.
504
552
505 ``permission`` defines the permission type needed to run this command.
553 ``permission`` defines the permission type needed to run this command.
506 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
554 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
507 respectively. Default is to assume command requires ``push`` permissions
555 respectively. Default is to assume command requires ``push`` permissions
508 because otherwise commands not declaring their permissions could modify
556 because otherwise commands not declaring their permissions could modify
509 a repository that is supposed to be read-only.
557 a repository that is supposed to be read-only.
510
558
511 Wire protocol commands are generators of objects to be serialized and
559 Wire protocol commands are generators of objects to be serialized and
512 sent to the client.
560 sent to the client.
513
561
514 If a command raises an uncaught exception, this will be translated into
562 If a command raises an uncaught exception, this will be translated into
515 a command error.
563 a command error.
516 """
564 """
517 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
565 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
518 if v['version'] == 2}
566 if v['version'] == 2}
519
567
520 if permission not in ('push', 'pull'):
568 if permission not in ('push', 'pull'):
521 raise error.ProgrammingError('invalid wire protocol permission; '
569 raise error.ProgrammingError('invalid wire protocol permission; '
522 'got %s; expected "push" or "pull"' %
570 'got %s; expected "push" or "pull"' %
523 permission)
571 permission)
524
572
525 if args is None:
573 if args is None:
526 args = {}
574 args = {}
527
575
528 if not isinstance(args, dict):
576 if not isinstance(args, dict):
529 raise error.ProgrammingError('arguments for version 2 commands '
577 raise error.ProgrammingError('arguments for version 2 commands '
530 'must be declared as dicts')
578 'must be declared as dicts')
531
579
580 for arg, meta in args.items():
581 if arg == '*':
582 raise error.ProgrammingError('* argument name not allowed on '
583 'version 2 commands')
584
585 if not isinstance(meta, dict):
586 raise error.ProgrammingError('arguments for version 2 commands '
587 'must declare metadata as a dict')
588
589 if 'type' not in meta:
590 raise error.ProgrammingError('%s argument for command %s does not '
591 'declare type field' % (arg, name))
592
593 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
594 raise error.ProgrammingError('%s argument for command %s has '
595 'illegal type: %s' % (arg, name,
596 meta['type']))
597
598 if 'example' not in meta:
599 raise error.ProgrammingError('%s argument for command %s does not '
600 'declare example field' % (arg, name))
601
602 if 'default' in meta and meta.get('required'):
603 raise error.ProgrammingError('%s argument for command %s is marked '
604 'as required but has a default value' %
605 (arg, name))
606
607 meta.setdefault('default', lambda: None)
608 meta.setdefault('required', False)
609
532 def register(func):
610 def register(func):
533 if name in COMMANDS:
611 if name in COMMANDS:
534 raise error.ProgrammingError('%s command already registered '
612 raise error.ProgrammingError('%s command already registered '
535 'for version 2' % name)
613 'for version 2' % name)
536
614
537 COMMANDS[name] = wireprototypes.commandentry(
615 COMMANDS[name] = wireprototypes.commandentry(
538 func, args=args, transports=transports, permission=permission)
616 func, args=args, transports=transports, permission=permission)
539
617
540 return func
618 return func
541
619
542 return register
620 return register
543
621
544 @wireprotocommand('branchmap', permission='pull')
622 @wireprotocommand('branchmap', permission='pull')
545 def branchmapv2(repo, proto):
623 def branchmapv2(repo, proto):
546 yield {encoding.fromlocal(k): v
624 yield {encoding.fromlocal(k): v
547 for k, v in repo.branchmap().iteritems()}
625 for k, v in repo.branchmap().iteritems()}
548
626
549 @wireprotocommand('capabilities', permission='pull')
627 @wireprotocommand('capabilities', permission='pull')
550 def capabilitiesv2(repo, proto):
628 def capabilitiesv2(repo, proto):
551 yield _capabilitiesv2(repo, proto)
629 yield _capabilitiesv2(repo, proto)
552
630
553 @wireprotocommand('changesetdata',
631 @wireprotocommand(
554 args={
632 'changesetdata',
555 'noderange': [[b'0123456...'], [b'abcdef...']],
633 args={
556 'nodes': [b'0123456...'],
634 'noderange': {
557 'fields': {b'parents', b'revision'},
635 'type': 'list',
558 },
636 'example': [[b'0123456...'], [b'abcdef...']],
559 permission='pull')
637 },
560 def changesetdata(repo, proto, noderange=None, nodes=None, fields=None):
638 'nodes': {
561 fields = fields or set()
639 'type': 'list',
562
640 'example': [b'0123456...'],
641 },
642 'fields': {
643 'type': 'set',
644 'default': set,
645 'example': {b'parents', b'revision'},
646 },
647 },
648 permission='pull')
649 def changesetdata(repo, proto, noderange, nodes, fields):
563 # TODO look for unknown fields and abort when they can't be serviced.
650 # TODO look for unknown fields and abort when they can't be serviced.
564
651
565 if noderange is None and nodes is None:
652 if noderange is None and nodes is None:
566 raise error.WireprotoCommandError(
653 raise error.WireprotoCommandError(
567 'noderange or nodes must be defined')
654 'noderange or nodes must be defined')
568
655
569 if noderange is not None:
656 if noderange is not None:
570 if len(noderange) != 2:
657 if len(noderange) != 2:
571 raise error.WireprotoCommandError(
658 raise error.WireprotoCommandError(
572 'noderange must consist of 2 elements')
659 'noderange must consist of 2 elements')
573
660
574 if not noderange[1]:
661 if not noderange[1]:
575 raise error.WireprotoCommandError(
662 raise error.WireprotoCommandError(
576 'heads in noderange request cannot be empty')
663 'heads in noderange request cannot be empty')
577
664
578 cl = repo.changelog
665 cl = repo.changelog
579 hasnode = cl.hasnode
666 hasnode = cl.hasnode
580
667
581 seen = set()
668 seen = set()
582 outgoing = []
669 outgoing = []
583
670
584 if nodes is not None:
671 if nodes is not None:
585 outgoing.extend(n for n in nodes if hasnode(n))
672 outgoing.extend(n for n in nodes if hasnode(n))
586 seen |= set(outgoing)
673 seen |= set(outgoing)
587
674
588 if noderange is not None:
675 if noderange is not None:
589 if noderange[0]:
676 if noderange[0]:
590 common = [n for n in noderange[0] if hasnode(n)]
677 common = [n for n in noderange[0] if hasnode(n)]
591 else:
678 else:
592 common = [nullid]
679 common = [nullid]
593
680
594 for n in discovery.outgoing(repo, common, noderange[1]).missing:
681 for n in discovery.outgoing(repo, common, noderange[1]).missing:
595 if n not in seen:
682 if n not in seen:
596 outgoing.append(n)
683 outgoing.append(n)
597 # Don't need to add to seen here because this is the final
684 # Don't need to add to seen here because this is the final
598 # source of nodes and there should be no duplicates in this
685 # source of nodes and there should be no duplicates in this
599 # list.
686 # list.
600
687
601 seen.clear()
688 seen.clear()
602 publishing = repo.publishing()
689 publishing = repo.publishing()
603
690
604 if outgoing:
691 if outgoing:
605 repo.hook('preoutgoing', throw=True, source='serve')
692 repo.hook('preoutgoing', throw=True, source='serve')
606
693
607 yield {
694 yield {
608 b'totalitems': len(outgoing),
695 b'totalitems': len(outgoing),
609 }
696 }
610
697
611 # The phases of nodes already transferred to the client may have changed
698 # The phases of nodes already transferred to the client may have changed
612 # since the client last requested data. We send phase-only records
699 # since the client last requested data. We send phase-only records
613 # for these revisions, if requested.
700 # for these revisions, if requested.
614 if b'phase' in fields and noderange is not None:
701 if b'phase' in fields and noderange is not None:
615 # TODO skip nodes whose phase will be reflected by a node in the
702 # TODO skip nodes whose phase will be reflected by a node in the
616 # outgoing set. This is purely an optimization to reduce data
703 # outgoing set. This is purely an optimization to reduce data
617 # size.
704 # size.
618 for node in noderange[0]:
705 for node in noderange[0]:
619 yield {
706 yield {
620 b'node': node,
707 b'node': node,
621 b'phase': b'public' if publishing else repo[node].phasestr()
708 b'phase': b'public' if publishing else repo[node].phasestr()
622 }
709 }
623
710
624 nodebookmarks = {}
711 nodebookmarks = {}
625 for mark, node in repo._bookmarks.items():
712 for mark, node in repo._bookmarks.items():
626 nodebookmarks.setdefault(node, set()).add(mark)
713 nodebookmarks.setdefault(node, set()).add(mark)
627
714
628 # It is already topologically sorted by revision number.
715 # It is already topologically sorted by revision number.
629 for node in outgoing:
716 for node in outgoing:
630 d = {
717 d = {
631 b'node': node,
718 b'node': node,
632 }
719 }
633
720
634 if b'parents' in fields:
721 if b'parents' in fields:
635 d[b'parents'] = cl.parents(node)
722 d[b'parents'] = cl.parents(node)
636
723
637 if b'phase' in fields:
724 if b'phase' in fields:
638 if publishing:
725 if publishing:
639 d[b'phase'] = b'public'
726 d[b'phase'] = b'public'
640 else:
727 else:
641 ctx = repo[node]
728 ctx = repo[node]
642 d[b'phase'] = ctx.phasestr()
729 d[b'phase'] = ctx.phasestr()
643
730
644 if b'bookmarks' in fields and node in nodebookmarks:
731 if b'bookmarks' in fields and node in nodebookmarks:
645 d[b'bookmarks'] = sorted(nodebookmarks[node])
732 d[b'bookmarks'] = sorted(nodebookmarks[node])
646 del nodebookmarks[node]
733 del nodebookmarks[node]
647
734
648 revisiondata = None
735 revisiondata = None
649
736
650 if b'revision' in fields:
737 if b'revision' in fields:
651 revisiondata = cl.revision(node, raw=True)
738 revisiondata = cl.revision(node, raw=True)
652 d[b'revisionsize'] = len(revisiondata)
739 d[b'revisionsize'] = len(revisiondata)
653
740
654 # TODO make it possible for extensions to wrap a function or register
741 # TODO make it possible for extensions to wrap a function or register
655 # a handler to service custom fields.
742 # a handler to service custom fields.
656
743
657 yield d
744 yield d
658
745
659 if revisiondata is not None:
746 if revisiondata is not None:
660 yield revisiondata
747 yield revisiondata
661
748
662 # If requested, send bookmarks from nodes that didn't have revision
749 # If requested, send bookmarks from nodes that didn't have revision
663 # data sent so receiver is aware of any bookmark updates.
750 # data sent so receiver is aware of any bookmark updates.
664 if b'bookmarks' in fields:
751 if b'bookmarks' in fields:
665 for node, marks in sorted(nodebookmarks.iteritems()):
752 for node, marks in sorted(nodebookmarks.iteritems()):
666 yield {
753 yield {
667 b'node': node,
754 b'node': node,
668 b'bookmarks': sorted(marks),
755 b'bookmarks': sorted(marks),
669 }
756 }
670
757
671 class FileAccessError(Exception):
758 class FileAccessError(Exception):
672 """Represents an error accessing a specific file."""
759 """Represents an error accessing a specific file."""
673
760
674 def __init__(self, path, msg, args):
761 def __init__(self, path, msg, args):
675 self.path = path
762 self.path = path
676 self.msg = msg
763 self.msg = msg
677 self.args = args
764 self.args = args
678
765
679 def getfilestore(repo, proto, path):
766 def getfilestore(repo, proto, path):
680 """Obtain a file storage object for use with wire protocol.
767 """Obtain a file storage object for use with wire protocol.
681
768
682 Exists as a standalone function so extensions can monkeypatch to add
769 Exists as a standalone function so extensions can monkeypatch to add
683 access control.
770 access control.
684 """
771 """
685 # This seems to work even if the file doesn't exist. So catch
772 # This seems to work even if the file doesn't exist. So catch
686 # "empty" files and return an error.
773 # "empty" files and return an error.
687 fl = repo.file(path)
774 fl = repo.file(path)
688
775
689 if not len(fl):
776 if not len(fl):
690 raise FileAccessError(path, 'unknown file: %s', (path,))
777 raise FileAccessError(path, 'unknown file: %s', (path,))
691
778
692 return fl
779 return fl
693
780
694 @wireprotocommand('filedata',
781 @wireprotocommand(
695 args={
782 'filedata',
696 'haveparents': True,
783 args={
697 'nodes': [b'0123456...'],
784 'haveparents': {
698 'fields': [b'parents', b'revision'],
785 'type': 'bool',
699 'path': b'foo.txt',
786 'default': lambda: False,
700 },
787 'example': True,
701 permission='pull')
788 },
702 def filedata(repo, proto, haveparents=False, nodes=None, fields=None,
789 'nodes': {
703 path=None):
790 'type': 'list',
704 fields = fields or set()
791 'required': True,
705
792 'example': [b'0123456...'],
706 if nodes is None:
793 },
707 raise error.WireprotoCommandError('nodes argument must be defined')
794 'fields': {
708
795 'type': 'set',
709 if path is None:
796 'default': set,
710 raise error.WireprotoCommandError('path argument must be defined')
797 'example': {b'parents', b'revision'},
711
798 },
799 'path': {
800 'type': 'bytes',
801 'required': True,
802 'example': b'foo.txt',
803 }
804 },
805 permission='pull')
806 def filedata(repo, proto, haveparents, nodes, fields, path):
712 try:
807 try:
713 # Extensions may wish to access the protocol handler.
808 # Extensions may wish to access the protocol handler.
714 store = getfilestore(repo, proto, path)
809 store = getfilestore(repo, proto, path)
715 except FileAccessError as e:
810 except FileAccessError as e:
716 raise error.WireprotoCommandError(e.msg, e.args)
811 raise error.WireprotoCommandError(e.msg, e.args)
717
812
718 # Validate requested nodes.
813 # Validate requested nodes.
719 for node in nodes:
814 for node in nodes:
720 try:
815 try:
721 store.rev(node)
816 store.rev(node)
722 except error.LookupError:
817 except error.LookupError:
723 raise error.WireprotoCommandError('unknown file node: %s',
818 raise error.WireprotoCommandError('unknown file node: %s',
724 (hex(node),))
819 (hex(node),))
725
820
726 revs, requests = builddeltarequests(store, nodes, haveparents)
821 revs, requests = builddeltarequests(store, nodes, haveparents)
727
822
728 yield {
823 yield {
729 b'totalitems': len(revs),
824 b'totalitems': len(revs),
730 }
825 }
731
826
732 if b'revision' in fields:
827 if b'revision' in fields:
733 deltas = store.emitrevisiondeltas(requests)
828 deltas = store.emitrevisiondeltas(requests)
734 else:
829 else:
735 deltas = None
830 deltas = None
736
831
737 for rev in revs:
832 for rev in revs:
738 node = store.node(rev)
833 node = store.node(rev)
739
834
740 if deltas is not None:
835 if deltas is not None:
741 delta = next(deltas)
836 delta = next(deltas)
742 else:
837 else:
743 delta = None
838 delta = None
744
839
745 d = {
840 d = {
746 b'node': node,
841 b'node': node,
747 }
842 }
748
843
749 if b'parents' in fields:
844 if b'parents' in fields:
750 d[b'parents'] = store.parents(node)
845 d[b'parents'] = store.parents(node)
751
846
752 if b'revision' in fields:
847 if b'revision' in fields:
753 assert delta is not None
848 assert delta is not None
754 assert delta.flags == 0
849 assert delta.flags == 0
755 assert d[b'node'] == delta.node
850 assert d[b'node'] == delta.node
756
851
757 if delta.revision is not None:
852 if delta.revision is not None:
758 revisiondata = delta.revision
853 revisiondata = delta.revision
759 d[b'revisionsize'] = len(revisiondata)
854 d[b'revisionsize'] = len(revisiondata)
760 else:
855 else:
761 d[b'deltabasenode'] = delta.basenode
856 d[b'deltabasenode'] = delta.basenode
762 revisiondata = delta.delta
857 revisiondata = delta.delta
763 d[b'deltasize'] = len(revisiondata)
858 d[b'deltasize'] = len(revisiondata)
764 else:
859 else:
765 revisiondata = None
860 revisiondata = None
766
861
767 yield d
862 yield d
768
863
769 if revisiondata is not None:
864 if revisiondata is not None:
770 yield revisiondata
865 yield revisiondata
771
866
772 if deltas is not None:
867 if deltas is not None:
773 try:
868 try:
774 next(deltas)
869 next(deltas)
775 raise error.ProgrammingError('should not have more deltas')
870 raise error.ProgrammingError('should not have more deltas')
776 except GeneratorExit:
871 except GeneratorExit:
777 pass
872 pass
778
873
779 @wireprotocommand('heads',
874 @wireprotocommand(
780 args={
875 'heads',
781 'publiconly': False,
876 args={
782 },
877 'publiconly': {
783 permission='pull')
878 'type': 'bool',
784 def headsv2(repo, proto, publiconly=False):
879 'default': lambda: False,
880 'example': False,
881 },
882 },
883 permission='pull')
884 def headsv2(repo, proto, publiconly):
785 if publiconly:
885 if publiconly:
786 repo = repo.filtered('immutable')
886 repo = repo.filtered('immutable')
787
887
788 yield repo.heads()
888 yield repo.heads()
789
889
790 @wireprotocommand('known',
890 @wireprotocommand(
791 args={
891 'known',
792 'nodes': [b'deadbeef'],
892 args={
793 },
893 'nodes': {
794 permission='pull')
894 'type': 'list',
795 def knownv2(repo, proto, nodes=None):
895 'default': list,
796 nodes = nodes or []
896 'example': [b'deadbeef'],
897 },
898 },
899 permission='pull')
900 def knownv2(repo, proto, nodes):
797 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
901 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
798 yield result
902 yield result
799
903
800 @wireprotocommand('listkeys',
904 @wireprotocommand(
801 args={
905 'listkeys',
802 'namespace': b'ns',
906 args={
803 },
907 'namespace': {
804 permission='pull')
908 'type': 'bytes',
805 def listkeysv2(repo, proto, namespace=None):
909 'required': True,
910 'example': b'ns',
911 },
912 },
913 permission='pull')
914 def listkeysv2(repo, proto, namespace):
806 keys = repo.listkeys(encoding.tolocal(namespace))
915 keys = repo.listkeys(encoding.tolocal(namespace))
807 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
916 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
808 for k, v in keys.iteritems()}
917 for k, v in keys.iteritems()}
809
918
810 yield keys
919 yield keys
811
920
812 @wireprotocommand('lookup',
921 @wireprotocommand(
813 args={
922 'lookup',
814 'key': b'foo',
923 args={
815 },
924 'key': {
816 permission='pull')
925 'type': 'bytes',
926 'required': True,
927 'example': b'foo',
928 },
929 },
930 permission='pull')
817 def lookupv2(repo, proto, key):
931 def lookupv2(repo, proto, key):
818 key = encoding.tolocal(key)
932 key = encoding.tolocal(key)
819
933
820 # TODO handle exception.
934 # TODO handle exception.
821 node = repo.lookup(key)
935 node = repo.lookup(key)
822
936
823 yield node
937 yield node
824
938
825 @wireprotocommand('manifestdata',
939 @wireprotocommand(
826 args={
940 'manifestdata',
827 'nodes': [b'0123456...'],
941 args={
828 'haveparents': True,
942 'nodes': {
829 'fields': [b'parents', b'revision'],
943 'type': 'list',
830 'tree': b'',
944 'required': True,
831 },
945 'example': [b'0123456...'],
832 permission='pull')
946 },
833 def manifestdata(repo, proto, haveparents=False, nodes=None, fields=None,
947 'haveparents': {
834 tree=None):
948 'type': 'bool',
835 fields = fields or set()
949 'default': lambda: False,
836
950 'example': True,
837 if nodes is None:
951 },
838 raise error.WireprotoCommandError(
952 'fields': {
839 'nodes argument must be defined')
953 'type': 'set',
840
954 'default': set,
841 if tree is None:
955 'example': {b'parents', b'revision'},
842 raise error.WireprotoCommandError(
956 },
843 'tree argument must be defined')
957 'tree': {
844
958 'type': 'bytes',
959 'required': True,
960 'example': b'',
961 },
962 },
963 permission='pull')
964 def manifestdata(repo, proto, haveparents, nodes, fields, tree):
845 store = repo.manifestlog.getstorage(tree)
965 store = repo.manifestlog.getstorage(tree)
846
966
847 # Validate the node is known and abort on unknown revisions.
967 # Validate the node is known and abort on unknown revisions.
848 for node in nodes:
968 for node in nodes:
849 try:
969 try:
850 store.rev(node)
970 store.rev(node)
851 except error.LookupError:
971 except error.LookupError:
852 raise error.WireprotoCommandError(
972 raise error.WireprotoCommandError(
853 'unknown node: %s', (node,))
973 'unknown node: %s', (node,))
854
974
855 revs, requests = builddeltarequests(store, nodes, haveparents)
975 revs, requests = builddeltarequests(store, nodes, haveparents)
856
976
857 yield {
977 yield {
858 b'totalitems': len(revs),
978 b'totalitems': len(revs),
859 }
979 }
860
980
861 if b'revision' in fields:
981 if b'revision' in fields:
862 deltas = store.emitrevisiondeltas(requests)
982 deltas = store.emitrevisiondeltas(requests)
863 else:
983 else:
864 deltas = None
984 deltas = None
865
985
866 for rev in revs:
986 for rev in revs:
867 node = store.node(rev)
987 node = store.node(rev)
868
988
869 if deltas is not None:
989 if deltas is not None:
870 delta = next(deltas)
990 delta = next(deltas)
871 else:
991 else:
872 delta = None
992 delta = None
873
993
874 d = {
994 d = {
875 b'node': node,
995 b'node': node,
876 }
996 }
877
997
878 if b'parents' in fields:
998 if b'parents' in fields:
879 d[b'parents'] = store.parents(node)
999 d[b'parents'] = store.parents(node)
880
1000
881 if b'revision' in fields:
1001 if b'revision' in fields:
882 assert delta is not None
1002 assert delta is not None
883 assert delta.flags == 0
1003 assert delta.flags == 0
884 assert d[b'node'] == delta.node
1004 assert d[b'node'] == delta.node
885
1005
886 if delta.revision is not None:
1006 if delta.revision is not None:
887 revisiondata = delta.revision
1007 revisiondata = delta.revision
888 d[b'revisionsize'] = len(revisiondata)
1008 d[b'revisionsize'] = len(revisiondata)
889 else:
1009 else:
890 d[b'deltabasenode'] = delta.basenode
1010 d[b'deltabasenode'] = delta.basenode
891 revisiondata = delta.delta
1011 revisiondata = delta.delta
892 d[b'deltasize'] = len(revisiondata)
1012 d[b'deltasize'] = len(revisiondata)
893 else:
1013 else:
894 revisiondata = None
1014 revisiondata = None
895
1015
896 yield d
1016 yield d
897
1017
898 if revisiondata is not None:
1018 if revisiondata is not None:
899 yield revisiondata
1019 yield revisiondata
900
1020
901 if deltas is not None:
1021 if deltas is not None:
902 try:
1022 try:
903 next(deltas)
1023 next(deltas)
904 raise error.ProgrammingError('should not have more deltas')
1024 raise error.ProgrammingError('should not have more deltas')
905 except GeneratorExit:
1025 except GeneratorExit:
906 pass
1026 pass
907
1027
908 @wireprotocommand('pushkey',
1028 @wireprotocommand(
909 args={
1029 'pushkey',
910 'namespace': b'ns',
1030 args={
911 'key': b'key',
1031 'namespace': {
912 'old': b'old',
1032 'type': 'bytes',
913 'new': b'new',
1033 'required': True,
914 },
1034 'example': b'ns',
915 permission='push')
1035 },
1036 'key': {
1037 'type': 'bytes',
1038 'required': True,
1039 'example': b'key',
1040 },
1041 'old': {
1042 'type': 'bytes',
1043 'required': True,
1044 'example': b'old',
1045 },
1046 'new': {
1047 'type': 'bytes',
1048 'required': True,
1049 'example': 'new',
1050 },
1051 },
1052 permission='push')
916 def pushkeyv2(repo, proto, namespace, key, old, new):
1053 def pushkeyv2(repo, proto, namespace, key, old, new):
917 # TODO handle ui output redirection
1054 # TODO handle ui output redirection
918 yield repo.pushkey(encoding.tolocal(namespace),
1055 yield repo.pushkey(encoding.tolocal(namespace),
919 encoding.tolocal(key),
1056 encoding.tolocal(key),
920 encoding.tolocal(old),
1057 encoding.tolocal(old),
921 encoding.tolocal(new))
1058 encoding.tolocal(new))
@@ -1,749 +1,749
1 #require no-chg
1 #require no-chg
2
2
3 $ . $TESTDIR/wireprotohelpers.sh
3 $ . $TESTDIR/wireprotohelpers.sh
4
4
5 $ cat >> $HGRCPATH << EOF
5 $ cat >> $HGRCPATH << EOF
6 > [web]
6 > [web]
7 > push_ssl = false
7 > push_ssl = false
8 > allow_push = *
8 > allow_push = *
9 > EOF
9 > EOF
10
10
11 $ hg init server
11 $ hg init server
12 $ cd server
12 $ cd server
13 $ touch a
13 $ touch a
14 $ hg -q commit -A -m initial
14 $ hg -q commit -A -m initial
15 $ cd ..
15 $ cd ..
16
16
17 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
17 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
18 $ cat hg.pid >> $DAEMON_PIDS
18 $ cat hg.pid >> $DAEMON_PIDS
19
19
20 compression formats are advertised in compression capability
20 compression formats are advertised in compression capability
21
21
22 #if zstd
22 #if zstd
23 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zstd,zlib$' > /dev/null
23 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zstd,zlib$' > /dev/null
24 #else
24 #else
25 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zlib$' > /dev/null
25 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zlib$' > /dev/null
26 #endif
26 #endif
27
27
28 $ killdaemons.py
28 $ killdaemons.py
29
29
30 server.compressionengines can replace engines list wholesale
30 server.compressionengines can replace engines list wholesale
31
31
32 $ hg serve --config server.compressionengines=none -R server -p $HGPORT -d --pid-file hg.pid
32 $ hg serve --config server.compressionengines=none -R server -p $HGPORT -d --pid-file hg.pid
33 $ cat hg.pid > $DAEMON_PIDS
33 $ cat hg.pid > $DAEMON_PIDS
34 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none$' > /dev/null
34 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none$' > /dev/null
35
35
36 $ killdaemons.py
36 $ killdaemons.py
37
37
38 Order of engines can also change
38 Order of engines can also change
39
39
40 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
40 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
41 $ cat hg.pid > $DAEMON_PIDS
41 $ cat hg.pid > $DAEMON_PIDS
42 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none,zlib$' > /dev/null
42 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none,zlib$' > /dev/null
43
43
44 $ killdaemons.py
44 $ killdaemons.py
45
45
46 Start a default server again
46 Start a default server again
47
47
48 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
48 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
49 $ cat hg.pid > $DAEMON_PIDS
49 $ cat hg.pid > $DAEMON_PIDS
50
50
51 Server should send application/mercurial-0.1 to clients if no Accept is used
51 Server should send application/mercurial-0.1 to clients if no Accept is used
52
52
53 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
53 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
54 200 Script output follows
54 200 Script output follows
55 content-type: application/mercurial-0.1
55 content-type: application/mercurial-0.1
56 date: $HTTP_DATE$
56 date: $HTTP_DATE$
57 server: testing stub value
57 server: testing stub value
58 transfer-encoding: chunked
58 transfer-encoding: chunked
59
59
60 Server should send application/mercurial-0.1 when client says it wants it
60 Server should send application/mercurial-0.1 when client says it wants it
61
61
62 $ get-with-headers.py --hgproto '0.1' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
62 $ get-with-headers.py --hgproto '0.1' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
63 200 Script output follows
63 200 Script output follows
64 content-type: application/mercurial-0.1
64 content-type: application/mercurial-0.1
65 date: $HTTP_DATE$
65 date: $HTTP_DATE$
66 server: testing stub value
66 server: testing stub value
67 transfer-encoding: chunked
67 transfer-encoding: chunked
68
68
69 Server should send application/mercurial-0.2 when client says it wants it
69 Server should send application/mercurial-0.2 when client says it wants it
70
70
71 $ get-with-headers.py --hgproto '0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
71 $ get-with-headers.py --hgproto '0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
72 200 Script output follows
72 200 Script output follows
73 content-type: application/mercurial-0.2
73 content-type: application/mercurial-0.2
74 date: $HTTP_DATE$
74 date: $HTTP_DATE$
75 server: testing stub value
75 server: testing stub value
76 transfer-encoding: chunked
76 transfer-encoding: chunked
77
77
78 $ get-with-headers.py --hgproto '0.1 0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
78 $ get-with-headers.py --hgproto '0.1 0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
79 200 Script output follows
79 200 Script output follows
80 content-type: application/mercurial-0.2
80 content-type: application/mercurial-0.2
81 date: $HTTP_DATE$
81 date: $HTTP_DATE$
82 server: testing stub value
82 server: testing stub value
83 transfer-encoding: chunked
83 transfer-encoding: chunked
84
84
85 Requesting a compression format that server doesn't support results will fall back to 0.1
85 Requesting a compression format that server doesn't support results will fall back to 0.1
86
86
87 $ get-with-headers.py --hgproto '0.2 comp=aa' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
87 $ get-with-headers.py --hgproto '0.2 comp=aa' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
88 200 Script output follows
88 200 Script output follows
89 content-type: application/mercurial-0.1
89 content-type: application/mercurial-0.1
90 date: $HTTP_DATE$
90 date: $HTTP_DATE$
91 server: testing stub value
91 server: testing stub value
92 transfer-encoding: chunked
92 transfer-encoding: chunked
93
93
94 #if zstd
94 #if zstd
95 zstd is used if available
95 zstd is used if available
96
96
97 $ get-with-headers.py --hgproto '0.2 comp=zstd' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
97 $ get-with-headers.py --hgproto '0.2 comp=zstd' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
98 $ f --size --hexdump --bytes 36 --sha1 resp
98 $ f --size --hexdump --bytes 36 --sha1 resp
99 resp: size=248, sha1=4d8d8f87fb82bd542ce52881fdc94f850748
99 resp: size=248, sha1=4d8d8f87fb82bd542ce52881fdc94f850748
100 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
100 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
101 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 73 74 64 |t follows...zstd|
101 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 73 74 64 |t follows...zstd|
102 0020: 28 b5 2f fd |(./.|
102 0020: 28 b5 2f fd |(./.|
103
103
104 #endif
104 #endif
105
105
106 application/mercurial-0.2 is not yet used on non-streaming responses
106 application/mercurial-0.2 is not yet used on non-streaming responses
107
107
108 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=heads' -
108 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=heads' -
109 200 Script output follows
109 200 Script output follows
110 content-length: 41
110 content-length: 41
111 content-type: application/mercurial-0.1
111 content-type: application/mercurial-0.1
112 date: $HTTP_DATE$
112 date: $HTTP_DATE$
113 server: testing stub value
113 server: testing stub value
114
114
115 e93700bd72895c5addab234c56d4024b487a362f
115 e93700bd72895c5addab234c56d4024b487a362f
116
116
117 Now test protocol preference usage
117 Now test protocol preference usage
118
118
119 $ killdaemons.py
119 $ killdaemons.py
120 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
120 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
121 $ cat hg.pid > $DAEMON_PIDS
121 $ cat hg.pid > $DAEMON_PIDS
122
122
123 No Accept will send 0.1+zlib, even though "none" is preferred b/c "none" isn't supported on 0.1
123 No Accept will send 0.1+zlib, even though "none" is preferred b/c "none" isn't supported on 0.1
124
124
125 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' Content-Type
125 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' Content-Type
126 200 Script output follows
126 200 Script output follows
127 content-type: application/mercurial-0.1
127 content-type: application/mercurial-0.1
128
128
129 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
129 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
130 $ f --size --hexdump --bytes 28 --sha1 resp
130 $ f --size --hexdump --bytes 28 --sha1 resp
131 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
131 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
132 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
132 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
133 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
133 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
134
134
135 Explicit 0.1 will send zlib because "none" isn't supported on 0.1
135 Explicit 0.1 will send zlib because "none" isn't supported on 0.1
136
136
137 $ get-with-headers.py --hgproto '0.1' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
137 $ get-with-headers.py --hgproto '0.1' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
138 $ f --size --hexdump --bytes 28 --sha1 resp
138 $ f --size --hexdump --bytes 28 --sha1 resp
139 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
139 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
140 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
140 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
141 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
141 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
142
142
143 0.2 with no compression will get "none" because that is server's preference
143 0.2 with no compression will get "none" because that is server's preference
144 (spec says ZL and UN are implicitly supported)
144 (spec says ZL and UN are implicitly supported)
145
145
146 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
146 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
147 $ f --size --hexdump --bytes 32 --sha1 resp
147 $ f --size --hexdump --bytes 32 --sha1 resp
148 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
148 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
149 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
149 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
150 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
150 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
151
151
152 Client receives server preference even if local order doesn't match
152 Client receives server preference even if local order doesn't match
153
153
154 $ get-with-headers.py --hgproto '0.2 comp=zlib,none' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
154 $ get-with-headers.py --hgproto '0.2 comp=zlib,none' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
155 $ f --size --hexdump --bytes 32 --sha1 resp
155 $ f --size --hexdump --bytes 32 --sha1 resp
156 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
156 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
157 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
157 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
158 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
158 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
159
159
160 Client receives only supported format even if not server preferred format
160 Client receives only supported format even if not server preferred format
161
161
162 $ get-with-headers.py --hgproto '0.2 comp=zlib' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
162 $ get-with-headers.py --hgproto '0.2 comp=zlib' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
163 $ f --size --hexdump --bytes 33 --sha1 resp
163 $ f --size --hexdump --bytes 33 --sha1 resp
164 resp: size=232, sha1=a1c727f0c9693ca15742a75c30419bc36
164 resp: size=232, sha1=a1c727f0c9693ca15742a75c30419bc36
165 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
165 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
166 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib|
166 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib|
167 0020: 78 |x|
167 0020: 78 |x|
168
168
169 $ killdaemons.py
169 $ killdaemons.py
170 $ cd ..
170 $ cd ..
171
171
172 Test listkeys for listing namespaces
172 Test listkeys for listing namespaces
173
173
174 $ hg init empty
174 $ hg init empty
175 $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid
175 $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid
176 $ cat hg.pid > $DAEMON_PIDS
176 $ cat hg.pid > $DAEMON_PIDS
177
177
178 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
178 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
179 > command listkeys
179 > command listkeys
180 > namespace namespaces
180 > namespace namespaces
181 > EOF
181 > EOF
182 s> GET /?cmd=capabilities HTTP/1.1\r\n
182 s> GET /?cmd=capabilities HTTP/1.1\r\n
183 s> Accept-Encoding: identity\r\n
183 s> Accept-Encoding: identity\r\n
184 s> accept: application/mercurial-0.1\r\n
184 s> accept: application/mercurial-0.1\r\n
185 s> host: $LOCALIP:$HGPORT\r\n (glob)
185 s> host: $LOCALIP:$HGPORT\r\n (glob)
186 s> user-agent: Mercurial debugwireproto\r\n
186 s> user-agent: Mercurial debugwireproto\r\n
187 s> \r\n
187 s> \r\n
188 s> makefile('rb', None)
188 s> makefile('rb', None)
189 s> HTTP/1.1 200 Script output follows\r\n
189 s> HTTP/1.1 200 Script output follows\r\n
190 s> Server: testing stub value\r\n
190 s> Server: testing stub value\r\n
191 s> Date: $HTTP_DATE$\r\n
191 s> Date: $HTTP_DATE$\r\n
192 s> Content-Type: application/mercurial-0.1\r\n
192 s> Content-Type: application/mercurial-0.1\r\n
193 s> Content-Length: *\r\n (glob)
193 s> Content-Length: *\r\n (glob)
194 s> \r\n
194 s> \r\n
195 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
195 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
196 sending listkeys command
196 sending listkeys command
197 s> GET /?cmd=listkeys HTTP/1.1\r\n
197 s> GET /?cmd=listkeys HTTP/1.1\r\n
198 s> Accept-Encoding: identity\r\n
198 s> Accept-Encoding: identity\r\n
199 s> vary: X-HgArg-1,X-HgProto-1\r\n
199 s> vary: X-HgArg-1,X-HgProto-1\r\n
200 s> x-hgarg-1: namespace=namespaces\r\n
200 s> x-hgarg-1: namespace=namespaces\r\n
201 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
201 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
202 s> accept: application/mercurial-0.1\r\n
202 s> accept: application/mercurial-0.1\r\n
203 s> host: $LOCALIP:$HGPORT\r\n (glob)
203 s> host: $LOCALIP:$HGPORT\r\n (glob)
204 s> user-agent: Mercurial debugwireproto\r\n
204 s> user-agent: Mercurial debugwireproto\r\n
205 s> \r\n
205 s> \r\n
206 s> makefile('rb', None)
206 s> makefile('rb', None)
207 s> HTTP/1.1 200 Script output follows\r\n
207 s> HTTP/1.1 200 Script output follows\r\n
208 s> Server: testing stub value\r\n
208 s> Server: testing stub value\r\n
209 s> Date: $HTTP_DATE$\r\n
209 s> Date: $HTTP_DATE$\r\n
210 s> Content-Type: application/mercurial-0.1\r\n
210 s> Content-Type: application/mercurial-0.1\r\n
211 s> Content-Length: 30\r\n
211 s> Content-Length: 30\r\n
212 s> \r\n
212 s> \r\n
213 s> bookmarks\t\n
213 s> bookmarks\t\n
214 s> namespaces\t\n
214 s> namespaces\t\n
215 s> phases\t
215 s> phases\t
216 response: {
216 response: {
217 b'bookmarks': b'',
217 b'bookmarks': b'',
218 b'namespaces': b'',
218 b'namespaces': b'',
219 b'phases': b''
219 b'phases': b''
220 }
220 }
221
221
222 Same thing, but with "httprequest" command
222 Same thing, but with "httprequest" command
223
223
224 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
224 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
225 > httprequest GET ?cmd=listkeys
225 > httprequest GET ?cmd=listkeys
226 > user-agent: test
226 > user-agent: test
227 > x-hgarg-1: namespace=namespaces
227 > x-hgarg-1: namespace=namespaces
228 > EOF
228 > EOF
229 using raw connection to peer
229 using raw connection to peer
230 s> GET /?cmd=listkeys HTTP/1.1\r\n
230 s> GET /?cmd=listkeys HTTP/1.1\r\n
231 s> Accept-Encoding: identity\r\n
231 s> Accept-Encoding: identity\r\n
232 s> user-agent: test\r\n
232 s> user-agent: test\r\n
233 s> x-hgarg-1: namespace=namespaces\r\n
233 s> x-hgarg-1: namespace=namespaces\r\n
234 s> host: $LOCALIP:$HGPORT\r\n (glob)
234 s> host: $LOCALIP:$HGPORT\r\n (glob)
235 s> \r\n
235 s> \r\n
236 s> makefile('rb', None)
236 s> makefile('rb', None)
237 s> HTTP/1.1 200 Script output follows\r\n
237 s> HTTP/1.1 200 Script output follows\r\n
238 s> Server: testing stub value\r\n
238 s> Server: testing stub value\r\n
239 s> Date: $HTTP_DATE$\r\n
239 s> Date: $HTTP_DATE$\r\n
240 s> Content-Type: application/mercurial-0.1\r\n
240 s> Content-Type: application/mercurial-0.1\r\n
241 s> Content-Length: 30\r\n
241 s> Content-Length: 30\r\n
242 s> \r\n
242 s> \r\n
243 s> bookmarks\t\n
243 s> bookmarks\t\n
244 s> namespaces\t\n
244 s> namespaces\t\n
245 s> phases\t
245 s> phases\t
246
246
247 Client with HTTPv2 enabled advertises that and gets old capabilities response from old server
247 Client with HTTPv2 enabled advertises that and gets old capabilities response from old server
248
248
249 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
249 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
250 > command heads
250 > command heads
251 > EOF
251 > EOF
252 s> GET /?cmd=capabilities HTTP/1.1\r\n
252 s> GET /?cmd=capabilities HTTP/1.1\r\n
253 s> Accept-Encoding: identity\r\n
253 s> Accept-Encoding: identity\r\n
254 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
254 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
255 s> x-hgproto-1: cbor\r\n
255 s> x-hgproto-1: cbor\r\n
256 s> x-hgupgrade-1: exp-http-v2-0001\r\n
256 s> x-hgupgrade-1: exp-http-v2-0001\r\n
257 s> accept: application/mercurial-0.1\r\n
257 s> accept: application/mercurial-0.1\r\n
258 s> host: $LOCALIP:$HGPORT\r\n (glob)
258 s> host: $LOCALIP:$HGPORT\r\n (glob)
259 s> user-agent: Mercurial debugwireproto\r\n
259 s> user-agent: Mercurial debugwireproto\r\n
260 s> \r\n
260 s> \r\n
261 s> makefile('rb', None)
261 s> makefile('rb', None)
262 s> HTTP/1.1 200 Script output follows\r\n
262 s> HTTP/1.1 200 Script output follows\r\n
263 s> Server: testing stub value\r\n
263 s> Server: testing stub value\r\n
264 s> Date: $HTTP_DATE$\r\n
264 s> Date: $HTTP_DATE$\r\n
265 s> Content-Type: application/mercurial-0.1\r\n
265 s> Content-Type: application/mercurial-0.1\r\n
266 s> Content-Length: *\r\n (glob)
266 s> Content-Length: *\r\n (glob)
267 s> \r\n
267 s> \r\n
268 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
268 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
269 sending heads command
269 sending heads command
270 s> GET /?cmd=heads HTTP/1.1\r\n
270 s> GET /?cmd=heads HTTP/1.1\r\n
271 s> Accept-Encoding: identity\r\n
271 s> Accept-Encoding: identity\r\n
272 s> vary: X-HgProto-1\r\n
272 s> vary: X-HgProto-1\r\n
273 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
273 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
274 s> accept: application/mercurial-0.1\r\n
274 s> accept: application/mercurial-0.1\r\n
275 s> host: $LOCALIP:$HGPORT\r\n (glob)
275 s> host: $LOCALIP:$HGPORT\r\n (glob)
276 s> user-agent: Mercurial debugwireproto\r\n
276 s> user-agent: Mercurial debugwireproto\r\n
277 s> \r\n
277 s> \r\n
278 s> makefile('rb', None)
278 s> makefile('rb', None)
279 s> HTTP/1.1 200 Script output follows\r\n
279 s> HTTP/1.1 200 Script output follows\r\n
280 s> Server: testing stub value\r\n
280 s> Server: testing stub value\r\n
281 s> Date: $HTTP_DATE$\r\n
281 s> Date: $HTTP_DATE$\r\n
282 s> Content-Type: application/mercurial-0.1\r\n
282 s> Content-Type: application/mercurial-0.1\r\n
283 s> Content-Length: 41\r\n
283 s> Content-Length: 41\r\n
284 s> \r\n
284 s> \r\n
285 s> 0000000000000000000000000000000000000000\n
285 s> 0000000000000000000000000000000000000000\n
286 response: [
286 response: [
287 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
287 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
288 ]
288 ]
289
289
290 $ killdaemons.py
290 $ killdaemons.py
291 $ enablehttpv2 empty
291 $ enablehttpv2 empty
292 $ hg --config server.compressionengines=zlib -R empty serve -p $HGPORT -d --pid-file hg.pid
292 $ hg --config server.compressionengines=zlib -R empty serve -p $HGPORT -d --pid-file hg.pid
293 $ cat hg.pid > $DAEMON_PIDS
293 $ cat hg.pid > $DAEMON_PIDS
294
294
295 Client with HTTPv2 enabled automatically upgrades if the server supports it
295 Client with HTTPv2 enabled automatically upgrades if the server supports it
296
296
297 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
297 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
298 > command heads
298 > command heads
299 > EOF
299 > EOF
300 s> GET /?cmd=capabilities HTTP/1.1\r\n
300 s> GET /?cmd=capabilities HTTP/1.1\r\n
301 s> Accept-Encoding: identity\r\n
301 s> Accept-Encoding: identity\r\n
302 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
302 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
303 s> x-hgproto-1: cbor\r\n
303 s> x-hgproto-1: cbor\r\n
304 s> x-hgupgrade-1: exp-http-v2-0001\r\n
304 s> x-hgupgrade-1: exp-http-v2-0001\r\n
305 s> accept: application/mercurial-0.1\r\n
305 s> accept: application/mercurial-0.1\r\n
306 s> host: $LOCALIP:$HGPORT\r\n (glob)
306 s> host: $LOCALIP:$HGPORT\r\n (glob)
307 s> user-agent: Mercurial debugwireproto\r\n
307 s> user-agent: Mercurial debugwireproto\r\n
308 s> \r\n
308 s> \r\n
309 s> makefile('rb', None)
309 s> makefile('rb', None)
310 s> HTTP/1.1 200 OK\r\n
310 s> HTTP/1.1 200 OK\r\n
311 s> Server: testing stub value\r\n
311 s> Server: testing stub value\r\n
312 s> Date: $HTTP_DATE$\r\n
312 s> Date: $HTTP_DATE$\r\n
313 s> Content-Type: application/mercurial-cbor\r\n
313 s> Content-Type: application/mercurial-cbor\r\n
314 s> Content-Length: *\r\n (glob)
314 s> Content-Length: *\r\n (glob)
315 s> \r\n
315 s> \r\n
316 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
316 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
317 sending heads command
317 sending heads command
318 s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n
318 s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n
319 s> Accept-Encoding: identity\r\n
319 s> Accept-Encoding: identity\r\n
320 s> accept: application/mercurial-exp-framing-0005\r\n
320 s> accept: application/mercurial-exp-framing-0005\r\n
321 s> content-type: application/mercurial-exp-framing-0005\r\n
321 s> content-type: application/mercurial-exp-framing-0005\r\n
322 s> content-length: 20\r\n
322 s> content-length: 20\r\n
323 s> host: $LOCALIP:$HGPORT\r\n (glob)
323 s> host: $LOCALIP:$HGPORT\r\n (glob)
324 s> user-agent: Mercurial debugwireproto\r\n
324 s> user-agent: Mercurial debugwireproto\r\n
325 s> \r\n
325 s> \r\n
326 s> \x0c\x00\x00\x01\x00\x01\x01\x11\xa1DnameEheads
326 s> \x0c\x00\x00\x01\x00\x01\x01\x11\xa1DnameEheads
327 s> makefile('rb', None)
327 s> makefile('rb', None)
328 s> HTTP/1.1 200 OK\r\n
328 s> HTTP/1.1 200 OK\r\n
329 s> Server: testing stub value\r\n
329 s> Server: testing stub value\r\n
330 s> Date: $HTTP_DATE$\r\n
330 s> Date: $HTTP_DATE$\r\n
331 s> Content-Type: application/mercurial-exp-framing-0005\r\n
331 s> Content-Type: application/mercurial-exp-framing-0005\r\n
332 s> Transfer-Encoding: chunked\r\n
332 s> Transfer-Encoding: chunked\r\n
333 s> \r\n
333 s> \r\n
334 s> 13\r\n
334 s> 13\r\n
335 s> \x0b\x00\x00\x01\x00\x02\x011
335 s> \x0b\x00\x00\x01\x00\x02\x011
336 s> \xa1FstatusBok
336 s> \xa1FstatusBok
337 s> \r\n
337 s> \r\n
338 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
338 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
339 s> 1e\r\n
339 s> 1e\r\n
340 s> \x16\x00\x00\x01\x00\x02\x001
340 s> \x16\x00\x00\x01\x00\x02\x001
341 s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
341 s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
342 s> \r\n
342 s> \r\n
343 received frame(size=22; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
343 received frame(size=22; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
344 s> 8\r\n
344 s> 8\r\n
345 s> \x00\x00\x00\x01\x00\x02\x002
345 s> \x00\x00\x00\x01\x00\x02\x002
346 s> \r\n
346 s> \r\n
347 s> 0\r\n
347 s> 0\r\n
348 s> \r\n
348 s> \r\n
349 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
349 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
350 response: [
350 response: [
351 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
351 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
352 ]
352 ]
353
353
354 $ killdaemons.py
354 $ killdaemons.py
355
355
356 HTTP client follows HTTP redirect on handshake to new repo
356 HTTP client follows HTTP redirect on handshake to new repo
357
357
358 $ cd $TESTTMP
358 $ cd $TESTTMP
359
359
360 $ hg init redirector
360 $ hg init redirector
361 $ hg init redirected
361 $ hg init redirected
362 $ cd redirected
362 $ cd redirected
363 $ touch foo
363 $ touch foo
364 $ hg -q commit -A -m initial
364 $ hg -q commit -A -m initial
365 $ cd ..
365 $ cd ..
366
366
367 $ cat > paths.conf << EOF
367 $ cat > paths.conf << EOF
368 > [paths]
368 > [paths]
369 > / = $TESTTMP/*
369 > / = $TESTTMP/*
370 > EOF
370 > EOF
371
371
372 $ cat > redirectext.py << EOF
372 $ cat > redirectext.py << EOF
373 > from mercurial import extensions, wireprotoserver
373 > from mercurial import extensions, wireprotoserver
374 > def wrappedcallhttp(orig, repo, req, res, proto, cmd):
374 > def wrappedcallhttp(orig, repo, req, res, proto, cmd):
375 > path = req.advertisedurl[len(req.advertisedbaseurl):]
375 > path = req.advertisedurl[len(req.advertisedbaseurl):]
376 > if not path.startswith(b'/redirector'):
376 > if not path.startswith(b'/redirector'):
377 > return orig(repo, req, res, proto, cmd)
377 > return orig(repo, req, res, proto, cmd)
378 > relpath = path[len(b'/redirector'):]
378 > relpath = path[len(b'/redirector'):]
379 > res.status = b'301 Redirect'
379 > res.status = b'301 Redirect'
380 > newurl = b'%s/redirected%s' % (req.baseurl, relpath)
380 > newurl = b'%s/redirected%s' % (req.baseurl, relpath)
381 > if not repo.ui.configbool('testing', 'redirectqs', True) and b'?' in newurl:
381 > if not repo.ui.configbool('testing', 'redirectqs', True) and b'?' in newurl:
382 > newurl = newurl[0:newurl.index(b'?')]
382 > newurl = newurl[0:newurl.index(b'?')]
383 > res.headers[b'Location'] = newurl
383 > res.headers[b'Location'] = newurl
384 > res.headers[b'Content-Type'] = b'text/plain'
384 > res.headers[b'Content-Type'] = b'text/plain'
385 > res.setbodybytes(b'redirected')
385 > res.setbodybytes(b'redirected')
386 > return True
386 > return True
387 >
387 >
388 > extensions.wrapfunction(wireprotoserver, '_callhttp', wrappedcallhttp)
388 > extensions.wrapfunction(wireprotoserver, '_callhttp', wrappedcallhttp)
389 > EOF
389 > EOF
390
390
391 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
391 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
392 > --config server.compressionengines=zlib \
392 > --config server.compressionengines=zlib \
393 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
393 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
394 $ cat hg.pid > $DAEMON_PIDS
394 $ cat hg.pid > $DAEMON_PIDS
395
395
396 Verify our HTTP 301 is served properly
396 Verify our HTTP 301 is served properly
397
397
398 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
398 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
399 > httprequest GET /redirector?cmd=capabilities
399 > httprequest GET /redirector?cmd=capabilities
400 > user-agent: test
400 > user-agent: test
401 > EOF
401 > EOF
402 using raw connection to peer
402 using raw connection to peer
403 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
403 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
404 s> Accept-Encoding: identity\r\n
404 s> Accept-Encoding: identity\r\n
405 s> user-agent: test\r\n
405 s> user-agent: test\r\n
406 s> host: $LOCALIP:$HGPORT\r\n (glob)
406 s> host: $LOCALIP:$HGPORT\r\n (glob)
407 s> \r\n
407 s> \r\n
408 s> makefile('rb', None)
408 s> makefile('rb', None)
409 s> HTTP/1.1 301 Redirect\r\n
409 s> HTTP/1.1 301 Redirect\r\n
410 s> Server: testing stub value\r\n
410 s> Server: testing stub value\r\n
411 s> Date: $HTTP_DATE$\r\n
411 s> Date: $HTTP_DATE$\r\n
412 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
412 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
413 s> Content-Type: text/plain\r\n
413 s> Content-Type: text/plain\r\n
414 s> Content-Length: 10\r\n
414 s> Content-Length: 10\r\n
415 s> \r\n
415 s> \r\n
416 s> redirected
416 s> redirected
417 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
417 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
418 s> Accept-Encoding: identity\r\n
418 s> Accept-Encoding: identity\r\n
419 s> user-agent: test\r\n
419 s> user-agent: test\r\n
420 s> host: $LOCALIP:$HGPORT\r\n (glob)
420 s> host: $LOCALIP:$HGPORT\r\n (glob)
421 s> \r\n
421 s> \r\n
422 s> makefile('rb', None)
422 s> makefile('rb', None)
423 s> HTTP/1.1 200 Script output follows\r\n
423 s> HTTP/1.1 200 Script output follows\r\n
424 s> Server: testing stub value\r\n
424 s> Server: testing stub value\r\n
425 s> Date: $HTTP_DATE$\r\n
425 s> Date: $HTTP_DATE$\r\n
426 s> Content-Type: application/mercurial-0.1\r\n
426 s> Content-Type: application/mercurial-0.1\r\n
427 s> Content-Length: 467\r\n
427 s> Content-Length: 467\r\n
428 s> \r\n
428 s> \r\n
429 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
429 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
430
430
431 Test with the HTTP peer
431 Test with the HTTP peer
432
432
433 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
433 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
434 > command heads
434 > command heads
435 > EOF
435 > EOF
436 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
436 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
437 s> Accept-Encoding: identity\r\n
437 s> Accept-Encoding: identity\r\n
438 s> accept: application/mercurial-0.1\r\n
438 s> accept: application/mercurial-0.1\r\n
439 s> host: $LOCALIP:$HGPORT\r\n (glob)
439 s> host: $LOCALIP:$HGPORT\r\n (glob)
440 s> user-agent: Mercurial debugwireproto\r\n
440 s> user-agent: Mercurial debugwireproto\r\n
441 s> \r\n
441 s> \r\n
442 s> makefile('rb', None)
442 s> makefile('rb', None)
443 s> HTTP/1.1 301 Redirect\r\n
443 s> HTTP/1.1 301 Redirect\r\n
444 s> Server: testing stub value\r\n
444 s> Server: testing stub value\r\n
445 s> Date: $HTTP_DATE$\r\n
445 s> Date: $HTTP_DATE$\r\n
446 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
446 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
447 s> Content-Type: text/plain\r\n
447 s> Content-Type: text/plain\r\n
448 s> Content-Length: 10\r\n
448 s> Content-Length: 10\r\n
449 s> \r\n
449 s> \r\n
450 s> redirected
450 s> redirected
451 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
451 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
452 s> Accept-Encoding: identity\r\n
452 s> Accept-Encoding: identity\r\n
453 s> accept: application/mercurial-0.1\r\n
453 s> accept: application/mercurial-0.1\r\n
454 s> host: $LOCALIP:$HGPORT\r\n (glob)
454 s> host: $LOCALIP:$HGPORT\r\n (glob)
455 s> user-agent: Mercurial debugwireproto\r\n
455 s> user-agent: Mercurial debugwireproto\r\n
456 s> \r\n
456 s> \r\n
457 s> makefile('rb', None)
457 s> makefile('rb', None)
458 s> HTTP/1.1 200 Script output follows\r\n
458 s> HTTP/1.1 200 Script output follows\r\n
459 s> Server: testing stub value\r\n
459 s> Server: testing stub value\r\n
460 s> Date: $HTTP_DATE$\r\n
460 s> Date: $HTTP_DATE$\r\n
461 s> Content-Type: application/mercurial-0.1\r\n
461 s> Content-Type: application/mercurial-0.1\r\n
462 s> Content-Length: 467\r\n
462 s> Content-Length: 467\r\n
463 s> \r\n
463 s> \r\n
464 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
464 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
465 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
465 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
466 sending heads command
466 sending heads command
467 s> GET /redirected?cmd=heads HTTP/1.1\r\n
467 s> GET /redirected?cmd=heads HTTP/1.1\r\n
468 s> Accept-Encoding: identity\r\n
468 s> Accept-Encoding: identity\r\n
469 s> vary: X-HgProto-1\r\n
469 s> vary: X-HgProto-1\r\n
470 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
470 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
471 s> accept: application/mercurial-0.1\r\n
471 s> accept: application/mercurial-0.1\r\n
472 s> host: $LOCALIP:$HGPORT\r\n (glob)
472 s> host: $LOCALIP:$HGPORT\r\n (glob)
473 s> user-agent: Mercurial debugwireproto\r\n
473 s> user-agent: Mercurial debugwireproto\r\n
474 s> \r\n
474 s> \r\n
475 s> makefile('rb', None)
475 s> makefile('rb', None)
476 s> HTTP/1.1 200 Script output follows\r\n
476 s> HTTP/1.1 200 Script output follows\r\n
477 s> Server: testing stub value\r\n
477 s> Server: testing stub value\r\n
478 s> Date: $HTTP_DATE$\r\n
478 s> Date: $HTTP_DATE$\r\n
479 s> Content-Type: application/mercurial-0.1\r\n
479 s> Content-Type: application/mercurial-0.1\r\n
480 s> Content-Length: 41\r\n
480 s> Content-Length: 41\r\n
481 s> \r\n
481 s> \r\n
482 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
482 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
483 response: [
483 response: [
484 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
484 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
485 ]
485 ]
486
486
487 $ killdaemons.py
487 $ killdaemons.py
488
488
489 Now test a variation where we strip the query string from the redirect URL.
489 Now test a variation where we strip the query string from the redirect URL.
490 (SCM Manager apparently did this and clients would recover from it)
490 (SCM Manager apparently did this and clients would recover from it)
491
491
492 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
492 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
493 > --config server.compressionengines=zlib \
493 > --config server.compressionengines=zlib \
494 > --config testing.redirectqs=false \
494 > --config testing.redirectqs=false \
495 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
495 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
496 $ cat hg.pid > $DAEMON_PIDS
496 $ cat hg.pid > $DAEMON_PIDS
497
497
498 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
498 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
499 > httprequest GET /redirector?cmd=capabilities
499 > httprequest GET /redirector?cmd=capabilities
500 > user-agent: test
500 > user-agent: test
501 > EOF
501 > EOF
502 using raw connection to peer
502 using raw connection to peer
503 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
503 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
504 s> Accept-Encoding: identity\r\n
504 s> Accept-Encoding: identity\r\n
505 s> user-agent: test\r\n
505 s> user-agent: test\r\n
506 s> host: $LOCALIP:$HGPORT\r\n (glob)
506 s> host: $LOCALIP:$HGPORT\r\n (glob)
507 s> \r\n
507 s> \r\n
508 s> makefile('rb', None)
508 s> makefile('rb', None)
509 s> HTTP/1.1 301 Redirect\r\n
509 s> HTTP/1.1 301 Redirect\r\n
510 s> Server: testing stub value\r\n
510 s> Server: testing stub value\r\n
511 s> Date: $HTTP_DATE$\r\n
511 s> Date: $HTTP_DATE$\r\n
512 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
512 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
513 s> Content-Type: text/plain\r\n
513 s> Content-Type: text/plain\r\n
514 s> Content-Length: 10\r\n
514 s> Content-Length: 10\r\n
515 s> \r\n
515 s> \r\n
516 s> redirected
516 s> redirected
517 s> GET /redirected HTTP/1.1\r\n
517 s> GET /redirected HTTP/1.1\r\n
518 s> Accept-Encoding: identity\r\n
518 s> Accept-Encoding: identity\r\n
519 s> user-agent: test\r\n
519 s> user-agent: test\r\n
520 s> host: $LOCALIP:$HGPORT\r\n (glob)
520 s> host: $LOCALIP:$HGPORT\r\n (glob)
521 s> \r\n
521 s> \r\n
522 s> makefile('rb', None)
522 s> makefile('rb', None)
523 s> HTTP/1.1 200 Script output follows\r\n
523 s> HTTP/1.1 200 Script output follows\r\n
524 s> Server: testing stub value\r\n
524 s> Server: testing stub value\r\n
525 s> Date: $HTTP_DATE$\r\n
525 s> Date: $HTTP_DATE$\r\n
526 s> ETag: W/"*"\r\n (glob)
526 s> ETag: W/"*"\r\n (glob)
527 s> Content-Type: text/html; charset=ascii\r\n
527 s> Content-Type: text/html; charset=ascii\r\n
528 s> Transfer-Encoding: chunked\r\n
528 s> Transfer-Encoding: chunked\r\n
529 s> \r\n
529 s> \r\n
530 s> 414\r\n
530 s> 414\r\n
531 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
531 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
532 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
532 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
533 s> <head>\n
533 s> <head>\n
534 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
534 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
535 s> <meta name="robots" content="index, nofollow" />\n
535 s> <meta name="robots" content="index, nofollow" />\n
536 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
536 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
537 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
537 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
538 s> \n
538 s> \n
539 s> <title>redirected: log</title>\n
539 s> <title>redirected: log</title>\n
540 s> <link rel="alternate" type="application/atom+xml"\n
540 s> <link rel="alternate" type="application/atom+xml"\n
541 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
541 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
542 s> <link rel="alternate" type="application/rss+xml"\n
542 s> <link rel="alternate" type="application/rss+xml"\n
543 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
543 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
544 s> </head>\n
544 s> </head>\n
545 s> <body>\n
545 s> <body>\n
546 s> \n
546 s> \n
547 s> <div class="container">\n
547 s> <div class="container">\n
548 s> <div class="menu">\n
548 s> <div class="menu">\n
549 s> <div class="logo">\n
549 s> <div class="logo">\n
550 s> <a href="https://mercurial-scm.org/">\n
550 s> <a href="https://mercurial-scm.org/">\n
551 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
551 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
552 s> </div>\n
552 s> </div>\n
553 s> <ul>\n
553 s> <ul>\n
554 s> <li class="active">log</li>\n
554 s> <li class="active">log</li>\n
555 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
555 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
556 s> <li><a href="/redirected/tags">tags</a></li>\n
556 s> <li><a href="/redirected/tags">tags</a></li>\n
557 s> <li><a href="
557 s> <li><a href="
558 s> \r\n
558 s> \r\n
559 s> 810\r\n
559 s> 810\r\n
560 s> /redirected/bookmarks">bookmarks</a></li>\n
560 s> /redirected/bookmarks">bookmarks</a></li>\n
561 s> <li><a href="/redirected/branches">branches</a></li>\n
561 s> <li><a href="/redirected/branches">branches</a></li>\n
562 s> </ul>\n
562 s> </ul>\n
563 s> <ul>\n
563 s> <ul>\n
564 s> <li><a href="/redirected/rev/tip">changeset</a></li>\n
564 s> <li><a href="/redirected/rev/tip">changeset</a></li>\n
565 s> <li><a href="/redirected/file/tip">browse</a></li>\n
565 s> <li><a href="/redirected/file/tip">browse</a></li>\n
566 s> </ul>\n
566 s> </ul>\n
567 s> <ul>\n
567 s> <ul>\n
568 s> \n
568 s> \n
569 s> </ul>\n
569 s> </ul>\n
570 s> <ul>\n
570 s> <ul>\n
571 s> <li><a href="/redirected/help">help</a></li>\n
571 s> <li><a href="/redirected/help">help</a></li>\n
572 s> </ul>\n
572 s> </ul>\n
573 s> <div class="atom-logo">\n
573 s> <div class="atom-logo">\n
574 s> <a href="/redirected/atom-log" title="subscribe to atom feed">\n
574 s> <a href="/redirected/atom-log" title="subscribe to atom feed">\n
575 s> <img class="atom-logo" src="/redirected/static/feed-icon-14x14.png" alt="atom feed" />\n
575 s> <img class="atom-logo" src="/redirected/static/feed-icon-14x14.png" alt="atom feed" />\n
576 s> </a>\n
576 s> </a>\n
577 s> </div>\n
577 s> </div>\n
578 s> </div>\n
578 s> </div>\n
579 s> \n
579 s> \n
580 s> <div class="main">\n
580 s> <div class="main">\n
581 s> <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/redirected">redirected</a> </h2>\n
581 s> <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/redirected">redirected</a> </h2>\n
582 s> <h3>log</h3>\n
582 s> <h3>log</h3>\n
583 s> \n
583 s> \n
584 s> \n
584 s> \n
585 s> <form class="search" action="/redirected/log">\n
585 s> <form class="search" action="/redirected/log">\n
586 s> \n
586 s> \n
587 s> <p><input name="rev" id="search1" type="text" size="30" value="" /></p>\n
587 s> <p><input name="rev" id="search1" type="text" size="30" value="" /></p>\n
588 s> <div id="hint">Find changesets by keywords (author, files, the commit message), revision\n
588 s> <div id="hint">Find changesets by keywords (author, files, the commit message), revision\n
589 s> number or hash, or <a href="/redirected/help/revsets">revset expression</a>.</div>\n
589 s> number or hash, or <a href="/redirected/help/revsets">revset expression</a>.</div>\n
590 s> </form>\n
590 s> </form>\n
591 s> \n
591 s> \n
592 s> <div class="navigate">\n
592 s> <div class="navigate">\n
593 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
593 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
594 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
594 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
595 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
595 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
596 s> </div>\n
596 s> </div>\n
597 s> \n
597 s> \n
598 s> <table class="bigtable">\n
598 s> <table class="bigtable">\n
599 s> <thead>\n
599 s> <thead>\n
600 s> <tr>\n
600 s> <tr>\n
601 s> <th class="age">age</th>\n
601 s> <th class="age">age</th>\n
602 s> <th class="author">author</th>\n
602 s> <th class="author">author</th>\n
603 s> <th class="description">description</th>\n
603 s> <th class="description">description</th>\n
604 s> </tr>\n
604 s> </tr>\n
605 s> </thead>\n
605 s> </thead>\n
606 s> <tbody class="stripes2">\n
606 s> <tbody class="stripes2">\n
607 s> <tr>\n
607 s> <tr>\n
608 s> <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>\n
608 s> <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>\n
609 s> <td class="author">test</td>\n
609 s> <td class="author">test</td>\n
610 s> <td class="description">\n
610 s> <td class="description">\n
611 s> <a href="/redirected/rev/96ee1d7354c4">initial</a>\n
611 s> <a href="/redirected/rev/96ee1d7354c4">initial</a>\n
612 s> <span class="phase">draft</span> <span class="branchhead">default</span> <span class="tag">tip</span> \n
612 s> <span class="phase">draft</span> <span class="branchhead">default</span> <span class="tag">tip</span> \n
613 s> </td>\n
613 s> </td>\n
614 s> </tr>\n
614 s> </tr>\n
615 s> \n
615 s> \n
616 s> </tbody>\n
616 s> </tbody>\n
617 s> </table>\n
617 s> </table>\n
618 s> \n
618 s> \n
619 s> <div class="navigate">\n
619 s> <div class="navigate">\n
620 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
620 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
621 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
621 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
622 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
622 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
623 s> </div>\n
623 s> </div>\n
624 s> \n
624 s> \n
625 s> <script type="text/javascript">\n
625 s> <script type="text/javascript">\n
626 s> ajaxScrollInit(\n
626 s> ajaxScrollInit(\n
627 s> \'/redirected/shortlog/%next%\',\n
627 s> \'/redirected/shortlog/%next%\',\n
628 s> \'\', <!-- NEXTHASH\n
628 s> \'\', <!-- NEXTHASH\n
629 s> function (htmlText) {
629 s> function (htmlText) {
630 s> \r\n
630 s> \r\n
631 s> 14a\r\n
631 s> 14a\r\n
632 s> \n
632 s> \n
633 s> var m = htmlText.match(/\'(\\w+)\', <!-- NEXTHASH/);\n
633 s> var m = htmlText.match(/\'(\\w+)\', <!-- NEXTHASH/);\n
634 s> return m ? m[1] : null;\n
634 s> return m ? m[1] : null;\n
635 s> },\n
635 s> },\n
636 s> \'.bigtable > tbody\',\n
636 s> \'.bigtable > tbody\',\n
637 s> \'<tr class="%class%">\\\n
637 s> \'<tr class="%class%">\\\n
638 s> <td colspan="3" style="text-align: center;">%text%</td>\\\n
638 s> <td colspan="3" style="text-align: center;">%text%</td>\\\n
639 s> </tr>\'\n
639 s> </tr>\'\n
640 s> );\n
640 s> );\n
641 s> </script>\n
641 s> </script>\n
642 s> \n
642 s> \n
643 s> </div>\n
643 s> </div>\n
644 s> </div>\n
644 s> </div>\n
645 s> \n
645 s> \n
646 s> \n
646 s> \n
647 s> \n
647 s> \n
648 s> </body>\n
648 s> </body>\n
649 s> </html>\n
649 s> </html>\n
650 s> \n
650 s> \n
651 s> \r\n
651 s> \r\n
652 s> 0\r\n
652 s> 0\r\n
653 s> \r\n
653 s> \r\n
654
654
655 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
655 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
656 > command heads
656 > command heads
657 > EOF
657 > EOF
658 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
658 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
659 s> Accept-Encoding: identity\r\n
659 s> Accept-Encoding: identity\r\n
660 s> accept: application/mercurial-0.1\r\n
660 s> accept: application/mercurial-0.1\r\n
661 s> host: $LOCALIP:$HGPORT\r\n (glob)
661 s> host: $LOCALIP:$HGPORT\r\n (glob)
662 s> user-agent: Mercurial debugwireproto\r\n
662 s> user-agent: Mercurial debugwireproto\r\n
663 s> \r\n
663 s> \r\n
664 s> makefile('rb', None)
664 s> makefile('rb', None)
665 s> HTTP/1.1 301 Redirect\r\n
665 s> HTTP/1.1 301 Redirect\r\n
666 s> Server: testing stub value\r\n
666 s> Server: testing stub value\r\n
667 s> Date: $HTTP_DATE$\r\n
667 s> Date: $HTTP_DATE$\r\n
668 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
668 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
669 s> Content-Type: text/plain\r\n
669 s> Content-Type: text/plain\r\n
670 s> Content-Length: 10\r\n
670 s> Content-Length: 10\r\n
671 s> \r\n
671 s> \r\n
672 s> redirected
672 s> redirected
673 s> GET /redirected HTTP/1.1\r\n
673 s> GET /redirected HTTP/1.1\r\n
674 s> Accept-Encoding: identity\r\n
674 s> Accept-Encoding: identity\r\n
675 s> accept: application/mercurial-0.1\r\n
675 s> accept: application/mercurial-0.1\r\n
676 s> host: $LOCALIP:$HGPORT\r\n (glob)
676 s> host: $LOCALIP:$HGPORT\r\n (glob)
677 s> user-agent: Mercurial debugwireproto\r\n
677 s> user-agent: Mercurial debugwireproto\r\n
678 s> \r\n
678 s> \r\n
679 s> makefile('rb', None)
679 s> makefile('rb', None)
680 s> HTTP/1.1 200 Script output follows\r\n
680 s> HTTP/1.1 200 Script output follows\r\n
681 s> Server: testing stub value\r\n
681 s> Server: testing stub value\r\n
682 s> Date: $HTTP_DATE$\r\n
682 s> Date: $HTTP_DATE$\r\n
683 s> ETag: W/"*"\r\n (glob)
683 s> ETag: W/"*"\r\n (glob)
684 s> Content-Type: text/html; charset=ascii\r\n
684 s> Content-Type: text/html; charset=ascii\r\n
685 s> Transfer-Encoding: chunked\r\n
685 s> Transfer-Encoding: chunked\r\n
686 s> \r\n
686 s> \r\n
687 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
687 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
688 s> 414\r\n
688 s> 414\r\n
689 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
689 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
690 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
690 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
691 s> <head>\n
691 s> <head>\n
692 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
692 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
693 s> <meta name="robots" content="index, nofollow" />\n
693 s> <meta name="robots" content="index, nofollow" />\n
694 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
694 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
695 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
695 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
696 s> \n
696 s> \n
697 s> <title>redirected: log</title>\n
697 s> <title>redirected: log</title>\n
698 s> <link rel="alternate" type="application/atom+xml"\n
698 s> <link rel="alternate" type="application/atom+xml"\n
699 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
699 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
700 s> <link rel="alternate" type="application/rss+xml"\n
700 s> <link rel="alternate" type="application/rss+xml"\n
701 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
701 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
702 s> </head>\n
702 s> </head>\n
703 s> <body>\n
703 s> <body>\n
704 s> \n
704 s> \n
705 s> <div class="container">\n
705 s> <div class="container">\n
706 s> <div class="menu">\n
706 s> <div class="menu">\n
707 s> <div class="logo">\n
707 s> <div class="logo">\n
708 s> <a href="https://mercurial-scm.org/">\n
708 s> <a href="https://mercurial-scm.org/">\n
709 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
709 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
710 s> </div>\n
710 s> </div>\n
711 s> <ul>\n
711 s> <ul>\n
712 s> <li class="active">log</li>\n
712 s> <li class="active">log</li>\n
713 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
713 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
714 s> <li><a href="/redirected/tags">tags</a
714 s> <li><a href="/redirected/tags">tags</a
715 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
715 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
716 s> Accept-Encoding: identity\r\n
716 s> Accept-Encoding: identity\r\n
717 s> accept: application/mercurial-0.1\r\n
717 s> accept: application/mercurial-0.1\r\n
718 s> host: $LOCALIP:$HGPORT\r\n (glob)
718 s> host: $LOCALIP:$HGPORT\r\n (glob)
719 s> user-agent: Mercurial debugwireproto\r\n
719 s> user-agent: Mercurial debugwireproto\r\n
720 s> \r\n
720 s> \r\n
721 s> makefile('rb', None)
721 s> makefile('rb', None)
722 s> HTTP/1.1 200 Script output follows\r\n
722 s> HTTP/1.1 200 Script output follows\r\n
723 s> Server: testing stub value\r\n
723 s> Server: testing stub value\r\n
724 s> Date: $HTTP_DATE$\r\n
724 s> Date: $HTTP_DATE$\r\n
725 s> Content-Type: application/mercurial-0.1\r\n
725 s> Content-Type: application/mercurial-0.1\r\n
726 s> Content-Length: 467\r\n
726 s> Content-Length: 467\r\n
727 s> \r\n
727 s> \r\n
728 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
728 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
729 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
729 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
730 sending heads command
730 sending heads command
731 s> GET /redirected?cmd=heads HTTP/1.1\r\n
731 s> GET /redirected?cmd=heads HTTP/1.1\r\n
732 s> Accept-Encoding: identity\r\n
732 s> Accept-Encoding: identity\r\n
733 s> vary: X-HgProto-1\r\n
733 s> vary: X-HgProto-1\r\n
734 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
734 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
735 s> accept: application/mercurial-0.1\r\n
735 s> accept: application/mercurial-0.1\r\n
736 s> host: $LOCALIP:$HGPORT\r\n (glob)
736 s> host: $LOCALIP:$HGPORT\r\n (glob)
737 s> user-agent: Mercurial debugwireproto\r\n
737 s> user-agent: Mercurial debugwireproto\r\n
738 s> \r\n
738 s> \r\n
739 s> makefile('rb', None)
739 s> makefile('rb', None)
740 s> HTTP/1.1 200 Script output follows\r\n
740 s> HTTP/1.1 200 Script output follows\r\n
741 s> Server: testing stub value\r\n
741 s> Server: testing stub value\r\n
742 s> Date: $HTTP_DATE$\r\n
742 s> Date: $HTTP_DATE$\r\n
743 s> Content-Type: application/mercurial-0.1\r\n
743 s> Content-Type: application/mercurial-0.1\r\n
744 s> Content-Length: 41\r\n
744 s> Content-Length: 41\r\n
745 s> \r\n
745 s> \r\n
746 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
746 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
747 response: [
747 response: [
748 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
748 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
749 ]
749 ]
@@ -1,536 +1,536
1 #require no-chg
1 #require no-chg
2
2
3 $ . $TESTDIR/wireprotohelpers.sh
3 $ . $TESTDIR/wireprotohelpers.sh
4
4
5 $ hg init server
5 $ hg init server
6
6
7 zstd isn't present in plain builds. Make tests easier by removing
7 zstd isn't present in plain builds. Make tests easier by removing
8 zstd from the equation.
8 zstd from the equation.
9
9
10 $ cat >> server/.hg/hgrc << EOF
10 $ cat >> server/.hg/hgrc << EOF
11 > [server]
11 > [server]
12 > compressionengines = zlib
12 > compressionengines = zlib
13 > EOF
13 > EOF
14
14
15 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
15 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
16 $ cat hg.pid > $DAEMON_PIDS
16 $ cat hg.pid > $DAEMON_PIDS
17
17
18 A normal capabilities request is serviced for version 1
18 A normal capabilities request is serviced for version 1
19
19
20 $ sendhttpraw << EOF
20 $ sendhttpraw << EOF
21 > httprequest GET ?cmd=capabilities
21 > httprequest GET ?cmd=capabilities
22 > user-agent: test
22 > user-agent: test
23 > EOF
23 > EOF
24 using raw connection to peer
24 using raw connection to peer
25 s> GET /?cmd=capabilities HTTP/1.1\r\n
25 s> GET /?cmd=capabilities HTTP/1.1\r\n
26 s> Accept-Encoding: identity\r\n
26 s> Accept-Encoding: identity\r\n
27 s> user-agent: test\r\n
27 s> user-agent: test\r\n
28 s> host: $LOCALIP:$HGPORT\r\n (glob)
28 s> host: $LOCALIP:$HGPORT\r\n (glob)
29 s> \r\n
29 s> \r\n
30 s> makefile('rb', None)
30 s> makefile('rb', None)
31 s> HTTP/1.1 200 Script output follows\r\n
31 s> HTTP/1.1 200 Script output follows\r\n
32 s> Server: testing stub value\r\n
32 s> Server: testing stub value\r\n
33 s> Date: $HTTP_DATE$\r\n
33 s> Date: $HTTP_DATE$\r\n
34 s> Content-Type: application/mercurial-0.1\r\n
34 s> Content-Type: application/mercurial-0.1\r\n
35 s> Content-Length: *\r\n (glob)
35 s> Content-Length: *\r\n (glob)
36 s> \r\n
36 s> \r\n
37 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
37 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
38
38
39 A proper request without the API server enabled returns the legacy response
39 A proper request without the API server enabled returns the legacy response
40
40
41 $ sendhttpraw << EOF
41 $ sendhttpraw << EOF
42 > httprequest GET ?cmd=capabilities
42 > httprequest GET ?cmd=capabilities
43 > user-agent: test
43 > user-agent: test
44 > x-hgupgrade-1: foo
44 > x-hgupgrade-1: foo
45 > x-hgproto-1: cbor
45 > x-hgproto-1: cbor
46 > EOF
46 > EOF
47 using raw connection to peer
47 using raw connection to peer
48 s> GET /?cmd=capabilities HTTP/1.1\r\n
48 s> GET /?cmd=capabilities HTTP/1.1\r\n
49 s> Accept-Encoding: identity\r\n
49 s> Accept-Encoding: identity\r\n
50 s> user-agent: test\r\n
50 s> user-agent: test\r\n
51 s> x-hgproto-1: cbor\r\n
51 s> x-hgproto-1: cbor\r\n
52 s> x-hgupgrade-1: foo\r\n
52 s> x-hgupgrade-1: foo\r\n
53 s> host: $LOCALIP:$HGPORT\r\n (glob)
53 s> host: $LOCALIP:$HGPORT\r\n (glob)
54 s> \r\n
54 s> \r\n
55 s> makefile('rb', None)
55 s> makefile('rb', None)
56 s> HTTP/1.1 200 Script output follows\r\n
56 s> HTTP/1.1 200 Script output follows\r\n
57 s> Server: testing stub value\r\n
57 s> Server: testing stub value\r\n
58 s> Date: $HTTP_DATE$\r\n
58 s> Date: $HTTP_DATE$\r\n
59 s> Content-Type: application/mercurial-0.1\r\n
59 s> Content-Type: application/mercurial-0.1\r\n
60 s> Content-Length: *\r\n (glob)
60 s> Content-Length: *\r\n (glob)
61 s> \r\n
61 s> \r\n
62 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
62 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
63
63
64 Restart with just API server enabled. This enables serving the new format.
64 Restart with just API server enabled. This enables serving the new format.
65
65
66 $ killdaemons.py
66 $ killdaemons.py
67 $ cat error.log
67 $ cat error.log
68
68
69 $ cat >> server/.hg/hgrc << EOF
69 $ cat >> server/.hg/hgrc << EOF
70 > [experimental]
70 > [experimental]
71 > web.apiserver = true
71 > web.apiserver = true
72 > EOF
72 > EOF
73
73
74 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
74 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
75 $ cat hg.pid > $DAEMON_PIDS
75 $ cat hg.pid > $DAEMON_PIDS
76
76
77 X-HgUpgrade-<N> without CBOR advertisement uses legacy response
77 X-HgUpgrade-<N> without CBOR advertisement uses legacy response
78
78
79 $ sendhttpraw << EOF
79 $ sendhttpraw << EOF
80 > httprequest GET ?cmd=capabilities
80 > httprequest GET ?cmd=capabilities
81 > user-agent: test
81 > user-agent: test
82 > x-hgupgrade-1: foo bar
82 > x-hgupgrade-1: foo bar
83 > EOF
83 > EOF
84 using raw connection to peer
84 using raw connection to peer
85 s> GET /?cmd=capabilities HTTP/1.1\r\n
85 s> GET /?cmd=capabilities HTTP/1.1\r\n
86 s> Accept-Encoding: identity\r\n
86 s> Accept-Encoding: identity\r\n
87 s> user-agent: test\r\n
87 s> user-agent: test\r\n
88 s> x-hgupgrade-1: foo bar\r\n
88 s> x-hgupgrade-1: foo bar\r\n
89 s> host: $LOCALIP:$HGPORT\r\n (glob)
89 s> host: $LOCALIP:$HGPORT\r\n (glob)
90 s> \r\n
90 s> \r\n
91 s> makefile('rb', None)
91 s> makefile('rb', None)
92 s> HTTP/1.1 200 Script output follows\r\n
92 s> HTTP/1.1 200 Script output follows\r\n
93 s> Server: testing stub value\r\n
93 s> Server: testing stub value\r\n
94 s> Date: $HTTP_DATE$\r\n
94 s> Date: $HTTP_DATE$\r\n
95 s> Content-Type: application/mercurial-0.1\r\n
95 s> Content-Type: application/mercurial-0.1\r\n
96 s> Content-Length: *\r\n (glob)
96 s> Content-Length: *\r\n (glob)
97 s> \r\n
97 s> \r\n
98 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
98 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
99
99
100 X-HgUpgrade-<N> without known serialization in X-HgProto-<N> uses legacy response
100 X-HgUpgrade-<N> without known serialization in X-HgProto-<N> uses legacy response
101
101
102 $ sendhttpraw << EOF
102 $ sendhttpraw << EOF
103 > httprequest GET ?cmd=capabilities
103 > httprequest GET ?cmd=capabilities
104 > user-agent: test
104 > user-agent: test
105 > x-hgupgrade-1: foo bar
105 > x-hgupgrade-1: foo bar
106 > x-hgproto-1: some value
106 > x-hgproto-1: some value
107 > EOF
107 > EOF
108 using raw connection to peer
108 using raw connection to peer
109 s> GET /?cmd=capabilities HTTP/1.1\r\n
109 s> GET /?cmd=capabilities HTTP/1.1\r\n
110 s> Accept-Encoding: identity\r\n
110 s> Accept-Encoding: identity\r\n
111 s> user-agent: test\r\n
111 s> user-agent: test\r\n
112 s> x-hgproto-1: some value\r\n
112 s> x-hgproto-1: some value\r\n
113 s> x-hgupgrade-1: foo bar\r\n
113 s> x-hgupgrade-1: foo bar\r\n
114 s> host: $LOCALIP:$HGPORT\r\n (glob)
114 s> host: $LOCALIP:$HGPORT\r\n (glob)
115 s> \r\n
115 s> \r\n
116 s> makefile('rb', None)
116 s> makefile('rb', None)
117 s> HTTP/1.1 200 Script output follows\r\n
117 s> HTTP/1.1 200 Script output follows\r\n
118 s> Server: testing stub value\r\n
118 s> Server: testing stub value\r\n
119 s> Date: $HTTP_DATE$\r\n
119 s> Date: $HTTP_DATE$\r\n
120 s> Content-Type: application/mercurial-0.1\r\n
120 s> Content-Type: application/mercurial-0.1\r\n
121 s> Content-Length: *\r\n (glob)
121 s> Content-Length: *\r\n (glob)
122 s> \r\n
122 s> \r\n
123 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
123 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
124
124
125 X-HgUpgrade-<N> + X-HgProto-<N> headers trigger new response format
125 X-HgUpgrade-<N> + X-HgProto-<N> headers trigger new response format
126
126
127 $ sendhttpraw << EOF
127 $ sendhttpraw << EOF
128 > httprequest GET ?cmd=capabilities
128 > httprequest GET ?cmd=capabilities
129 > user-agent: test
129 > user-agent: test
130 > x-hgupgrade-1: foo bar
130 > x-hgupgrade-1: foo bar
131 > x-hgproto-1: cbor
131 > x-hgproto-1: cbor
132 > EOF
132 > EOF
133 using raw connection to peer
133 using raw connection to peer
134 s> GET /?cmd=capabilities HTTP/1.1\r\n
134 s> GET /?cmd=capabilities HTTP/1.1\r\n
135 s> Accept-Encoding: identity\r\n
135 s> Accept-Encoding: identity\r\n
136 s> user-agent: test\r\n
136 s> user-agent: test\r\n
137 s> x-hgproto-1: cbor\r\n
137 s> x-hgproto-1: cbor\r\n
138 s> x-hgupgrade-1: foo bar\r\n
138 s> x-hgupgrade-1: foo bar\r\n
139 s> host: $LOCALIP:$HGPORT\r\n (glob)
139 s> host: $LOCALIP:$HGPORT\r\n (glob)
140 s> \r\n
140 s> \r\n
141 s> makefile('rb', None)
141 s> makefile('rb', None)
142 s> HTTP/1.1 200 OK\r\n
142 s> HTTP/1.1 200 OK\r\n
143 s> Server: testing stub value\r\n
143 s> Server: testing stub value\r\n
144 s> Date: $HTTP_DATE$\r\n
144 s> Date: $HTTP_DATE$\r\n
145 s> Content-Type: application/mercurial-cbor\r\n
145 s> Content-Type: application/mercurial-cbor\r\n
146 s> Content-Length: *\r\n (glob)
146 s> Content-Length: *\r\n (glob)
147 s> \r\n
147 s> \r\n
148 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
148 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
149 cbor> {
149 cbor> {
150 b'apibase': b'api/',
150 b'apibase': b'api/',
151 b'apis': {},
151 b'apis': {},
152 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
152 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
153 }
153 }
154
154
155 Restart server to enable HTTPv2
155 Restart server to enable HTTPv2
156
156
157 $ killdaemons.py
157 $ killdaemons.py
158 $ enablehttpv2 server
158 $ enablehttpv2 server
159 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
159 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
160 $ cat hg.pid > $DAEMON_PIDS
160 $ cat hg.pid > $DAEMON_PIDS
161
161
162 Only requested API services are returned
162 Only requested API services are returned
163
163
164 $ sendhttpraw << EOF
164 $ sendhttpraw << EOF
165 > httprequest GET ?cmd=capabilities
165 > httprequest GET ?cmd=capabilities
166 > user-agent: test
166 > user-agent: test
167 > x-hgupgrade-1: foo bar
167 > x-hgupgrade-1: foo bar
168 > x-hgproto-1: cbor
168 > x-hgproto-1: cbor
169 > EOF
169 > EOF
170 using raw connection to peer
170 using raw connection to peer
171 s> GET /?cmd=capabilities HTTP/1.1\r\n
171 s> GET /?cmd=capabilities HTTP/1.1\r\n
172 s> Accept-Encoding: identity\r\n
172 s> Accept-Encoding: identity\r\n
173 s> user-agent: test\r\n
173 s> user-agent: test\r\n
174 s> x-hgproto-1: cbor\r\n
174 s> x-hgproto-1: cbor\r\n
175 s> x-hgupgrade-1: foo bar\r\n
175 s> x-hgupgrade-1: foo bar\r\n
176 s> host: $LOCALIP:$HGPORT\r\n (glob)
176 s> host: $LOCALIP:$HGPORT\r\n (glob)
177 s> \r\n
177 s> \r\n
178 s> makefile('rb', None)
178 s> makefile('rb', None)
179 s> HTTP/1.1 200 OK\r\n
179 s> HTTP/1.1 200 OK\r\n
180 s> Server: testing stub value\r\n
180 s> Server: testing stub value\r\n
181 s> Date: $HTTP_DATE$\r\n
181 s> Date: $HTTP_DATE$\r\n
182 s> Content-Type: application/mercurial-cbor\r\n
182 s> Content-Type: application/mercurial-cbor\r\n
183 s> Content-Length: *\r\n (glob)
183 s> Content-Length: *\r\n (glob)
184 s> \r\n
184 s> \r\n
185 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
185 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
186 cbor> {
186 cbor> {
187 b'apibase': b'api/',
187 b'apibase': b'api/',
188 b'apis': {},
188 b'apis': {},
189 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
189 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
190 }
190 }
191
191
192 Request for HTTPv2 service returns information about it
192 Request for HTTPv2 service returns information about it
193
193
194 $ sendhttpraw << EOF
194 $ sendhttpraw << EOF
195 > httprequest GET ?cmd=capabilities
195 > httprequest GET ?cmd=capabilities
196 > user-agent: test
196 > user-agent: test
197 > x-hgupgrade-1: exp-http-v2-0001 foo bar
197 > x-hgupgrade-1: exp-http-v2-0001 foo bar
198 > x-hgproto-1: cbor
198 > x-hgproto-1: cbor
199 > EOF
199 > EOF
200 using raw connection to peer
200 using raw connection to peer
201 s> GET /?cmd=capabilities HTTP/1.1\r\n
201 s> GET /?cmd=capabilities HTTP/1.1\r\n
202 s> Accept-Encoding: identity\r\n
202 s> Accept-Encoding: identity\r\n
203 s> user-agent: test\r\n
203 s> user-agent: test\r\n
204 s> x-hgproto-1: cbor\r\n
204 s> x-hgproto-1: cbor\r\n
205 s> x-hgupgrade-1: exp-http-v2-0001 foo bar\r\n
205 s> x-hgupgrade-1: exp-http-v2-0001 foo bar\r\n
206 s> host: $LOCALIP:$HGPORT\r\n (glob)
206 s> host: $LOCALIP:$HGPORT\r\n (glob)
207 s> \r\n
207 s> \r\n
208 s> makefile('rb', None)
208 s> makefile('rb', None)
209 s> HTTP/1.1 200 OK\r\n
209 s> HTTP/1.1 200 OK\r\n
210 s> Server: testing stub value\r\n
210 s> Server: testing stub value\r\n
211 s> Date: $HTTP_DATE$\r\n
211 s> Date: $HTTP_DATE$\r\n
212 s> Content-Type: application/mercurial-cbor\r\n
212 s> Content-Type: application/mercurial-cbor\r\n
213 s> Content-Length: *\r\n (glob)
213 s> Content-Length: *\r\n (glob)
214 s> \r\n
214 s> \r\n
215 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
215 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
216 cbor> {
216 cbor> {
217 b'apibase': b'api/',
217 b'apibase': b'api/',
218 b'apis': {
218 b'apis': {
219 b'exp-http-v2-0001': {
219 b'exp-http-v2-0001': {
220 b'commands': {
220 b'commands': {
221 b'branchmap': {
221 b'branchmap': {
222 b'args': {},
222 b'args': {},
223 b'permissions': [
223 b'permissions': [
224 b'pull'
224 b'pull'
225 ]
225 ]
226 },
226 },
227 b'capabilities': {
227 b'capabilities': {
228 b'args': {},
228 b'args': {},
229 b'permissions': [
229 b'permissions': [
230 b'pull'
230 b'pull'
231 ]
231 ]
232 },
232 },
233 b'changesetdata': {
233 b'changesetdata': {
234 b'args': {
234 b'args': {
235 b'fields': set([
235 b'fields': set([
236 b'parents',
236 b'parents',
237 b'revision'
237 b'revision'
238 ]),
238 ]),
239 b'noderange': [
239 b'noderange': [
240 [
240 [
241 b'0123456...'
241 b'0123456...'
242 ],
242 ],
243 [
243 [
244 b'abcdef...'
244 b'abcdef...'
245 ]
245 ]
246 ],
246 ],
247 b'nodes': [
247 b'nodes': [
248 b'0123456...'
248 b'0123456...'
249 ]
249 ]
250 },
250 },
251 b'permissions': [
251 b'permissions': [
252 b'pull'
252 b'pull'
253 ]
253 ]
254 },
254 },
255 b'filedata': {
255 b'filedata': {
256 b'args': {
256 b'args': {
257 b'fields': [
257 b'fields': set([
258 b'parents',
258 b'parents',
259 b'revision'
259 b'revision'
260 ],
260 ]),
261 b'haveparents': True,
261 b'haveparents': True,
262 b'nodes': [
262 b'nodes': [
263 b'0123456...'
263 b'0123456...'
264 ],
264 ],
265 b'path': b'foo.txt'
265 b'path': b'foo.txt'
266 },
266 },
267 b'permissions': [
267 b'permissions': [
268 b'pull'
268 b'pull'
269 ]
269 ]
270 },
270 },
271 b'heads': {
271 b'heads': {
272 b'args': {
272 b'args': {
273 b'publiconly': False
273 b'publiconly': False
274 },
274 },
275 b'permissions': [
275 b'permissions': [
276 b'pull'
276 b'pull'
277 ]
277 ]
278 },
278 },
279 b'known': {
279 b'known': {
280 b'args': {
280 b'args': {
281 b'nodes': [
281 b'nodes': [
282 b'deadbeef'
282 b'deadbeef'
283 ]
283 ]
284 },
284 },
285 b'permissions': [
285 b'permissions': [
286 b'pull'
286 b'pull'
287 ]
287 ]
288 },
288 },
289 b'listkeys': {
289 b'listkeys': {
290 b'args': {
290 b'args': {
291 b'namespace': b'ns'
291 b'namespace': b'ns'
292 },
292 },
293 b'permissions': [
293 b'permissions': [
294 b'pull'
294 b'pull'
295 ]
295 ]
296 },
296 },
297 b'lookup': {
297 b'lookup': {
298 b'args': {
298 b'args': {
299 b'key': b'foo'
299 b'key': b'foo'
300 },
300 },
301 b'permissions': [
301 b'permissions': [
302 b'pull'
302 b'pull'
303 ]
303 ]
304 },
304 },
305 b'manifestdata': {
305 b'manifestdata': {
306 b'args': {
306 b'args': {
307 b'fields': [
307 b'fields': set([
308 b'parents',
308 b'parents',
309 b'revision'
309 b'revision'
310 ],
310 ]),
311 b'haveparents': True,
311 b'haveparents': True,
312 b'nodes': [
312 b'nodes': [
313 b'0123456...'
313 b'0123456...'
314 ],
314 ],
315 b'tree': b''
315 b'tree': b''
316 },
316 },
317 b'permissions': [
317 b'permissions': [
318 b'pull'
318 b'pull'
319 ]
319 ]
320 },
320 },
321 b'pushkey': {
321 b'pushkey': {
322 b'args': {
322 b'args': {
323 b'key': b'key',
323 b'key': b'key',
324 b'namespace': b'ns',
324 b'namespace': b'ns',
325 b'new': b'new',
325 b'new': b'new',
326 b'old': b'old'
326 b'old': b'old'
327 },
327 },
328 b'permissions': [
328 b'permissions': [
329 b'push'
329 b'push'
330 ]
330 ]
331 }
331 }
332 },
332 },
333 b'compression': [
333 b'compression': [
334 {
334 {
335 b'name': b'zlib'
335 b'name': b'zlib'
336 }
336 }
337 ],
337 ],
338 b'framingmediatypes': [
338 b'framingmediatypes': [
339 b'application/mercurial-exp-framing-0005'
339 b'application/mercurial-exp-framing-0005'
340 ],
340 ],
341 b'rawrepoformats': [
341 b'rawrepoformats': [
342 b'generaldelta',
342 b'generaldelta',
343 b'revlogv1'
343 b'revlogv1'
344 ]
344 ]
345 }
345 }
346 },
346 },
347 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
347 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
348 }
348 }
349
349
350 capabilities command returns expected info
350 capabilities command returns expected info
351
351
352 $ sendhttpv2peerhandshake << EOF
352 $ sendhttpv2peerhandshake << EOF
353 > command capabilities
353 > command capabilities
354 > EOF
354 > EOF
355 creating http peer for wire protocol version 2
355 creating http peer for wire protocol version 2
356 s> GET /?cmd=capabilities HTTP/1.1\r\n
356 s> GET /?cmd=capabilities HTTP/1.1\r\n
357 s> Accept-Encoding: identity\r\n
357 s> Accept-Encoding: identity\r\n
358 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
358 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
359 s> x-hgproto-1: cbor\r\n
359 s> x-hgproto-1: cbor\r\n
360 s> x-hgupgrade-1: exp-http-v2-0001\r\n
360 s> x-hgupgrade-1: exp-http-v2-0001\r\n
361 s> accept: application/mercurial-0.1\r\n
361 s> accept: application/mercurial-0.1\r\n
362 s> host: $LOCALIP:$HGPORT\r\n (glob)
362 s> host: $LOCALIP:$HGPORT\r\n (glob)
363 s> user-agent: Mercurial debugwireproto\r\n
363 s> user-agent: Mercurial debugwireproto\r\n
364 s> \r\n
364 s> \r\n
365 s> makefile('rb', None)
365 s> makefile('rb', None)
366 s> HTTP/1.1 200 OK\r\n
366 s> HTTP/1.1 200 OK\r\n
367 s> Server: testing stub value\r\n
367 s> Server: testing stub value\r\n
368 s> Date: $HTTP_DATE$\r\n
368 s> Date: $HTTP_DATE$\r\n
369 s> Content-Type: application/mercurial-cbor\r\n
369 s> Content-Type: application/mercurial-cbor\r\n
370 s> Content-Length: *\r\n (glob)
370 s> Content-Length: *\r\n (glob)
371 s> \r\n
371 s> \r\n
372 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
372 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
373 sending capabilities command
373 sending capabilities command
374 s> POST /api/exp-http-v2-0001/ro/capabilities HTTP/1.1\r\n
374 s> POST /api/exp-http-v2-0001/ro/capabilities HTTP/1.1\r\n
375 s> Accept-Encoding: identity\r\n
375 s> Accept-Encoding: identity\r\n
376 s> accept: application/mercurial-exp-framing-0005\r\n
376 s> accept: application/mercurial-exp-framing-0005\r\n
377 s> content-type: application/mercurial-exp-framing-0005\r\n
377 s> content-type: application/mercurial-exp-framing-0005\r\n
378 s> content-length: 27\r\n
378 s> content-length: 27\r\n
379 s> host: $LOCALIP:$HGPORT\r\n (glob)
379 s> host: $LOCALIP:$HGPORT\r\n (glob)
380 s> user-agent: Mercurial debugwireproto\r\n
380 s> user-agent: Mercurial debugwireproto\r\n
381 s> \r\n
381 s> \r\n
382 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLcapabilities
382 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLcapabilities
383 s> makefile('rb', None)
383 s> makefile('rb', None)
384 s> HTTP/1.1 200 OK\r\n
384 s> HTTP/1.1 200 OK\r\n
385 s> Server: testing stub value\r\n
385 s> Server: testing stub value\r\n
386 s> Date: $HTTP_DATE$\r\n
386 s> Date: $HTTP_DATE$\r\n
387 s> Content-Type: application/mercurial-exp-framing-0005\r\n
387 s> Content-Type: application/mercurial-exp-framing-0005\r\n
388 s> Transfer-Encoding: chunked\r\n
388 s> Transfer-Encoding: chunked\r\n
389 s> \r\n
389 s> \r\n
390 s> 13\r\n
390 s> 13\r\n
391 s> \x0b\x00\x00\x01\x00\x02\x011
391 s> \x0b\x00\x00\x01\x00\x02\x011
392 s> \xa1FstatusBok
392 s> \xa1FstatusBok
393 s> \r\n
393 s> \r\n
394 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
394 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
395 s> 30e\r\n
395 s> 314\r\n
396 s> \x06\x03\x00\x01\x00\x02\x001
396 s> \x0c\x03\x00\x01\x00\x02\x001
397 s> \xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1
397 s> \xa4Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xd9\x01\x02\x82GparentsHrevisionInoderange\x82\x81J0123456...\x81Iabcdef...Enodes\x81J0123456...Kpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...DpathGfoo.txtKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xf5Enodes\x81J0123456...Dtree@Kpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyInamespaceBnsCnewCnewColdColdKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Nrawrepoformats\x82LgeneraldeltaHrevlogv1
398 s> \r\n
398 s> \r\n
399 received frame(size=774; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
399 received frame(size=780; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
400 s> 8\r\n
400 s> 8\r\n
401 s> \x00\x00\x00\x01\x00\x02\x002
401 s> \x00\x00\x00\x01\x00\x02\x002
402 s> \r\n
402 s> \r\n
403 s> 0\r\n
403 s> 0\r\n
404 s> \r\n
404 s> \r\n
405 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
405 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
406 response: gen[
406 response: gen[
407 {
407 {
408 b'commands': {
408 b'commands': {
409 b'branchmap': {
409 b'branchmap': {
410 b'args': {},
410 b'args': {},
411 b'permissions': [
411 b'permissions': [
412 b'pull'
412 b'pull'
413 ]
413 ]
414 },
414 },
415 b'capabilities': {
415 b'capabilities': {
416 b'args': {},
416 b'args': {},
417 b'permissions': [
417 b'permissions': [
418 b'pull'
418 b'pull'
419 ]
419 ]
420 },
420 },
421 b'changesetdata': {
421 b'changesetdata': {
422 b'args': {
422 b'args': {
423 b'fields': set([
423 b'fields': set([
424 b'parents',
424 b'parents',
425 b'revision'
425 b'revision'
426 ]),
426 ]),
427 b'noderange': [
427 b'noderange': [
428 [
428 [
429 b'0123456...'
429 b'0123456...'
430 ],
430 ],
431 [
431 [
432 b'abcdef...'
432 b'abcdef...'
433 ]
433 ]
434 ],
434 ],
435 b'nodes': [
435 b'nodes': [
436 b'0123456...'
436 b'0123456...'
437 ]
437 ]
438 },
438 },
439 b'permissions': [
439 b'permissions': [
440 b'pull'
440 b'pull'
441 ]
441 ]
442 },
442 },
443 b'filedata': {
443 b'filedata': {
444 b'args': {
444 b'args': {
445 b'fields': [
445 b'fields': set([
446 b'parents',
446 b'parents',
447 b'revision'
447 b'revision'
448 ],
448 ]),
449 b'haveparents': True,
449 b'haveparents': True,
450 b'nodes': [
450 b'nodes': [
451 b'0123456...'
451 b'0123456...'
452 ],
452 ],
453 b'path': b'foo.txt'
453 b'path': b'foo.txt'
454 },
454 },
455 b'permissions': [
455 b'permissions': [
456 b'pull'
456 b'pull'
457 ]
457 ]
458 },
458 },
459 b'heads': {
459 b'heads': {
460 b'args': {
460 b'args': {
461 b'publiconly': False
461 b'publiconly': False
462 },
462 },
463 b'permissions': [
463 b'permissions': [
464 b'pull'
464 b'pull'
465 ]
465 ]
466 },
466 },
467 b'known': {
467 b'known': {
468 b'args': {
468 b'args': {
469 b'nodes': [
469 b'nodes': [
470 b'deadbeef'
470 b'deadbeef'
471 ]
471 ]
472 },
472 },
473 b'permissions': [
473 b'permissions': [
474 b'pull'
474 b'pull'
475 ]
475 ]
476 },
476 },
477 b'listkeys': {
477 b'listkeys': {
478 b'args': {
478 b'args': {
479 b'namespace': b'ns'
479 b'namespace': b'ns'
480 },
480 },
481 b'permissions': [
481 b'permissions': [
482 b'pull'
482 b'pull'
483 ]
483 ]
484 },
484 },
485 b'lookup': {
485 b'lookup': {
486 b'args': {
486 b'args': {
487 b'key': b'foo'
487 b'key': b'foo'
488 },
488 },
489 b'permissions': [
489 b'permissions': [
490 b'pull'
490 b'pull'
491 ]
491 ]
492 },
492 },
493 b'manifestdata': {
493 b'manifestdata': {
494 b'args': {
494 b'args': {
495 b'fields': [
495 b'fields': set([
496 b'parents',
496 b'parents',
497 b'revision'
497 b'revision'
498 ],
498 ]),
499 b'haveparents': True,
499 b'haveparents': True,
500 b'nodes': [
500 b'nodes': [
501 b'0123456...'
501 b'0123456...'
502 ],
502 ],
503 b'tree': b''
503 b'tree': b''
504 },
504 },
505 b'permissions': [
505 b'permissions': [
506 b'pull'
506 b'pull'
507 ]
507 ]
508 },
508 },
509 b'pushkey': {
509 b'pushkey': {
510 b'args': {
510 b'args': {
511 b'key': b'key',
511 b'key': b'key',
512 b'namespace': b'ns',
512 b'namespace': b'ns',
513 b'new': b'new',
513 b'new': b'new',
514 b'old': b'old'
514 b'old': b'old'
515 },
515 },
516 b'permissions': [
516 b'permissions': [
517 b'push'
517 b'push'
518 ]
518 ]
519 }
519 }
520 },
520 },
521 b'compression': [
521 b'compression': [
522 {
522 {
523 b'name': b'zlib'
523 b'name': b'zlib'
524 }
524 }
525 ],
525 ],
526 b'framingmediatypes': [
526 b'framingmediatypes': [
527 b'application/mercurial-exp-framing-0005'
527 b'application/mercurial-exp-framing-0005'
528 ],
528 ],
529 b'rawrepoformats': [
529 b'rawrepoformats': [
530 b'generaldelta',
530 b'generaldelta',
531 b'revlogv1'
531 b'revlogv1'
532 ]
532 ]
533 }
533 }
534 ]
534 ]
535
535
536 $ cat error.log
536 $ cat error.log
@@ -1,604 +1,604
1 $ . $TESTDIR/wireprotohelpers.sh
1 $ . $TESTDIR/wireprotohelpers.sh
2
2
3 $ hg init server
3 $ hg init server
4 $ enablehttpv2 server
4 $ enablehttpv2 server
5 $ cd server
5 $ cd server
6 $ echo a0 > a
6 $ echo a0 > a
7 $ echo b0 > b
7 $ echo b0 > b
8 $ mkdir -p dir0/child0 dir0/child1 dir1
8 $ mkdir -p dir0/child0 dir0/child1 dir1
9 $ echo c0 > dir0/c
9 $ echo c0 > dir0/c
10 $ echo d0 > dir0/d
10 $ echo d0 > dir0/d
11 $ echo e0 > dir0/child0/e
11 $ echo e0 > dir0/child0/e
12 $ echo f0 > dir0/child1/f
12 $ echo f0 > dir0/child1/f
13 $ hg -q commit -A -m 'commit 0'
13 $ hg -q commit -A -m 'commit 0'
14
14
15 $ echo a1 > a
15 $ echo a1 > a
16 $ echo d1 > dir0/d
16 $ echo d1 > dir0/d
17 $ hg commit -m 'commit 1'
17 $ hg commit -m 'commit 1'
18 $ echo f0 > dir0/child1/f
18 $ echo f0 > dir0/child1/f
19 $ hg commit -m 'commit 2'
19 $ hg commit -m 'commit 2'
20 nothing changed
20 nothing changed
21 [1]
21 [1]
22
22
23 $ hg -q up -r 0
23 $ hg -q up -r 0
24 $ echo a2 > a
24 $ echo a2 > a
25 $ hg commit -m 'commit 3'
25 $ hg commit -m 'commit 3'
26 created new head
26 created new head
27
27
28 $ hg log -G -T '{rev}:{node} {desc}\n'
28 $ hg log -G -T '{rev}:{node} {desc}\n'
29 @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
29 @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
30 |
30 |
31 | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
31 | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
32 |/
32 |/
33 o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
33 o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
34
34
35
35
36 $ hg --debug debugindex a
36 $ hg --debug debugindex a
37 rev linkrev nodeid p1 p2
37 rev linkrev nodeid p1 p2
38 0 0 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
38 0 0 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
39 1 1 9a38122997b3ac97be2a9aa2e556838341fdf2cc 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
39 1 1 9a38122997b3ac97be2a9aa2e556838341fdf2cc 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
40 2 2 0879345e39377229634b420c639454156726c6b6 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
40 2 2 0879345e39377229634b420c639454156726c6b6 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
41
41
42 $ hg --debug debugindex dir0/child0/e
42 $ hg --debug debugindex dir0/child0/e
43 rev linkrev nodeid p1 p2
43 rev linkrev nodeid p1 p2
44 0 0 bbba6c06b30f443d34ff841bc985c4d0827c6be4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
44 0 0 bbba6c06b30f443d34ff841bc985c4d0827c6be4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
45
45
46 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
46 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
47 $ cat hg.pid > $DAEMON_PIDS
47 $ cat hg.pid > $DAEMON_PIDS
48
48
49 Missing arguments is an error
49 Missing arguments is an error
50
50
51 $ sendhttpv2peer << EOF
51 $ sendhttpv2peer << EOF
52 > command filedata
52 > command filedata
53 > EOF
53 > EOF
54 creating http peer for wire protocol version 2
54 creating http peer for wire protocol version 2
55 sending filedata command
55 sending filedata command
56 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
56 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
57 s> Accept-Encoding: identity\r\n
57 s> Accept-Encoding: identity\r\n
58 s> accept: application/mercurial-exp-framing-0005\r\n
58 s> accept: application/mercurial-exp-framing-0005\r\n
59 s> content-type: application/mercurial-exp-framing-0005\r\n
59 s> content-type: application/mercurial-exp-framing-0005\r\n
60 s> content-length: 23\r\n
60 s> content-length: 23\r\n
61 s> host: $LOCALIP:$HGPORT\r\n (glob)
61 s> host: $LOCALIP:$HGPORT\r\n (glob)
62 s> user-agent: Mercurial debugwireproto\r\n
62 s> user-agent: Mercurial debugwireproto\r\n
63 s> \r\n
63 s> \r\n
64 s> \x0f\x00\x00\x01\x00\x01\x01\x11\xa1DnameHfiledata
64 s> \x0f\x00\x00\x01\x00\x01\x01\x11\xa1DnameHfiledata
65 s> makefile('rb', None)
65 s> makefile('rb', None)
66 s> HTTP/1.1 200 OK\r\n
66 s> HTTP/1.1 200 OK\r\n
67 s> Server: testing stub value\r\n
67 s> Server: testing stub value\r\n
68 s> Date: $HTTP_DATE$\r\n
68 s> Date: $HTTP_DATE$\r\n
69 s> Content-Type: application/mercurial-exp-framing-0005\r\n
69 s> Content-Type: application/mercurial-exp-framing-0005\r\n
70 s> Transfer-Encoding: chunked\r\n
70 s> Transfer-Encoding: chunked\r\n
71 s> \r\n
71 s> \r\n
72 s> 45\r\n
72 s> 4e\r\n
73 s> =\x00\x00\x01\x00\x02\x012
73 s> F\x00\x00\x01\x00\x02\x012
74 s> \xa2Eerror\xa1GmessageX\x1enodes argument must be definedFstatusEerror
74 s> \xa2Eerror\xa1GmessageX\'missing required arguments: nodes, pathFstatusEerror
75 s> \r\n
75 s> \r\n
76 received frame(size=61; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
76 received frame(size=70; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
77 s> 0\r\n
77 s> 0\r\n
78 s> \r\n
78 s> \r\n
79 abort: nodes argument must be defined!
79 abort: missing required arguments: nodes, path!
80 [255]
80 [255]
81
81
82 $ sendhttpv2peer << EOF
82 $ sendhttpv2peer << EOF
83 > command filedata
83 > command filedata
84 > nodes eval:[]
84 > nodes eval:[]
85 > EOF
85 > EOF
86 creating http peer for wire protocol version 2
86 creating http peer for wire protocol version 2
87 sending filedata command
87 sending filedata command
88 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
88 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
89 s> Accept-Encoding: identity\r\n
89 s> Accept-Encoding: identity\r\n
90 s> accept: application/mercurial-exp-framing-0005\r\n
90 s> accept: application/mercurial-exp-framing-0005\r\n
91 s> content-type: application/mercurial-exp-framing-0005\r\n
91 s> content-type: application/mercurial-exp-framing-0005\r\n
92 s> content-length: 36\r\n
92 s> content-length: 36\r\n
93 s> host: $LOCALIP:$HGPORT\r\n (glob)
93 s> host: $LOCALIP:$HGPORT\r\n (glob)
94 s> user-agent: Mercurial debugwireproto\r\n
94 s> user-agent: Mercurial debugwireproto\r\n
95 s> \r\n
95 s> \r\n
96 s> \x1c\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x80DnameHfiledata
96 s> \x1c\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x80DnameHfiledata
97 s> makefile('rb', None)
97 s> makefile('rb', None)
98 s> HTTP/1.1 200 OK\r\n
98 s> HTTP/1.1 200 OK\r\n
99 s> Server: testing stub value\r\n
99 s> Server: testing stub value\r\n
100 s> Date: $HTTP_DATE$\r\n
100 s> Date: $HTTP_DATE$\r\n
101 s> Content-Type: application/mercurial-exp-framing-0005\r\n
101 s> Content-Type: application/mercurial-exp-framing-0005\r\n
102 s> Transfer-Encoding: chunked\r\n
102 s> Transfer-Encoding: chunked\r\n
103 s> \r\n
103 s> \r\n
104 s> 44\r\n
104 s> 47\r\n
105 s> <\x00\x00\x01\x00\x02\x012
105 s> ?\x00\x00\x01\x00\x02\x012
106 s> \xa2Eerror\xa1GmessageX\x1dpath argument must be definedFstatusEerror
106 s> \xa2Eerror\xa1GmessageX missing required arguments: pathFstatusEerror
107 s> \r\n
107 s> \r\n
108 received frame(size=60; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
108 received frame(size=63; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
109 s> 0\r\n
109 s> 0\r\n
110 s> \r\n
110 s> \r\n
111 abort: path argument must be defined!
111 abort: missing required arguments: path!
112 [255]
112 [255]
113
113
114 Unknown node is an error
114 Unknown node is an error
115
115
116 $ sendhttpv2peer << EOF
116 $ sendhttpv2peer << EOF
117 > command filedata
117 > command filedata
118 > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
118 > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
119 > path eval:b'a'
119 > path eval:b'a'
120 > EOF
120 > EOF
121 creating http peer for wire protocol version 2
121 creating http peer for wire protocol version 2
122 sending filedata command
122 sending filedata command
123 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
123 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
124 s> Accept-Encoding: identity\r\n
124 s> Accept-Encoding: identity\r\n
125 s> accept: application/mercurial-exp-framing-0005\r\n
125 s> accept: application/mercurial-exp-framing-0005\r\n
126 s> content-type: application/mercurial-exp-framing-0005\r\n
126 s> content-type: application/mercurial-exp-framing-0005\r\n
127 s> content-length: 64\r\n
127 s> content-length: 64\r\n
128 s> host: $LOCALIP:$HGPORT\r\n (glob)
128 s> host: $LOCALIP:$HGPORT\r\n (glob)
129 s> user-agent: Mercurial debugwireproto\r\n
129 s> user-agent: Mercurial debugwireproto\r\n
130 s> \r\n
130 s> \r\n
131 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaDpathAaDnameHfiledata
131 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaDpathAaDnameHfiledata
132 s> makefile('rb', None)
132 s> makefile('rb', None)
133 s> HTTP/1.1 200 OK\r\n
133 s> HTTP/1.1 200 OK\r\n
134 s> Server: testing stub value\r\n
134 s> Server: testing stub value\r\n
135 s> Date: $HTTP_DATE$\r\n
135 s> Date: $HTTP_DATE$\r\n
136 s> Content-Type: application/mercurial-exp-framing-0005\r\n
136 s> Content-Type: application/mercurial-exp-framing-0005\r\n
137 s> Transfer-Encoding: chunked\r\n
137 s> Transfer-Encoding: chunked\r\n
138 s> \r\n
138 s> \r\n
139 s> 6b\r\n
139 s> 6b\r\n
140 s> c\x00\x00\x01\x00\x02\x012
140 s> c\x00\x00\x01\x00\x02\x012
141 s> \xa2Eerror\xa2Dargs\x81X(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGmessageUunknown file node: %sFstatusEerror
141 s> \xa2Eerror\xa2Dargs\x81X(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGmessageUunknown file node: %sFstatusEerror
142 s> \r\n
142 s> \r\n
143 received frame(size=99; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
143 received frame(size=99; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
144 s> 0\r\n
144 s> 0\r\n
145 s> \r\n
145 s> \r\n
146 abort: unknown file node: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
146 abort: unknown file node: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
147 [255]
147 [255]
148
148
149 Fetching a single revision returns just metadata by default
149 Fetching a single revision returns just metadata by default
150
150
151 $ sendhttpv2peer << EOF
151 $ sendhttpv2peer << EOF
152 > command filedata
152 > command filedata
153 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
153 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
154 > path eval:b'a'
154 > path eval:b'a'
155 > EOF
155 > EOF
156 creating http peer for wire protocol version 2
156 creating http peer for wire protocol version 2
157 sending filedata command
157 sending filedata command
158 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
158 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
159 s> Accept-Encoding: identity\r\n
159 s> Accept-Encoding: identity\r\n
160 s> accept: application/mercurial-exp-framing-0005\r\n
160 s> accept: application/mercurial-exp-framing-0005\r\n
161 s> content-type: application/mercurial-exp-framing-0005\r\n
161 s> content-type: application/mercurial-exp-framing-0005\r\n
162 s> content-length: 64\r\n
162 s> content-length: 64\r\n
163 s> host: $LOCALIP:$HGPORT\r\n (glob)
163 s> host: $LOCALIP:$HGPORT\r\n (glob)
164 s> user-agent: Mercurial debugwireproto\r\n
164 s> user-agent: Mercurial debugwireproto\r\n
165 s> \r\n
165 s> \r\n
166 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
166 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
167 s> makefile('rb', None)
167 s> makefile('rb', None)
168 s> HTTP/1.1 200 OK\r\n
168 s> HTTP/1.1 200 OK\r\n
169 s> Server: testing stub value\r\n
169 s> Server: testing stub value\r\n
170 s> Date: $HTTP_DATE$\r\n
170 s> Date: $HTTP_DATE$\r\n
171 s> Content-Type: application/mercurial-exp-framing-0005\r\n
171 s> Content-Type: application/mercurial-exp-framing-0005\r\n
172 s> Transfer-Encoding: chunked\r\n
172 s> Transfer-Encoding: chunked\r\n
173 s> \r\n
173 s> \r\n
174 s> 13\r\n
174 s> 13\r\n
175 s> \x0b\x00\x00\x01\x00\x02\x011
175 s> \x0b\x00\x00\x01\x00\x02\x011
176 s> \xa1FstatusBok
176 s> \xa1FstatusBok
177 s> \r\n
177 s> \r\n
178 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
178 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
179 s> 30\r\n
179 s> 30\r\n
180 s> (\x00\x00\x01\x00\x02\x001
180 s> (\x00\x00\x01\x00\x02\x001
181 s> \xa1Jtotalitems\x01\xa1DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc
181 s> \xa1Jtotalitems\x01\xa1DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc
182 s> \r\n
182 s> \r\n
183 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
183 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
184 s> 8\r\n
184 s> 8\r\n
185 s> \x00\x00\x00\x01\x00\x02\x002
185 s> \x00\x00\x00\x01\x00\x02\x002
186 s> \r\n
186 s> \r\n
187 s> 0\r\n
187 s> 0\r\n
188 s> \r\n
188 s> \r\n
189 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
189 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
190 response: gen[
190 response: gen[
191 {
191 {
192 b'totalitems': 1
192 b'totalitems': 1
193 },
193 },
194 {
194 {
195 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
195 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
196 }
196 }
197 ]
197 ]
198
198
199 Requesting parents works
199 Requesting parents works
200
200
201 $ sendhttpv2peer << EOF
201 $ sendhttpv2peer << EOF
202 > command filedata
202 > command filedata
203 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
203 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
204 > path eval:b'a'
204 > path eval:b'a'
205 > fields eval:[b'parents']
205 > fields eval:[b'parents']
206 > EOF
206 > EOF
207 creating http peer for wire protocol version 2
207 creating http peer for wire protocol version 2
208 sending filedata command
208 sending filedata command
209 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
209 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
210 s> Accept-Encoding: identity\r\n
210 s> Accept-Encoding: identity\r\n
211 s> accept: application/mercurial-exp-framing-0005\r\n
211 s> accept: application/mercurial-exp-framing-0005\r\n
212 s> content-type: application/mercurial-exp-framing-0005\r\n
212 s> content-type: application/mercurial-exp-framing-0005\r\n
213 s> content-length: 80\r\n
213 s> content-length: 80\r\n
214 s> host: $LOCALIP:$HGPORT\r\n (glob)
214 s> host: $LOCALIP:$HGPORT\r\n (glob)
215 s> user-agent: Mercurial debugwireproto\r\n
215 s> user-agent: Mercurial debugwireproto\r\n
216 s> \r\n
216 s> \r\n
217 s> H\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81GparentsEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
217 s> H\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81GparentsEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
218 s> makefile('rb', None)
218 s> makefile('rb', None)
219 s> HTTP/1.1 200 OK\r\n
219 s> HTTP/1.1 200 OK\r\n
220 s> Server: testing stub value\r\n
220 s> Server: testing stub value\r\n
221 s> Date: $HTTP_DATE$\r\n
221 s> Date: $HTTP_DATE$\r\n
222 s> Content-Type: application/mercurial-exp-framing-0005\r\n
222 s> Content-Type: application/mercurial-exp-framing-0005\r\n
223 s> Transfer-Encoding: chunked\r\n
223 s> Transfer-Encoding: chunked\r\n
224 s> \r\n
224 s> \r\n
225 s> 13\r\n
225 s> 13\r\n
226 s> \x0b\x00\x00\x01\x00\x02\x011
226 s> \x0b\x00\x00\x01\x00\x02\x011
227 s> \xa1FstatusBok
227 s> \xa1FstatusBok
228 s> \r\n
228 s> \r\n
229 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
229 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
230 s> 63\r\n
230 s> 63\r\n
231 s> [\x00\x00\x01\x00\x02\x001
231 s> [\x00\x00\x01\x00\x02\x001
232 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccGparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
232 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccGparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
233 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
233 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
234 s> \r\n
234 s> \r\n
235 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
235 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
236 s> 8\r\n
236 s> 8\r\n
237 s> \x00\x00\x00\x01\x00\x02\x002
237 s> \x00\x00\x00\x01\x00\x02\x002
238 s> \r\n
238 s> \r\n
239 s> 0\r\n
239 s> 0\r\n
240 s> \r\n
240 s> \r\n
241 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
241 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
242 response: gen[
242 response: gen[
243 {
243 {
244 b'totalitems': 1
244 b'totalitems': 1
245 },
245 },
246 {
246 {
247 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
247 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
248 b'parents': [
248 b'parents': [
249 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
249 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
250 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
250 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
251 ]
251 ]
252 }
252 }
253 ]
253 ]
254
254
255 Requesting revision data works
255 Requesting revision data works
256 (haveparents defaults to False, so fulltext is emitted)
256 (haveparents defaults to False, so fulltext is emitted)
257
257
258 $ sendhttpv2peer << EOF
258 $ sendhttpv2peer << EOF
259 > command filedata
259 > command filedata
260 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
260 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
261 > path eval:b'a'
261 > path eval:b'a'
262 > fields eval:[b'revision']
262 > fields eval:[b'revision']
263 > EOF
263 > EOF
264 creating http peer for wire protocol version 2
264 creating http peer for wire protocol version 2
265 sending filedata command
265 sending filedata command
266 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
266 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
267 s> Accept-Encoding: identity\r\n
267 s> Accept-Encoding: identity\r\n
268 s> accept: application/mercurial-exp-framing-0005\r\n
268 s> accept: application/mercurial-exp-framing-0005\r\n
269 s> content-type: application/mercurial-exp-framing-0005\r\n
269 s> content-type: application/mercurial-exp-framing-0005\r\n
270 s> content-length: 81\r\n
270 s> content-length: 81\r\n
271 s> host: $LOCALIP:$HGPORT\r\n (glob)
271 s> host: $LOCALIP:$HGPORT\r\n (glob)
272 s> user-agent: Mercurial debugwireproto\r\n
272 s> user-agent: Mercurial debugwireproto\r\n
273 s> \r\n
273 s> \r\n
274 s> I\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
274 s> I\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
275 s> makefile('rb', None)
275 s> makefile('rb', None)
276 s> HTTP/1.1 200 OK\r\n
276 s> HTTP/1.1 200 OK\r\n
277 s> Server: testing stub value\r\n
277 s> Server: testing stub value\r\n
278 s> Date: $HTTP_DATE$\r\n
278 s> Date: $HTTP_DATE$\r\n
279 s> Content-Type: application/mercurial-exp-framing-0005\r\n
279 s> Content-Type: application/mercurial-exp-framing-0005\r\n
280 s> Transfer-Encoding: chunked\r\n
280 s> Transfer-Encoding: chunked\r\n
281 s> \r\n
281 s> \r\n
282 s> 13\r\n
282 s> 13\r\n
283 s> \x0b\x00\x00\x01\x00\x02\x011
283 s> \x0b\x00\x00\x01\x00\x02\x011
284 s> \xa1FstatusBok
284 s> \xa1FstatusBok
285 s> \r\n
285 s> \r\n
286 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
286 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
287 s> 42\r\n
287 s> 42\r\n
288 s> :\x00\x00\x01\x00\x02\x001
288 s> :\x00\x00\x01\x00\x02\x001
289 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
289 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
290 s> \r\n
290 s> \r\n
291 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
291 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
292 s> 8\r\n
292 s> 8\r\n
293 s> \x00\x00\x00\x01\x00\x02\x002
293 s> \x00\x00\x00\x01\x00\x02\x002
294 s> \r\n
294 s> \r\n
295 s> 0\r\n
295 s> 0\r\n
296 s> \r\n
296 s> \r\n
297 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
297 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
298 response: gen[
298 response: gen[
299 {
299 {
300 b'totalitems': 1
300 b'totalitems': 1
301 },
301 },
302 {
302 {
303 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
303 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
304 b'revisionsize': 3
304 b'revisionsize': 3
305 },
305 },
306 b'a1\n'
306 b'a1\n'
307 ]
307 ]
308
308
309 haveparents=False should be same as above
309 haveparents=False should be same as above
310
310
311 $ sendhttpv2peer << EOF
311 $ sendhttpv2peer << EOF
312 > command filedata
312 > command filedata
313 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
313 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
314 > path eval:b'a'
314 > path eval:b'a'
315 > fields eval:[b'revision']
315 > fields eval:[b'revision']
316 > haveparents eval:False
316 > haveparents eval:False
317 > EOF
317 > EOF
318 creating http peer for wire protocol version 2
318 creating http peer for wire protocol version 2
319 sending filedata command
319 sending filedata command
320 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
320 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
321 s> Accept-Encoding: identity\r\n
321 s> Accept-Encoding: identity\r\n
322 s> accept: application/mercurial-exp-framing-0005\r\n
322 s> accept: application/mercurial-exp-framing-0005\r\n
323 s> content-type: application/mercurial-exp-framing-0005\r\n
323 s> content-type: application/mercurial-exp-framing-0005\r\n
324 s> content-length: 94\r\n
324 s> content-length: 94\r\n
325 s> host: $LOCALIP:$HGPORT\r\n (glob)
325 s> host: $LOCALIP:$HGPORT\r\n (glob)
326 s> user-agent: Mercurial debugwireproto\r\n
326 s> user-agent: Mercurial debugwireproto\r\n
327 s> \r\n
327 s> \r\n
328 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf4Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
328 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf4Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
329 s> makefile('rb', None)
329 s> makefile('rb', None)
330 s> HTTP/1.1 200 OK\r\n
330 s> HTTP/1.1 200 OK\r\n
331 s> Server: testing stub value\r\n
331 s> Server: testing stub value\r\n
332 s> Date: $HTTP_DATE$\r\n
332 s> Date: $HTTP_DATE$\r\n
333 s> Content-Type: application/mercurial-exp-framing-0005\r\n
333 s> Content-Type: application/mercurial-exp-framing-0005\r\n
334 s> Transfer-Encoding: chunked\r\n
334 s> Transfer-Encoding: chunked\r\n
335 s> \r\n
335 s> \r\n
336 s> 13\r\n
336 s> 13\r\n
337 s> \x0b\x00\x00\x01\x00\x02\x011
337 s> \x0b\x00\x00\x01\x00\x02\x011
338 s> \xa1FstatusBok
338 s> \xa1FstatusBok
339 s> \r\n
339 s> \r\n
340 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
340 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
341 s> 42\r\n
341 s> 42\r\n
342 s> :\x00\x00\x01\x00\x02\x001
342 s> :\x00\x00\x01\x00\x02\x001
343 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
343 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
344 s> \r\n
344 s> \r\n
345 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
345 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
346 s> 8\r\n
346 s> 8\r\n
347 s> \x00\x00\x00\x01\x00\x02\x002
347 s> \x00\x00\x00\x01\x00\x02\x002
348 s> \r\n
348 s> \r\n
349 s> 0\r\n
349 s> 0\r\n
350 s> \r\n
350 s> \r\n
351 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
351 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
352 response: gen[
352 response: gen[
353 {
353 {
354 b'totalitems': 1
354 b'totalitems': 1
355 },
355 },
356 {
356 {
357 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
357 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
358 b'revisionsize': 3
358 b'revisionsize': 3
359 },
359 },
360 b'a1\n'
360 b'a1\n'
361 ]
361 ]
362
362
363 haveparents=True should emit a delta
363 haveparents=True should emit a delta
364
364
365 $ sendhttpv2peer << EOF
365 $ sendhttpv2peer << EOF
366 > command filedata
366 > command filedata
367 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
367 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
368 > path eval:b'a'
368 > path eval:b'a'
369 > fields eval:[b'revision']
369 > fields eval:[b'revision']
370 > haveparents eval:True
370 > haveparents eval:True
371 > EOF
371 > EOF
372 creating http peer for wire protocol version 2
372 creating http peer for wire protocol version 2
373 sending filedata command
373 sending filedata command
374 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
374 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
375 s> Accept-Encoding: identity\r\n
375 s> Accept-Encoding: identity\r\n
376 s> accept: application/mercurial-exp-framing-0005\r\n
376 s> accept: application/mercurial-exp-framing-0005\r\n
377 s> content-type: application/mercurial-exp-framing-0005\r\n
377 s> content-type: application/mercurial-exp-framing-0005\r\n
378 s> content-length: 94\r\n
378 s> content-length: 94\r\n
379 s> host: $LOCALIP:$HGPORT\r\n (glob)
379 s> host: $LOCALIP:$HGPORT\r\n (glob)
380 s> user-agent: Mercurial debugwireproto\r\n
380 s> user-agent: Mercurial debugwireproto\r\n
381 s> \r\n
381 s> \r\n
382 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
382 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
383 s> makefile('rb', None)
383 s> makefile('rb', None)
384 s> HTTP/1.1 200 OK\r\n
384 s> HTTP/1.1 200 OK\r\n
385 s> Server: testing stub value\r\n
385 s> Server: testing stub value\r\n
386 s> Date: $HTTP_DATE$\r\n
386 s> Date: $HTTP_DATE$\r\n
387 s> Content-Type: application/mercurial-exp-framing-0005\r\n
387 s> Content-Type: application/mercurial-exp-framing-0005\r\n
388 s> Transfer-Encoding: chunked\r\n
388 s> Transfer-Encoding: chunked\r\n
389 s> \r\n
389 s> \r\n
390 s> 13\r\n
390 s> 13\r\n
391 s> \x0b\x00\x00\x01\x00\x02\x011
391 s> \x0b\x00\x00\x01\x00\x02\x011
392 s> \xa1FstatusBok
392 s> \xa1FstatusBok
393 s> \r\n
393 s> \r\n
394 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
394 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
395 s> 6e\r\n
395 s> 6e\r\n
396 s> f\x00\x00\x01\x00\x02\x001
396 s> f\x00\x00\x01\x00\x02\x001
397 s> \xa1Jtotalitems\x01\xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
397 s> \xa1Jtotalitems\x01\xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
398 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
398 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
399 s> \r\n
399 s> \r\n
400 received frame(size=102; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
400 received frame(size=102; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
401 s> 8\r\n
401 s> 8\r\n
402 s> \x00\x00\x00\x01\x00\x02\x002
402 s> \x00\x00\x00\x01\x00\x02\x002
403 s> \r\n
403 s> \r\n
404 s> 0\r\n
404 s> 0\r\n
405 s> \r\n
405 s> \r\n
406 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
406 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
407 response: gen[
407 response: gen[
408 {
408 {
409 b'totalitems': 1
409 b'totalitems': 1
410 },
410 },
411 {
411 {
412 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
412 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
413 b'deltasize': 15,
413 b'deltasize': 15,
414 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
414 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
415 },
415 },
416 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
416 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
417 ]
417 ]
418
418
419 Requesting multiple revisions works
419 Requesting multiple revisions works
420 (first revision is a fulltext since haveparents=False by default)
420 (first revision is a fulltext since haveparents=False by default)
421
421
422 $ sendhttpv2peer << EOF
422 $ sendhttpv2peer << EOF
423 > command filedata
423 > command filedata
424 > nodes eval:['\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda', '\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
424 > nodes eval:['\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda', '\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
425 > path eval:b'a'
425 > path eval:b'a'
426 > fields eval:[b'revision']
426 > fields eval:[b'revision']
427 > EOF
427 > EOF
428 creating http peer for wire protocol version 2
428 creating http peer for wire protocol version 2
429 sending filedata command
429 sending filedata command
430 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
430 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
431 s> Accept-Encoding: identity\r\n
431 s> Accept-Encoding: identity\r\n
432 s> accept: application/mercurial-exp-framing-0005\r\n
432 s> accept: application/mercurial-exp-framing-0005\r\n
433 s> content-type: application/mercurial-exp-framing-0005\r\n
433 s> content-type: application/mercurial-exp-framing-0005\r\n
434 s> content-length: 102\r\n
434 s> content-length: 102\r\n
435 s> host: $LOCALIP:$HGPORT\r\n (glob)
435 s> host: $LOCALIP:$HGPORT\r\n (glob)
436 s> user-agent: Mercurial debugwireproto\r\n
436 s> user-agent: Mercurial debugwireproto\r\n
437 s> \r\n
437 s> \r\n
438 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
438 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
439 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
439 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
440 s> makefile('rb', None)
440 s> makefile('rb', None)
441 s> HTTP/1.1 200 OK\r\n
441 s> HTTP/1.1 200 OK\r\n
442 s> Server: testing stub value\r\n
442 s> Server: testing stub value\r\n
443 s> Date: $HTTP_DATE$\r\n
443 s> Date: $HTTP_DATE$\r\n
444 s> Content-Type: application/mercurial-exp-framing-0005\r\n
444 s> Content-Type: application/mercurial-exp-framing-0005\r\n
445 s> Transfer-Encoding: chunked\r\n
445 s> Transfer-Encoding: chunked\r\n
446 s> \r\n
446 s> \r\n
447 s> 13\r\n
447 s> 13\r\n
448 s> \x0b\x00\x00\x01\x00\x02\x011
448 s> \x0b\x00\x00\x01\x00\x02\x011
449 s> \xa1FstatusBok
449 s> \xa1FstatusBok
450 s> \r\n
450 s> \r\n
451 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
451 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
452 s> 9b\r\n
452 s> 9b\r\n
453 s> \x93\x00\x00\x01\x00\x02\x001
453 s> \x93\x00\x00\x01\x00\x02\x001
454 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
454 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
455 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
455 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
456 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
456 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
457 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
457 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
458 s> \r\n
458 s> \r\n
459 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
459 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
460 s> 8\r\n
460 s> 8\r\n
461 s> \x00\x00\x00\x01\x00\x02\x002
461 s> \x00\x00\x00\x01\x00\x02\x002
462 s> \r\n
462 s> \r\n
463 s> 0\r\n
463 s> 0\r\n
464 s> \r\n
464 s> \r\n
465 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
465 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
466 response: gen[
466 response: gen[
467 {
467 {
468 b'totalitems': 2
468 b'totalitems': 2
469 },
469 },
470 {
470 {
471 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
471 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
472 b'revisionsize': 3
472 b'revisionsize': 3
473 },
473 },
474 b'a0\n',
474 b'a0\n',
475 {
475 {
476 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
476 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
477 b'deltasize': 15,
477 b'deltasize': 15,
478 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
478 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
479 },
479 },
480 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
480 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
481 ]
481 ]
482
482
483 Revisions are sorted by DAG order, parents first
483 Revisions are sorted by DAG order, parents first
484
484
485 $ sendhttpv2peer << EOF
485 $ sendhttpv2peer << EOF
486 > command filedata
486 > command filedata
487 > nodes eval:['\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc', '\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda']
487 > nodes eval:['\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc', '\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda']
488 > path eval:b'a'
488 > path eval:b'a'
489 > fields eval:[b'revision']
489 > fields eval:[b'revision']
490 > EOF
490 > EOF
491 creating http peer for wire protocol version 2
491 creating http peer for wire protocol version 2
492 sending filedata command
492 sending filedata command
493 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
493 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
494 s> Accept-Encoding: identity\r\n
494 s> Accept-Encoding: identity\r\n
495 s> accept: application/mercurial-exp-framing-0005\r\n
495 s> accept: application/mercurial-exp-framing-0005\r\n
496 s> content-type: application/mercurial-exp-framing-0005\r\n
496 s> content-type: application/mercurial-exp-framing-0005\r\n
497 s> content-length: 102\r\n
497 s> content-length: 102\r\n
498 s> host: $LOCALIP:$HGPORT\r\n (glob)
498 s> host: $LOCALIP:$HGPORT\r\n (glob)
499 s> user-agent: Mercurial debugwireproto\r\n
499 s> user-agent: Mercurial debugwireproto\r\n
500 s> \r\n
500 s> \r\n
501 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccT+N\xb0s\x19\xbf\xa0w\xa4\n
501 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccT+N\xb0s\x19\xbf\xa0w\xa4\n
502 s> /\x04\x916Y\xae\xf0\xdaB\xdaDpathAaDnameHfiledata
502 s> /\x04\x916Y\xae\xf0\xdaB\xdaDpathAaDnameHfiledata
503 s> makefile('rb', None)
503 s> makefile('rb', None)
504 s> HTTP/1.1 200 OK\r\n
504 s> HTTP/1.1 200 OK\r\n
505 s> Server: testing stub value\r\n
505 s> Server: testing stub value\r\n
506 s> Date: $HTTP_DATE$\r\n
506 s> Date: $HTTP_DATE$\r\n
507 s> Content-Type: application/mercurial-exp-framing-0005\r\n
507 s> Content-Type: application/mercurial-exp-framing-0005\r\n
508 s> Transfer-Encoding: chunked\r\n
508 s> Transfer-Encoding: chunked\r\n
509 s> \r\n
509 s> \r\n
510 s> 13\r\n
510 s> 13\r\n
511 s> \x0b\x00\x00\x01\x00\x02\x011
511 s> \x0b\x00\x00\x01\x00\x02\x011
512 s> \xa1FstatusBok
512 s> \xa1FstatusBok
513 s> \r\n
513 s> \r\n
514 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
514 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
515 s> 9b\r\n
515 s> 9b\r\n
516 s> \x93\x00\x00\x01\x00\x02\x001
516 s> \x93\x00\x00\x01\x00\x02\x001
517 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
517 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
518 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
518 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
519 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
519 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
520 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
520 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
521 s> \r\n
521 s> \r\n
522 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
522 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
523 s> 8\r\n
523 s> 8\r\n
524 s> \x00\x00\x00\x01\x00\x02\x002
524 s> \x00\x00\x00\x01\x00\x02\x002
525 s> \r\n
525 s> \r\n
526 s> 0\r\n
526 s> 0\r\n
527 s> \r\n
527 s> \r\n
528 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
528 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
529 response: gen[
529 response: gen[
530 {
530 {
531 b'totalitems': 2
531 b'totalitems': 2
532 },
532 },
533 {
533 {
534 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
534 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
535 b'revisionsize': 3
535 b'revisionsize': 3
536 },
536 },
537 b'a0\n',
537 b'a0\n',
538 {
538 {
539 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
539 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
540 b'deltasize': 15,
540 b'deltasize': 15,
541 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
541 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
542 },
542 },
543 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
543 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
544 ]
544 ]
545
545
546 Requesting parents and revision data works
546 Requesting parents and revision data works
547
547
548 $ sendhttpv2peer << EOF
548 $ sendhttpv2peer << EOF
549 > command filedata
549 > command filedata
550 > nodes eval:['\x08\x79\x34\x5e\x39\x37\x72\x29\x63\x4b\x42\x0c\x63\x94\x54\x15\x67\x26\xc6\xb6']
550 > nodes eval:['\x08\x79\x34\x5e\x39\x37\x72\x29\x63\x4b\x42\x0c\x63\x94\x54\x15\x67\x26\xc6\xb6']
551 > path eval:b'a'
551 > path eval:b'a'
552 > fields eval:[b'parents', b'revision']
552 > fields eval:[b'parents', b'revision']
553 > EOF
553 > EOF
554 creating http peer for wire protocol version 2
554 creating http peer for wire protocol version 2
555 sending filedata command
555 sending filedata command
556 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
556 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
557 s> Accept-Encoding: identity\r\n
557 s> Accept-Encoding: identity\r\n
558 s> accept: application/mercurial-exp-framing-0005\r\n
558 s> accept: application/mercurial-exp-framing-0005\r\n
559 s> content-type: application/mercurial-exp-framing-0005\r\n
559 s> content-type: application/mercurial-exp-framing-0005\r\n
560 s> content-length: 89\r\n
560 s> content-length: 89\r\n
561 s> host: $LOCALIP:$HGPORT\r\n (glob)
561 s> host: $LOCALIP:$HGPORT\r\n (glob)
562 s> user-agent: Mercurial debugwireproto\r\n
562 s> user-agent: Mercurial debugwireproto\r\n
563 s> \r\n
563 s> \r\n
564 s> Q\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x82GparentsHrevisionEnodes\x81T\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6DpathAaDnameHfiledata
564 s> Q\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x82GparentsHrevisionEnodes\x81T\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6DpathAaDnameHfiledata
565 s> makefile('rb', None)
565 s> makefile('rb', None)
566 s> HTTP/1.1 200 OK\r\n
566 s> HTTP/1.1 200 OK\r\n
567 s> Server: testing stub value\r\n
567 s> Server: testing stub value\r\n
568 s> Date: $HTTP_DATE$\r\n
568 s> Date: $HTTP_DATE$\r\n
569 s> Content-Type: application/mercurial-exp-framing-0005\r\n
569 s> Content-Type: application/mercurial-exp-framing-0005\r\n
570 s> Transfer-Encoding: chunked\r\n
570 s> Transfer-Encoding: chunked\r\n
571 s> \r\n
571 s> \r\n
572 s> 13\r\n
572 s> 13\r\n
573 s> \x0b\x00\x00\x01\x00\x02\x011
573 s> \x0b\x00\x00\x01\x00\x02\x011
574 s> \xa1FstatusBok
574 s> \xa1FstatusBok
575 s> \r\n
575 s> \r\n
576 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
576 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
577 s> 75\r\n
577 s> 75\r\n
578 s> m\x00\x00\x01\x00\x02\x001
578 s> m\x00\x00\x01\x00\x02\x001
579 s> \xa1Jtotalitems\x01\xa3DnodeT\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6Gparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
579 s> \xa1Jtotalitems\x01\xa3DnodeT\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6Gparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
580 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x03Ca2\n
580 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x03Ca2\n
581 s> \r\n
581 s> \r\n
582 received frame(size=109; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
582 received frame(size=109; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
583 s> 8\r\n
583 s> 8\r\n
584 s> \x00\x00\x00\x01\x00\x02\x002
584 s> \x00\x00\x00\x01\x00\x02\x002
585 s> \r\n
585 s> \r\n
586 s> 0\r\n
586 s> 0\r\n
587 s> \r\n
587 s> \r\n
588 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
588 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
589 response: gen[
589 response: gen[
590 {
590 {
591 b'totalitems': 1
591 b'totalitems': 1
592 },
592 },
593 {
593 {
594 b'node': b'\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6',
594 b'node': b'\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6',
595 b'parents': [
595 b'parents': [
596 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
596 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
597 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
597 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
598 ],
598 ],
599 b'revisionsize': 3
599 b'revisionsize': 3
600 },
600 },
601 b'a2\n'
601 b'a2\n'
602 ]
602 ]
603
603
604 $ cat error.log
604 $ cat error.log
@@ -1,694 +1,694
1 $ . $TESTDIR/wireprotohelpers.sh
1 $ . $TESTDIR/wireprotohelpers.sh
2
2
3 $ hg init server
3 $ hg init server
4 $ enablehttpv2 server
4 $ enablehttpv2 server
5 $ cd server
5 $ cd server
6 $ echo a0 > a
6 $ echo a0 > a
7 $ echo b0 > b
7 $ echo b0 > b
8 $ mkdir -p dir0/child0 dir0/child1 dir1
8 $ mkdir -p dir0/child0 dir0/child1 dir1
9 $ echo c0 > dir0/c
9 $ echo c0 > dir0/c
10 $ echo d0 > dir0/d
10 $ echo d0 > dir0/d
11 $ echo e0 > dir0/child0/e
11 $ echo e0 > dir0/child0/e
12 $ echo f0 > dir0/child1/f
12 $ echo f0 > dir0/child1/f
13 $ hg -q commit -A -m 'commit 0'
13 $ hg -q commit -A -m 'commit 0'
14
14
15 $ echo a1 > a
15 $ echo a1 > a
16 $ echo d1 > dir0/d
16 $ echo d1 > dir0/d
17 $ hg commit -m 'commit 1'
17 $ hg commit -m 'commit 1'
18 $ echo f0 > dir0/child1/f
18 $ echo f0 > dir0/child1/f
19 $ hg commit -m 'commit 2'
19 $ hg commit -m 'commit 2'
20 nothing changed
20 nothing changed
21 [1]
21 [1]
22
22
23 $ hg -q up -r 0
23 $ hg -q up -r 0
24 $ echo a2 > a
24 $ echo a2 > a
25 $ hg commit -m 'commit 3'
25 $ hg commit -m 'commit 3'
26 created new head
26 created new head
27
27
28 $ hg log -G -T '{rev}:{node} {desc}\n'
28 $ hg log -G -T '{rev}:{node} {desc}\n'
29 @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
29 @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
30 |
30 |
31 | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
31 | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
32 |/
32 |/
33 o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
33 o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
34
34
35
35
36 $ hg --debug debugindex -m
36 $ hg --debug debugindex -m
37 rev linkrev nodeid p1 p2
37 rev linkrev nodeid p1 p2
38 0 0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
38 0 0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
39 1 1 91e0bdbfb0dde0023fa063edc1445f207a22eac7 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
39 1 1 91e0bdbfb0dde0023fa063edc1445f207a22eac7 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
40 2 2 46a6721b5edaf0ea04b79a5cb3218854a4d2aba0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
40 2 2 46a6721b5edaf0ea04b79a5cb3218854a4d2aba0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
41
41
42 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
42 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
43 $ cat hg.pid > $DAEMON_PIDS
43 $ cat hg.pid > $DAEMON_PIDS
44
44
45 Missing arguments is an error
45 Missing arguments is an error
46
46
47 $ sendhttpv2peer << EOF
47 $ sendhttpv2peer << EOF
48 > command manifestdata
48 > command manifestdata
49 > EOF
49 > EOF
50 creating http peer for wire protocol version 2
50 creating http peer for wire protocol version 2
51 sending manifestdata command
51 sending manifestdata command
52 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
52 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
53 s> Accept-Encoding: identity\r\n
53 s> Accept-Encoding: identity\r\n
54 s> accept: application/mercurial-exp-framing-0005\r\n
54 s> accept: application/mercurial-exp-framing-0005\r\n
55 s> content-type: application/mercurial-exp-framing-0005\r\n
55 s> content-type: application/mercurial-exp-framing-0005\r\n
56 s> content-length: 27\r\n
56 s> content-length: 27\r\n
57 s> host: $LOCALIP:$HGPORT\r\n (glob)
57 s> host: $LOCALIP:$HGPORT\r\n (glob)
58 s> user-agent: Mercurial debugwireproto\r\n
58 s> user-agent: Mercurial debugwireproto\r\n
59 s> \r\n
59 s> \r\n
60 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLmanifestdata
60 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLmanifestdata
61 s> makefile('rb', None)
61 s> makefile('rb', None)
62 s> HTTP/1.1 200 OK\r\n
62 s> HTTP/1.1 200 OK\r\n
63 s> Server: testing stub value\r\n
63 s> Server: testing stub value\r\n
64 s> Date: $HTTP_DATE$\r\n
64 s> Date: $HTTP_DATE$\r\n
65 s> Content-Type: application/mercurial-exp-framing-0005\r\n
65 s> Content-Type: application/mercurial-exp-framing-0005\r\n
66 s> Transfer-Encoding: chunked\r\n
66 s> Transfer-Encoding: chunked\r\n
67 s> \r\n
67 s> \r\n
68 s> 45\r\n
68 s> 4e\r\n
69 s> =\x00\x00\x01\x00\x02\x012
69 s> F\x00\x00\x01\x00\x02\x012
70 s> \xa2Eerror\xa1GmessageX\x1enodes argument must be definedFstatusEerror
70 s> \xa2Eerror\xa1GmessageX\'missing required arguments: nodes, treeFstatusEerror
71 s> \r\n
71 s> \r\n
72 received frame(size=61; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
72 received frame(size=70; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
73 s> 0\r\n
73 s> 0\r\n
74 s> \r\n
74 s> \r\n
75 abort: nodes argument must be defined!
75 abort: missing required arguments: nodes, tree!
76 [255]
76 [255]
77
77
78 $ sendhttpv2peer << EOF
78 $ sendhttpv2peer << EOF
79 > command manifestdata
79 > command manifestdata
80 > nodes eval:[]
80 > nodes eval:[]
81 > EOF
81 > EOF
82 creating http peer for wire protocol version 2
82 creating http peer for wire protocol version 2
83 sending manifestdata command
83 sending manifestdata command
84 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
84 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
85 s> Accept-Encoding: identity\r\n
85 s> Accept-Encoding: identity\r\n
86 s> accept: application/mercurial-exp-framing-0005\r\n
86 s> accept: application/mercurial-exp-framing-0005\r\n
87 s> content-type: application/mercurial-exp-framing-0005\r\n
87 s> content-type: application/mercurial-exp-framing-0005\r\n
88 s> content-length: 40\r\n
88 s> content-length: 40\r\n
89 s> host: $LOCALIP:$HGPORT\r\n (glob)
89 s> host: $LOCALIP:$HGPORT\r\n (glob)
90 s> user-agent: Mercurial debugwireproto\r\n
90 s> user-agent: Mercurial debugwireproto\r\n
91 s> \r\n
91 s> \r\n
92 s> \x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x80DnameLmanifestdata
92 s> \x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x80DnameLmanifestdata
93 s> makefile('rb', None)
93 s> makefile('rb', None)
94 s> HTTP/1.1 200 OK\r\n
94 s> HTTP/1.1 200 OK\r\n
95 s> Server: testing stub value\r\n
95 s> Server: testing stub value\r\n
96 s> Date: $HTTP_DATE$\r\n
96 s> Date: $HTTP_DATE$\r\n
97 s> Content-Type: application/mercurial-exp-framing-0005\r\n
97 s> Content-Type: application/mercurial-exp-framing-0005\r\n
98 s> Transfer-Encoding: chunked\r\n
98 s> Transfer-Encoding: chunked\r\n
99 s> \r\n
99 s> \r\n
100 s> 44\r\n
100 s> 47\r\n
101 s> <\x00\x00\x01\x00\x02\x012
101 s> ?\x00\x00\x01\x00\x02\x012
102 s> \xa2Eerror\xa1GmessageX\x1dtree argument must be definedFstatusEerror
102 s> \xa2Eerror\xa1GmessageX missing required arguments: treeFstatusEerror
103 s> \r\n
103 s> \r\n
104 received frame(size=60; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
104 received frame(size=63; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
105 s> 0\r\n
105 s> 0\r\n
106 s> \r\n
106 s> \r\n
107 abort: tree argument must be defined!
107 abort: missing required arguments: tree!
108 [255]
108 [255]
109
109
110 Unknown node is an error
110 Unknown node is an error
111
111
112 $ sendhttpv2peer << EOF
112 $ sendhttpv2peer << EOF
113 > command manifestdata
113 > command manifestdata
114 > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
114 > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
115 > tree eval:b''
115 > tree eval:b''
116 > EOF
116 > EOF
117 creating http peer for wire protocol version 2
117 creating http peer for wire protocol version 2
118 sending manifestdata command
118 sending manifestdata command
119 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
119 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
120 s> Accept-Encoding: identity\r\n
120 s> Accept-Encoding: identity\r\n
121 s> accept: application/mercurial-exp-framing-0005\r\n
121 s> accept: application/mercurial-exp-framing-0005\r\n
122 s> content-type: application/mercurial-exp-framing-0005\r\n
122 s> content-type: application/mercurial-exp-framing-0005\r\n
123 s> content-length: 67\r\n
123 s> content-length: 67\r\n
124 s> host: $LOCALIP:$HGPORT\r\n (glob)
124 s> host: $LOCALIP:$HGPORT\r\n (glob)
125 s> user-agent: Mercurial debugwireproto\r\n
125 s> user-agent: Mercurial debugwireproto\r\n
126 s> \r\n
126 s> \r\n
127 s> ;\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaDtree@DnameLmanifestdata
127 s> ;\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaDtree@DnameLmanifestdata
128 s> makefile('rb', None)
128 s> makefile('rb', None)
129 s> HTTP/1.1 200 OK\r\n
129 s> HTTP/1.1 200 OK\r\n
130 s> Server: testing stub value\r\n
130 s> Server: testing stub value\r\n
131 s> Date: $HTTP_DATE$\r\n
131 s> Date: $HTTP_DATE$\r\n
132 s> Content-Type: application/mercurial-exp-framing-0005\r\n
132 s> Content-Type: application/mercurial-exp-framing-0005\r\n
133 s> Transfer-Encoding: chunked\r\n
133 s> Transfer-Encoding: chunked\r\n
134 s> \r\n
134 s> \r\n
135 s> 51\r\n
135 s> 51\r\n
136 s> I\x00\x00\x01\x00\x02\x012
136 s> I\x00\x00\x01\x00\x02\x012
137 s> \xa2Eerror\xa2Dargs\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaGmessagePunknown node: %sFstatusEerror
137 s> \xa2Eerror\xa2Dargs\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaGmessagePunknown node: %sFstatusEerror
138 s> \r\n
138 s> \r\n
139 received frame(size=73; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
139 received frame(size=73; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
140 s> 0\r\n
140 s> 0\r\n
141 s> \r\n
141 s> \r\n
142 abort: unknown node: \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa! (esc)
142 abort: unknown node: \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa! (esc)
143 [255]
143 [255]
144
144
145 Fetching a single revision returns just metadata by default
145 Fetching a single revision returns just metadata by default
146
146
147 $ sendhttpv2peer << EOF
147 $ sendhttpv2peer << EOF
148 > command manifestdata
148 > command manifestdata
149 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
149 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
150 > tree eval:b''
150 > tree eval:b''
151 > EOF
151 > EOF
152 creating http peer for wire protocol version 2
152 creating http peer for wire protocol version 2
153 sending manifestdata command
153 sending manifestdata command
154 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
154 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
155 s> Accept-Encoding: identity\r\n
155 s> Accept-Encoding: identity\r\n
156 s> accept: application/mercurial-exp-framing-0005\r\n
156 s> accept: application/mercurial-exp-framing-0005\r\n
157 s> content-type: application/mercurial-exp-framing-0005\r\n
157 s> content-type: application/mercurial-exp-framing-0005\r\n
158 s> content-length: 67\r\n
158 s> content-length: 67\r\n
159 s> host: $LOCALIP:$HGPORT\r\n (glob)
159 s> host: $LOCALIP:$HGPORT\r\n (glob)
160 s> user-agent: Mercurial debugwireproto\r\n
160 s> user-agent: Mercurial debugwireproto\r\n
161 s> \r\n
161 s> \r\n
162 s> ;\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
162 s> ;\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
163 s> makefile('rb', None)
163 s> makefile('rb', None)
164 s> HTTP/1.1 200 OK\r\n
164 s> HTTP/1.1 200 OK\r\n
165 s> Server: testing stub value\r\n
165 s> Server: testing stub value\r\n
166 s> Date: $HTTP_DATE$\r\n
166 s> Date: $HTTP_DATE$\r\n
167 s> Content-Type: application/mercurial-exp-framing-0005\r\n
167 s> Content-Type: application/mercurial-exp-framing-0005\r\n
168 s> Transfer-Encoding: chunked\r\n
168 s> Transfer-Encoding: chunked\r\n
169 s> \r\n
169 s> \r\n
170 s> 13\r\n
170 s> 13\r\n
171 s> \x0b\x00\x00\x01\x00\x02\x011
171 s> \x0b\x00\x00\x01\x00\x02\x011
172 s> \xa1FstatusBok
172 s> \xa1FstatusBok
173 s> \r\n
173 s> \r\n
174 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
174 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
175 s> 30\r\n
175 s> 30\r\n
176 s> (\x00\x00\x01\x00\x02\x001
176 s> (\x00\x00\x01\x00\x02\x001
177 s> \xa1Jtotalitems\x01\xa1DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0
177 s> \xa1Jtotalitems\x01\xa1DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0
178 s> \r\n
178 s> \r\n
179 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
179 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
180 s> 8\r\n
180 s> 8\r\n
181 s> \x00\x00\x00\x01\x00\x02\x002
181 s> \x00\x00\x00\x01\x00\x02\x002
182 s> \r\n
182 s> \r\n
183 s> 0\r\n
183 s> 0\r\n
184 s> \r\n
184 s> \r\n
185 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
185 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
186 response: gen[
186 response: gen[
187 {
187 {
188 b'totalitems': 1
188 b'totalitems': 1
189 },
189 },
190 {
190 {
191 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
191 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
192 }
192 }
193 ]
193 ]
194
194
195 Requesting parents works
195 Requesting parents works
196
196
197 $ sendhttpv2peer << EOF
197 $ sendhttpv2peer << EOF
198 > command manifestdata
198 > command manifestdata
199 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
199 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
200 > tree eval:b''
200 > tree eval:b''
201 > fields eval:[b'parents']
201 > fields eval:[b'parents']
202 > EOF
202 > EOF
203 creating http peer for wire protocol version 2
203 creating http peer for wire protocol version 2
204 sending manifestdata command
204 sending manifestdata command
205 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
205 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
206 s> Accept-Encoding: identity\r\n
206 s> Accept-Encoding: identity\r\n
207 s> accept: application/mercurial-exp-framing-0005\r\n
207 s> accept: application/mercurial-exp-framing-0005\r\n
208 s> content-type: application/mercurial-exp-framing-0005\r\n
208 s> content-type: application/mercurial-exp-framing-0005\r\n
209 s> content-length: 83\r\n
209 s> content-length: 83\r\n
210 s> host: $LOCALIP:$HGPORT\r\n (glob)
210 s> host: $LOCALIP:$HGPORT\r\n (glob)
211 s> user-agent: Mercurial debugwireproto\r\n
211 s> user-agent: Mercurial debugwireproto\r\n
212 s> \r\n
212 s> \r\n
213 s> K\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81GparentsEnodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
213 s> K\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81GparentsEnodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
214 s> makefile('rb', None)
214 s> makefile('rb', None)
215 s> HTTP/1.1 200 OK\r\n
215 s> HTTP/1.1 200 OK\r\n
216 s> Server: testing stub value\r\n
216 s> Server: testing stub value\r\n
217 s> Date: $HTTP_DATE$\r\n
217 s> Date: $HTTP_DATE$\r\n
218 s> Content-Type: application/mercurial-exp-framing-0005\r\n
218 s> Content-Type: application/mercurial-exp-framing-0005\r\n
219 s> Transfer-Encoding: chunked\r\n
219 s> Transfer-Encoding: chunked\r\n
220 s> \r\n
220 s> \r\n
221 s> 13\r\n
221 s> 13\r\n
222 s> \x0b\x00\x00\x01\x00\x02\x011
222 s> \x0b\x00\x00\x01\x00\x02\x011
223 s> \xa1FstatusBok
223 s> \xa1FstatusBok
224 s> \r\n
224 s> \r\n
225 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
225 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
226 s> 63\r\n
226 s> 63\r\n
227 s> [\x00\x00\x01\x00\x02\x001
227 s> [\x00\x00\x01\x00\x02\x001
228 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Gparents\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
228 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Gparents\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
229 s> \r\n
229 s> \r\n
230 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
230 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
231 s> 8\r\n
231 s> 8\r\n
232 s> \x00\x00\x00\x01\x00\x02\x002
232 s> \x00\x00\x00\x01\x00\x02\x002
233 s> \r\n
233 s> \r\n
234 s> 0\r\n
234 s> 0\r\n
235 s> \r\n
235 s> \r\n
236 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
236 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
237 response: gen[
237 response: gen[
238 {
238 {
239 b'totalitems': 1
239 b'totalitems': 1
240 },
240 },
241 {
241 {
242 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
242 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
243 b'parents': [
243 b'parents': [
244 b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
244 b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
245 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
245 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
246 ]
246 ]
247 }
247 }
248 ]
248 ]
249
249
250 Requesting revision data works
250 Requesting revision data works
251 (haveparents defaults to false, so fulltext is emitted)
251 (haveparents defaults to false, so fulltext is emitted)
252
252
253 $ sendhttpv2peer << EOF
253 $ sendhttpv2peer << EOF
254 > command manifestdata
254 > command manifestdata
255 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
255 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
256 > tree eval:b''
256 > tree eval:b''
257 > fields eval:[b'revision']
257 > fields eval:[b'revision']
258 > EOF
258 > EOF
259 creating http peer for wire protocol version 2
259 creating http peer for wire protocol version 2
260 sending manifestdata command
260 sending manifestdata command
261 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
261 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
262 s> Accept-Encoding: identity\r\n
262 s> Accept-Encoding: identity\r\n
263 s> accept: application/mercurial-exp-framing-0005\r\n
263 s> accept: application/mercurial-exp-framing-0005\r\n
264 s> content-type: application/mercurial-exp-framing-0005\r\n
264 s> content-type: application/mercurial-exp-framing-0005\r\n
265 s> content-length: 84\r\n
265 s> content-length: 84\r\n
266 s> host: $LOCALIP:$HGPORT\r\n (glob)
266 s> host: $LOCALIP:$HGPORT\r\n (glob)
267 s> user-agent: Mercurial debugwireproto\r\n
267 s> user-agent: Mercurial debugwireproto\r\n
268 s> \r\n
268 s> \r\n
269 s> L\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
269 s> L\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
270 s> makefile('rb', None)
270 s> makefile('rb', None)
271 s> HTTP/1.1 200 OK\r\n
271 s> HTTP/1.1 200 OK\r\n
272 s> Server: testing stub value\r\n
272 s> Server: testing stub value\r\n
273 s> Date: $HTTP_DATE$\r\n
273 s> Date: $HTTP_DATE$\r\n
274 s> Content-Type: application/mercurial-exp-framing-0005\r\n
274 s> Content-Type: application/mercurial-exp-framing-0005\r\n
275 s> Transfer-Encoding: chunked\r\n
275 s> Transfer-Encoding: chunked\r\n
276 s> \r\n
276 s> \r\n
277 s> 13\r\n
277 s> 13\r\n
278 s> \x0b\x00\x00\x01\x00\x02\x011
278 s> \x0b\x00\x00\x01\x00\x02\x011
279 s> \xa1FstatusBok
279 s> \xa1FstatusBok
280 s> \r\n
280 s> \r\n
281 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
281 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
282 s> 167\r\n
282 s> 167\r\n
283 s> _\x01\x00\x01\x00\x02\x001
283 s> _\x01\x00\x01\x00\x02\x001
284 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Lrevisionsize\x19\x01$Y\x01$a\x000879345e39377229634b420c639454156726c6b6\n
284 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Lrevisionsize\x19\x01$Y\x01$a\x000879345e39377229634b420c639454156726c6b6\n
285 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
285 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
286 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
286 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
287 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
287 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
288 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
288 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
289 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
289 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
290 s> \r\n
290 s> \r\n
291 received frame(size=351; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
291 received frame(size=351; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
292 s> 8\r\n
292 s> 8\r\n
293 s> \x00\x00\x00\x01\x00\x02\x002
293 s> \x00\x00\x00\x01\x00\x02\x002
294 s> \r\n
294 s> \r\n
295 s> 0\r\n
295 s> 0\r\n
296 s> \r\n
296 s> \r\n
297 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
297 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
298 response: gen[
298 response: gen[
299 {
299 {
300 b'totalitems': 1
300 b'totalitems': 1
301 },
301 },
302 {
302 {
303 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
303 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
304 b'revisionsize': 292
304 b'revisionsize': 292
305 },
305 },
306 b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
306 b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
307 ]
307 ]
308
308
309 haveparents=False yields same output
309 haveparents=False yields same output
310
310
311 $ sendhttpv2peer << EOF
311 $ sendhttpv2peer << EOF
312 > command manifestdata
312 > command manifestdata
313 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
313 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
314 > tree eval:b''
314 > tree eval:b''
315 > fields eval:[b'revision']
315 > fields eval:[b'revision']
316 > haveparents eval:False
316 > haveparents eval:False
317 > EOF
317 > EOF
318 creating http peer for wire protocol version 2
318 creating http peer for wire protocol version 2
319 sending manifestdata command
319 sending manifestdata command
320 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
320 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
321 s> Accept-Encoding: identity\r\n
321 s> Accept-Encoding: identity\r\n
322 s> accept: application/mercurial-exp-framing-0005\r\n
322 s> accept: application/mercurial-exp-framing-0005\r\n
323 s> content-type: application/mercurial-exp-framing-0005\r\n
323 s> content-type: application/mercurial-exp-framing-0005\r\n
324 s> content-length: 97\r\n
324 s> content-length: 97\r\n
325 s> host: $LOCALIP:$HGPORT\r\n (glob)
325 s> host: $LOCALIP:$HGPORT\r\n (glob)
326 s> user-agent: Mercurial debugwireproto\r\n
326 s> user-agent: Mercurial debugwireproto\r\n
327 s> \r\n
327 s> \r\n
328 s> Y\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf4Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
328 s> Y\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf4Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
329 s> makefile('rb', None)
329 s> makefile('rb', None)
330 s> HTTP/1.1 200 OK\r\n
330 s> HTTP/1.1 200 OK\r\n
331 s> Server: testing stub value\r\n
331 s> Server: testing stub value\r\n
332 s> Date: $HTTP_DATE$\r\n
332 s> Date: $HTTP_DATE$\r\n
333 s> Content-Type: application/mercurial-exp-framing-0005\r\n
333 s> Content-Type: application/mercurial-exp-framing-0005\r\n
334 s> Transfer-Encoding: chunked\r\n
334 s> Transfer-Encoding: chunked\r\n
335 s> \r\n
335 s> \r\n
336 s> 13\r\n
336 s> 13\r\n
337 s> \x0b\x00\x00\x01\x00\x02\x011
337 s> \x0b\x00\x00\x01\x00\x02\x011
338 s> \xa1FstatusBok
338 s> \xa1FstatusBok
339 s> \r\n
339 s> \r\n
340 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
340 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
341 s> 167\r\n
341 s> 167\r\n
342 s> _\x01\x00\x01\x00\x02\x001
342 s> _\x01\x00\x01\x00\x02\x001
343 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Lrevisionsize\x19\x01$Y\x01$a\x000879345e39377229634b420c639454156726c6b6\n
343 s> \xa1Jtotalitems\x01\xa2DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Lrevisionsize\x19\x01$Y\x01$a\x000879345e39377229634b420c639454156726c6b6\n
344 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
344 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
345 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
345 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
346 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
346 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
347 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
347 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
348 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
348 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
349 s> \r\n
349 s> \r\n
350 received frame(size=351; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
350 received frame(size=351; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
351 s> 8\r\n
351 s> 8\r\n
352 s> \x00\x00\x00\x01\x00\x02\x002
352 s> \x00\x00\x00\x01\x00\x02\x002
353 s> \r\n
353 s> \r\n
354 s> 0\r\n
354 s> 0\r\n
355 s> \r\n
355 s> \r\n
356 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
356 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
357 response: gen[
357 response: gen[
358 {
358 {
359 b'totalitems': 1
359 b'totalitems': 1
360 },
360 },
361 {
361 {
362 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
362 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
363 b'revisionsize': 292
363 b'revisionsize': 292
364 },
364 },
365 b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
365 b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
366 ]
366 ]
367
367
368 haveparents=True will emit delta
368 haveparents=True will emit delta
369
369
370 $ sendhttpv2peer << EOF
370 $ sendhttpv2peer << EOF
371 > command manifestdata
371 > command manifestdata
372 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
372 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
373 > tree eval:b''
373 > tree eval:b''
374 > fields eval:[b'revision']
374 > fields eval:[b'revision']
375 > haveparents eval:True
375 > haveparents eval:True
376 > EOF
376 > EOF
377 creating http peer for wire protocol version 2
377 creating http peer for wire protocol version 2
378 sending manifestdata command
378 sending manifestdata command
379 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
379 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
380 s> Accept-Encoding: identity\r\n
380 s> Accept-Encoding: identity\r\n
381 s> accept: application/mercurial-exp-framing-0005\r\n
381 s> accept: application/mercurial-exp-framing-0005\r\n
382 s> content-type: application/mercurial-exp-framing-0005\r\n
382 s> content-type: application/mercurial-exp-framing-0005\r\n
383 s> content-length: 97\r\n
383 s> content-length: 97\r\n
384 s> host: $LOCALIP:$HGPORT\r\n (glob)
384 s> host: $LOCALIP:$HGPORT\r\n (glob)
385 s> user-agent: Mercurial debugwireproto\r\n
385 s> user-agent: Mercurial debugwireproto\r\n
386 s> \r\n
386 s> \r\n
387 s> Y\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
387 s> Y\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x81TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
388 s> makefile('rb', None)
388 s> makefile('rb', None)
389 s> HTTP/1.1 200 OK\r\n
389 s> HTTP/1.1 200 OK\r\n
390 s> Server: testing stub value\r\n
390 s> Server: testing stub value\r\n
391 s> Date: $HTTP_DATE$\r\n
391 s> Date: $HTTP_DATE$\r\n
392 s> Content-Type: application/mercurial-exp-framing-0005\r\n
392 s> Content-Type: application/mercurial-exp-framing-0005\r\n
393 s> Transfer-Encoding: chunked\r\n
393 s> Transfer-Encoding: chunked\r\n
394 s> \r\n
394 s> \r\n
395 s> 13\r\n
395 s> 13\r\n
396 s> \x0b\x00\x00\x01\x00\x02\x011
396 s> \x0b\x00\x00\x01\x00\x02\x011
397 s> \xa1FstatusBok
397 s> \xa1FstatusBok
398 s> \r\n
398 s> \r\n
399 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
399 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
400 s> 98\r\n
400 s> 98\r\n
401 s> \x90\x00\x00\x01\x00\x02\x001
401 s> \x90\x00\x00\x01\x00\x02\x001
402 s> \xa1Jtotalitems\x01\xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
402 s> \xa1Jtotalitems\x01\xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
403 s> \r\n
403 s> \r\n
404 received frame(size=144; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
404 received frame(size=144; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
405 s> 8\r\n
405 s> 8\r\n
406 s> \x00\x00\x00\x01\x00\x02\x002
406 s> \x00\x00\x00\x01\x00\x02\x002
407 s> \r\n
407 s> \r\n
408 s> 0\r\n
408 s> 0\r\n
409 s> \r\n
409 s> \r\n
410 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
410 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
411 response: gen[
411 response: gen[
412 {
412 {
413 b'totalitems': 1
413 b'totalitems': 1
414 },
414 },
415 {
415 {
416 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
416 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
417 b'deltasize': 55,
417 b'deltasize': 55,
418 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
418 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
419 },
419 },
420 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
420 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
421 ]
421 ]
422
422
423 Requesting multiple revisions works
423 Requesting multiple revisions works
424 (haveparents defaults to false, so fulltext is emitted unless a parent
424 (haveparents defaults to false, so fulltext is emitted unless a parent
425 has been emitted)
425 has been emitted)
426
426
427 $ sendhttpv2peer << EOF
427 $ sendhttpv2peer << EOF
428 > command manifestdata
428 > command manifestdata
429 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
429 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
430 > tree eval:b''
430 > tree eval:b''
431 > fields eval:[b'revision']
431 > fields eval:[b'revision']
432 > EOF
432 > EOF
433 creating http peer for wire protocol version 2
433 creating http peer for wire protocol version 2
434 sending manifestdata command
434 sending manifestdata command
435 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
435 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
436 s> Accept-Encoding: identity\r\n
436 s> Accept-Encoding: identity\r\n
437 s> accept: application/mercurial-exp-framing-0005\r\n
437 s> accept: application/mercurial-exp-framing-0005\r\n
438 s> content-type: application/mercurial-exp-framing-0005\r\n
438 s> content-type: application/mercurial-exp-framing-0005\r\n
439 s> content-length: 105\r\n
439 s> content-length: 105\r\n
440 s> host: $LOCALIP:$HGPORT\r\n (glob)
440 s> host: $LOCALIP:$HGPORT\r\n (glob)
441 s> user-agent: Mercurial debugwireproto\r\n
441 s> user-agent: Mercurial debugwireproto\r\n
442 s> \r\n
442 s> \r\n
443 s> a\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
443 s> a\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
444 s> makefile('rb', None)
444 s> makefile('rb', None)
445 s> HTTP/1.1 200 OK\r\n
445 s> HTTP/1.1 200 OK\r\n
446 s> Server: testing stub value\r\n
446 s> Server: testing stub value\r\n
447 s> Date: $HTTP_DATE$\r\n
447 s> Date: $HTTP_DATE$\r\n
448 s> Content-Type: application/mercurial-exp-framing-0005\r\n
448 s> Content-Type: application/mercurial-exp-framing-0005\r\n
449 s> Transfer-Encoding: chunked\r\n
449 s> Transfer-Encoding: chunked\r\n
450 s> \r\n
450 s> \r\n
451 s> 13\r\n
451 s> 13\r\n
452 s> \x0b\x00\x00\x01\x00\x02\x011
452 s> \x0b\x00\x00\x01\x00\x02\x011
453 s> \xa1FstatusBok
453 s> \xa1FstatusBok
454 s> \r\n
454 s> \r\n
455 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
455 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
456 s> 1ea\r\n
456 s> 1ea\r\n
457 s> \xe2\x01\x00\x01\x00\x02\x001
457 s> \xe2\x01\x00\x01\x00\x02\x001
458 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
458 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
459 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
459 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
460 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
460 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
461 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
461 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
462 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
462 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
463 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
463 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
464 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
464 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
465 s> \r\n
465 s> \r\n
466 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
466 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
467 s> 8\r\n
467 s> 8\r\n
468 s> \x00\x00\x00\x01\x00\x02\x002
468 s> \x00\x00\x00\x01\x00\x02\x002
469 s> \r\n
469 s> \r\n
470 s> 0\r\n
470 s> 0\r\n
471 s> \r\n
471 s> \r\n
472 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
472 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
473 response: gen[
473 response: gen[
474 {
474 {
475 b'totalitems': 2
475 b'totalitems': 2
476 },
476 },
477 {
477 {
478 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
478 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
479 b'revisionsize': 292
479 b'revisionsize': 292
480 },
480 },
481 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
481 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
482 {
482 {
483 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
483 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
484 b'deltasize': 55,
484 b'deltasize': 55,
485 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
485 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
486 },
486 },
487 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
487 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
488 ]
488 ]
489
489
490 With haveparents=True, first revision is a delta instead of fulltext
490 With haveparents=True, first revision is a delta instead of fulltext
491
491
492 $ sendhttpv2peer << EOF
492 $ sendhttpv2peer << EOF
493 > command manifestdata
493 > command manifestdata
494 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
494 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
495 > tree eval:b''
495 > tree eval:b''
496 > fields eval:[b'revision']
496 > fields eval:[b'revision']
497 > haveparents eval:True
497 > haveparents eval:True
498 > EOF
498 > EOF
499 creating http peer for wire protocol version 2
499 creating http peer for wire protocol version 2
500 sending manifestdata command
500 sending manifestdata command
501 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
501 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
502 s> Accept-Encoding: identity\r\n
502 s> Accept-Encoding: identity\r\n
503 s> accept: application/mercurial-exp-framing-0005\r\n
503 s> accept: application/mercurial-exp-framing-0005\r\n
504 s> content-type: application/mercurial-exp-framing-0005\r\n
504 s> content-type: application/mercurial-exp-framing-0005\r\n
505 s> content-length: 118\r\n
505 s> content-length: 118\r\n
506 s> host: $LOCALIP:$HGPORT\r\n (glob)
506 s> host: $LOCALIP:$HGPORT\r\n (glob)
507 s> user-agent: Mercurial debugwireproto\r\n
507 s> user-agent: Mercurial debugwireproto\r\n
508 s> \r\n
508 s> \r\n
509 s> n\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
509 s> n\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
510 s> makefile('rb', None)
510 s> makefile('rb', None)
511 s> HTTP/1.1 200 OK\r\n
511 s> HTTP/1.1 200 OK\r\n
512 s> Server: testing stub value\r\n
512 s> Server: testing stub value\r\n
513 s> Date: $HTTP_DATE$\r\n
513 s> Date: $HTTP_DATE$\r\n
514 s> Content-Type: application/mercurial-exp-framing-0005\r\n
514 s> Content-Type: application/mercurial-exp-framing-0005\r\n
515 s> Transfer-Encoding: chunked\r\n
515 s> Transfer-Encoding: chunked\r\n
516 s> \r\n
516 s> \r\n
517 s> 13\r\n
517 s> 13\r\n
518 s> \x0b\x00\x00\x01\x00\x02\x011
518 s> \x0b\x00\x00\x01\x00\x02\x011
519 s> \xa1FstatusBok
519 s> \xa1FstatusBok
520 s> \r\n
520 s> \r\n
521 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
521 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
522 s> 1ea\r\n
522 s> 1ea\r\n
523 s> \xe2\x01\x00\x01\x00\x02\x001
523 s> \xe2\x01\x00\x01\x00\x02\x001
524 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
524 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
525 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
525 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
526 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
526 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
527 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
527 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
528 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
528 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
529 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
529 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
530 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
530 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
531 s> \r\n
531 s> \r\n
532 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
532 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
533 s> 8\r\n
533 s> 8\r\n
534 s> \x00\x00\x00\x01\x00\x02\x002
534 s> \x00\x00\x00\x01\x00\x02\x002
535 s> \r\n
535 s> \r\n
536 s> 0\r\n
536 s> 0\r\n
537 s> \r\n
537 s> \r\n
538 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
538 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
539 response: gen[
539 response: gen[
540 {
540 {
541 b'totalitems': 2
541 b'totalitems': 2
542 },
542 },
543 {
543 {
544 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
544 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
545 b'revisionsize': 292
545 b'revisionsize': 292
546 },
546 },
547 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
547 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
548 {
548 {
549 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
549 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
550 b'deltasize': 55,
550 b'deltasize': 55,
551 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
551 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
552 },
552 },
553 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
553 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
554 ]
554 ]
555
555
556 Revisions are sorted by DAG order, parents first
556 Revisions are sorted by DAG order, parents first
557
557
558 $ sendhttpv2peer << EOF
558 $ sendhttpv2peer << EOF
559 > command manifestdata
559 > command manifestdata
560 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0', b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4']
560 > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0', b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4']
561 > tree eval:b''
561 > tree eval:b''
562 > fields eval:[b'revision']
562 > fields eval:[b'revision']
563 > EOF
563 > EOF
564 creating http peer for wire protocol version 2
564 creating http peer for wire protocol version 2
565 sending manifestdata command
565 sending manifestdata command
566 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
566 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
567 s> Accept-Encoding: identity\r\n
567 s> Accept-Encoding: identity\r\n
568 s> accept: application/mercurial-exp-framing-0005\r\n
568 s> accept: application/mercurial-exp-framing-0005\r\n
569 s> content-type: application/mercurial-exp-framing-0005\r\n
569 s> content-type: application/mercurial-exp-framing-0005\r\n
570 s> content-length: 105\r\n
570 s> content-length: 105\r\n
571 s> host: $LOCALIP:$HGPORT\r\n (glob)
571 s> host: $LOCALIP:$HGPORT\r\n (glob)
572 s> user-agent: Mercurial debugwireproto\r\n
572 s> user-agent: Mercurial debugwireproto\r\n
573 s> \r\n
573 s> \r\n
574 s> a\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Dtree@DnameLmanifestdata
574 s> a\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Dtree@DnameLmanifestdata
575 s> makefile('rb', None)
575 s> makefile('rb', None)
576 s> HTTP/1.1 200 OK\r\n
576 s> HTTP/1.1 200 OK\r\n
577 s> Server: testing stub value\r\n
577 s> Server: testing stub value\r\n
578 s> Date: $HTTP_DATE$\r\n
578 s> Date: $HTTP_DATE$\r\n
579 s> Content-Type: application/mercurial-exp-framing-0005\r\n
579 s> Content-Type: application/mercurial-exp-framing-0005\r\n
580 s> Transfer-Encoding: chunked\r\n
580 s> Transfer-Encoding: chunked\r\n
581 s> \r\n
581 s> \r\n
582 s> 13\r\n
582 s> 13\r\n
583 s> \x0b\x00\x00\x01\x00\x02\x011
583 s> \x0b\x00\x00\x01\x00\x02\x011
584 s> \xa1FstatusBok
584 s> \xa1FstatusBok
585 s> \r\n
585 s> \r\n
586 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
586 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
587 s> 1ea\r\n
587 s> 1ea\r\n
588 s> \xe2\x01\x00\x01\x00\x02\x001
588 s> \xe2\x01\x00\x01\x00\x02\x001
589 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
589 s> \xa1Jtotalitems\x02\xa2DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
590 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
590 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
591 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
591 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
592 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
592 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
593 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
593 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
594 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
594 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
595 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
595 s> \xa3MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
596 s> \r\n
596 s> \r\n
597 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
597 received frame(size=482; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
598 s> 8\r\n
598 s> 8\r\n
599 s> \x00\x00\x00\x01\x00\x02\x002
599 s> \x00\x00\x00\x01\x00\x02\x002
600 s> \r\n
600 s> \r\n
601 s> 0\r\n
601 s> 0\r\n
602 s> \r\n
602 s> \r\n
603 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
603 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
604 response: gen[
604 response: gen[
605 {
605 {
606 b'totalitems': 2
606 b'totalitems': 2
607 },
607 },
608 {
608 {
609 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
609 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
610 b'revisionsize': 292
610 b'revisionsize': 292
611 },
611 },
612 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
612 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
613 {
613 {
614 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
614 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
615 b'deltasize': 55,
615 b'deltasize': 55,
616 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
616 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
617 },
617 },
618 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
618 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
619 ]
619 ]
620
620
621 Requesting parents and revision data works
621 Requesting parents and revision data works
622
622
623 $ sendhttpv2peer << EOF
623 $ sendhttpv2peer << EOF
624 > command manifestdata
624 > command manifestdata
625 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
625 > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
626 > tree eval:b''
626 > tree eval:b''
627 > fields eval:[b'parents', b'revision']
627 > fields eval:[b'parents', b'revision']
628 > EOF
628 > EOF
629 creating http peer for wire protocol version 2
629 creating http peer for wire protocol version 2
630 sending manifestdata command
630 sending manifestdata command
631 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
631 s> POST /api/exp-http-v2-0001/ro/manifestdata HTTP/1.1\r\n
632 s> Accept-Encoding: identity\r\n
632 s> Accept-Encoding: identity\r\n
633 s> accept: application/mercurial-exp-framing-0005\r\n
633 s> accept: application/mercurial-exp-framing-0005\r\n
634 s> content-type: application/mercurial-exp-framing-0005\r\n
634 s> content-type: application/mercurial-exp-framing-0005\r\n
635 s> content-length: 113\r\n
635 s> content-length: 113\r\n
636 s> host: $LOCALIP:$HGPORT\r\n (glob)
636 s> host: $LOCALIP:$HGPORT\r\n (glob)
637 s> user-agent: Mercurial debugwireproto\r\n
637 s> user-agent: Mercurial debugwireproto\r\n
638 s> \r\n
638 s> \r\n
639 s> i\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x82GparentsHrevisionEnodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
639 s> i\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x82GparentsHrevisionEnodes\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4TF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Dtree@DnameLmanifestdata
640 s> makefile('rb', None)
640 s> makefile('rb', None)
641 s> HTTP/1.1 200 OK\r\n
641 s> HTTP/1.1 200 OK\r\n
642 s> Server: testing stub value\r\n
642 s> Server: testing stub value\r\n
643 s> Date: $HTTP_DATE$\r\n
643 s> Date: $HTTP_DATE$\r\n
644 s> Content-Type: application/mercurial-exp-framing-0005\r\n
644 s> Content-Type: application/mercurial-exp-framing-0005\r\n
645 s> Transfer-Encoding: chunked\r\n
645 s> Transfer-Encoding: chunked\r\n
646 s> \r\n
646 s> \r\n
647 s> 13\r\n
647 s> 13\r\n
648 s> \x0b\x00\x00\x01\x00\x02\x011
648 s> \x0b\x00\x00\x01\x00\x02\x011
649 s> \xa1FstatusBok
649 s> \xa1FstatusBok
650 s> \r\n
650 s> \r\n
651 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
651 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
652 s> 250\r\n
652 s> 250\r\n
653 s> H\x02\x00\x01\x00\x02\x001
653 s> H\x02\x00\x01\x00\x02\x001
654 s> \xa1Jtotalitems\x02\xa3DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Gparents\x82T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
654 s> \xa1Jtotalitems\x02\xa3DnodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Gparents\x82T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x19\x01$Y\x01$a\x002b4eb07319bfa077a40a2f04913659aef0da42da\n
655 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
655 s> b\x00819e258d31a5e1606629f365bb902a1b21ee4216\n
656 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
656 s> dir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\n
657 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
657 s> dir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\n
658 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
658 s> dir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\n
659 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
659 s> dir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n
660 s> \xa4MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Gparents\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
660 s> \xa4MdeltabasenodeT\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4Ideltasize\x187DnodeTF\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0Gparents\x82T\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X7\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n
661 s> \r\n
661 s> \r\n
662 received frame(size=584; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
662 received frame(size=584; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
663 s> 8\r\n
663 s> 8\r\n
664 s> \x00\x00\x00\x01\x00\x02\x002
664 s> \x00\x00\x00\x01\x00\x02\x002
665 s> \r\n
665 s> \r\n
666 s> 0\r\n
666 s> 0\r\n
667 s> \r\n
667 s> \r\n
668 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
668 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
669 response: gen[
669 response: gen[
670 {
670 {
671 b'totalitems': 2
671 b'totalitems': 2
672 },
672 },
673 {
673 {
674 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
674 b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
675 b'parents': [
675 b'parents': [
676 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
676 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
677 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
677 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
678 ],
678 ],
679 b'revisionsize': 292
679 b'revisionsize': 292
680 },
680 },
681 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
681 b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
682 {
682 {
683 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
683 b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
684 b'deltasize': 55,
684 b'deltasize': 55,
685 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
685 b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
686 b'parents': [
686 b'parents': [
687 b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
687 b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
688 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
688 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
689 ]
689 ]
690 },
690 },
691 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
691 b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
692 ]
692 ]
693
693
694 $ cat error.log
694 $ cat error.log
General Comments 0
You need to be logged in to leave comments. Login now