Mercurial > hg
annotate mercurial/sshpeer.py @ 36374:f0c94af0d70d
py3: add b'' prefixes in test-dispatch.py
# skip-blame because this is just adding b'' prefixes
author | Pulkit Goyal <7895pulkit@gmail.com> |
---|---|
date | Wed, 21 Feb 2018 23:43:23 +0530 |
parents | b8d0761a85c7 |
children | dabf86721200 |
rev | line source |
---|---|
17192
1ac628cd7113
peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
16688
diff
changeset
|
1 # sshpeer.py - ssh repository proxy class for mercurial |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
2 # |
2859 | 3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8210
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
7 |
25975
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
8 from __future__ import absolute_import |
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
9 |
15622
86fc364ca5f8
sshrepo: don't quote obviously safe strings (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15581
diff
changeset
|
10 import re |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
11 import uuid |
25975
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
12 |
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
13 from .i18n import _ |
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
14 from . import ( |
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
15 error, |
33100
05906b8e1d23
py3: use pycompat.byteskwargs() to convert kwargs' keys to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32062
diff
changeset
|
16 pycompat, |
25975
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
17 util, |
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
18 wireproto, |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
19 wireprotoserver, |
25975
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
20 ) |
60 | 21 |
15581
d8fa35c28335
ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15017
diff
changeset
|
22 def _serverquote(s): |
35459
b520c8f98e1e
sshpeer: move docstring to top
Yuya Nishihara <yuya@tcha.org>
parents:
35436
diff
changeset
|
23 """quote a string for the remote shell ... which we assume is sh""" |
23671
e3f30068d2eb
sshpeer: more thorough shell quoting
Matt Mackall <mpm@selenic.com>
parents:
22935
diff
changeset
|
24 if not s: |
e3f30068d2eb
sshpeer: more thorough shell quoting
Matt Mackall <mpm@selenic.com>
parents:
22935
diff
changeset
|
25 return s |
15624
be43234a6d60
sshrepo: add more safe characters (issue2983)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
15622
diff
changeset
|
26 if re.match('[a-zA-Z0-9@%_+=:,./-]*$', s): |
15622
86fc364ca5f8
sshrepo: don't quote obviously safe strings (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15581
diff
changeset
|
27 return s |
15581
d8fa35c28335
ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15017
diff
changeset
|
28 return "'%s'" % s.replace("'", "'\\''") |
d8fa35c28335
ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15017
diff
changeset
|
29 |
25244
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
30 def _forwardoutput(ui, pipe): |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
31 """display all data currently available on pipe as remote output. |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
32 |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
33 This is non blocking.""" |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
34 s = util.readpipe(pipe) |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
35 if s: |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
36 for l in s.splitlines(): |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
37 ui.status(_("remote: "), l, '\n') |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
38 |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
39 class doublepipe(object): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
40 """Operate a side-channel pipe in addition of a main one |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
41 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
42 The side-channel pipe contains server output to be forwarded to the user |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
43 input. The double pipe will behave as the "main" pipe, but will ensure the |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
44 content of the "side" pipe is properly processed while we wait for blocking |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
45 call on the "main" pipe. |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
46 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
47 If large amounts of data are read from "main", the forward will cease after |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
48 the first bytes start to appear. This simplifies the implementation |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
49 without affecting actual output of sshpeer too much as we rarely issue |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
50 large read for data not yet emitted by the server. |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
51 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
52 The main pipe is expected to be a 'bufferedinputpipe' from the util module |
31953
cc2382b60007
sshpeer: fix docstring typo
Augie Fackler <augie@google.com>
parents:
31197
diff
changeset
|
53 that handle all the os specific bits. This class lives in this module |
26781
1aee2ab0f902
spelling: trivial spell checking
Mads Kiilerich <madski@unity3d.com>
parents:
26587
diff
changeset
|
54 because it focus on behavior specific to the ssh protocol.""" |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
55 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
56 def __init__(self, ui, main, side): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
57 self._ui = ui |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
58 self._main = main |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
59 self._side = side |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
60 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
61 def _wait(self): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
62 """wait until some data are available on main or side |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
63 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
64 return a pair of boolean (ismainready, issideready) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
65 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
66 (This will only wait for data if the setup is supported by `util.poll`) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
67 """ |
36369
066e6a9d52bb
sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36367
diff
changeset
|
68 if (isinstance(self._main, util.bufferedinputpipe) and |
066e6a9d52bb
sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36367
diff
changeset
|
69 self._main.hasbuffer): |
066e6a9d52bb
sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36367
diff
changeset
|
70 # Main has data. Assume side is worth poking at. |
066e6a9d52bb
sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36367
diff
changeset
|
71 return True, True |
066e6a9d52bb
sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36367
diff
changeset
|
72 |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
73 fds = [self._main.fileno(), self._side.fileno()] |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
74 try: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
75 act = util.poll(fds) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
76 except NotImplementedError: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
77 # non supported yet case, assume all have data. |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
78 act = fds |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
79 return (self._main.fileno() in act, self._side.fileno() in act) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
80 |
25456
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
81 def write(self, data): |
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
82 return self._call('write', data) |
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
83 |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
84 def read(self, size): |
32062
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
85 r = self._call('read', size) |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
86 if size != 0 and not r: |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
87 # We've observed a condition that indicates the |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
88 # stdout closed unexpectedly. Check stderr one |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
89 # more time and snag anything that's there before |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
90 # letting anyone know the main part of the pipe |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
91 # closed prematurely. |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
92 _forwardoutput(self._ui, self._side) |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
93 return r |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
94 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
95 def readline(self): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
96 return self._call('readline') |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
97 |
25455
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
98 def _call(self, methname, data=None): |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
99 """call <methname> on "main", forward output of "side" while blocking |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
100 """ |
25455
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
101 # data can be '' or 0 |
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
102 if (data is not None and not data) or self._main.closed: |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
103 _forwardoutput(self._ui, self._side) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
104 return '' |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
105 while True: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
106 mainready, sideready = self._wait() |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
107 if sideready: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
108 _forwardoutput(self._ui, self._side) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
109 if mainready: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
110 meth = getattr(self._main, methname) |
25455
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
111 if data is None: |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
112 return meth() |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
113 else: |
25455
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
114 return meth(data) |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
115 |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
116 def close(self): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
117 return self._main.close() |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
118 |
25456
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
119 def flush(self): |
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
120 return self._main.flush() |
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
121 |
35933
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
122 def _cleanuppipes(ui, pipei, pipeo, pipee): |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
123 """Clean up pipes used by an SSH connection.""" |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
124 if pipeo: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
125 pipeo.close() |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
126 if pipei: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
127 pipei.close() |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
128 |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
129 if pipee: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
130 # Try to read from the err descriptor until EOF. |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
131 try: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
132 for l in pipee: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
133 ui.status(_('remote: '), l) |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
134 except (IOError, ValueError): |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
135 pass |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
136 |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
137 pipee.close() |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
138 |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
139 def _makeconnection(ui, sshcmd, args, remotecmd, path, sshenv=None): |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
140 """Create an SSH connection to a server. |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
141 |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
142 Returns a tuple of (process, stdin, stdout, stderr) for the |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
143 spawned process. |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
144 """ |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
145 cmd = '%s %s %s' % ( |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
146 sshcmd, |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
147 args, |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
148 util.shellquote('%s -R %s serve --stdio' % ( |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
149 _serverquote(remotecmd), _serverquote(path)))) |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
150 |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
151 ui.debug('running %s\n' % cmd) |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
152 cmd = util.quotecommand(cmd) |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
153 |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
154 # no buffer allow the use of 'select' |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
155 # feel free to remove buffering and select usage when we ultimately |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
156 # move to threading. |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
157 stdin, stdout, stderr, proc = util.popen4(cmd, bufsize=0, env=sshenv) |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
158 |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
159 return proc, stdin, stdout, stderr |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
160 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
161 def _performhandshake(ui, stdin, stdout, stderr): |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
162 def badresponse(): |
36370
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
163 # Flush any output on stderr. |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
164 _forwardoutput(ui, stderr) |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
165 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
166 msg = _('no suitable response from remote hg') |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
167 hint = ui.config('ui', 'ssherrorhint') |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
168 raise error.RepoError(msg, hint=hint) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
169 |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
170 # The handshake consists of sending wire protocol commands in reverse |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
171 # order of protocol implementation and then sniffing for a response |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
172 # to one of them. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
173 # |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
174 # Those commands (from oldest to newest) are: |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
175 # |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
176 # ``between`` |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
177 # Asks for the set of revisions between a pair of revisions. Command |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
178 # present in all Mercurial server implementations. |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
179 # |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
180 # ``hello`` |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
181 # Instructs the server to advertise its capabilities. Introduced in |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
182 # Mercurial 0.9.1. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
183 # |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
184 # ``upgrade`` |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
185 # Requests upgrade from default transport protocol version 1 to |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
186 # a newer version. Introduced in Mercurial 4.6 as an experimental |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
187 # feature. |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
188 # |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
189 # The ``between`` command is issued with a request for the null |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
190 # range. If the remote is a Mercurial server, this request will |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
191 # generate a specific response: ``1\n\n``. This represents the |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
192 # wire protocol encoded value for ``\n``. We look for ``1\n\n`` |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
193 # in the output stream and know this is the response to ``between`` |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
194 # and we're at the end of our handshake reply. |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
195 # |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
196 # The response to the ``hello`` command will be a line with the |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
197 # length of the value returned by that command followed by that |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
198 # value. If the server doesn't support ``hello`` (which should be |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
199 # rare), that line will be ``0\n``. Otherwise, the value will contain |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
200 # RFC 822 like lines. Of these, the ``capabilities:`` line contains |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
201 # the capabilities of the server. |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
202 # |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
203 # The ``upgrade`` command isn't really a command in the traditional |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
204 # sense of version 1 of the transport because it isn't using the |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
205 # proper mechanism for formatting insteads: instead, it just encodes |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
206 # arguments on the line, delimited by spaces. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
207 # |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
208 # The ``upgrade`` line looks like ``upgrade <token> <capabilities>``. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
209 # If the server doesn't support protocol upgrades, it will reply to |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
210 # this line with ``0\n``. Otherwise, it emits an |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
211 # ``upgraded <token> <protocol>`` line to both stdout and stderr. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
212 # Content immediately following this line describes additional |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
213 # protocol and server state. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
214 # |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
215 # In addition to the responses to our command requests, the server |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
216 # may emit "banner" output on stdout. SSH servers are allowed to |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
217 # print messages to stdout on login. Issuing commands on connection |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
218 # allows us to flush this banner output from the server by scanning |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
219 # for output to our well-known ``between`` command. Of course, if |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
220 # the banner contains ``1\n\n``, this will throw off our detection. |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
221 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
222 requestlog = ui.configbool('devel', 'debug.peer-request') |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
223 |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
224 # Generate a random token to help identify responses to version 2 |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
225 # upgrade request. |
36043
223ed0b53f08
py3: more robustly cast UUID to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35978
diff
changeset
|
226 token = pycompat.sysbytes(str(uuid.uuid4())) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
227 upgradecaps = [ |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
228 ('proto', wireprotoserver.SSHV2), |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
229 ] |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
230 upgradecaps = util.urlreq.urlencode(upgradecaps) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
231 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
232 try: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
233 pairsarg = '%s-%s' % ('0' * 40, '0' * 40) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
234 handshake = [ |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
235 'hello\n', |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
236 'between\n', |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
237 'pairs %d\n' % len(pairsarg), |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
238 pairsarg, |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
239 ] |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
240 |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
241 # Request upgrade to version 2 if configured. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
242 if ui.configbool('experimental', 'sshpeer.advertise-v2'): |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
243 ui.debug('sending upgrade request: %s %s\n' % (token, upgradecaps)) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
244 handshake.insert(0, 'upgrade %s %s\n' % (token, upgradecaps)) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
245 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
246 if requestlog: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
247 ui.debug('devel-peer-request: hello\n') |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
248 ui.debug('sending hello command\n') |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
249 if requestlog: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
250 ui.debug('devel-peer-request: between\n') |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
251 ui.debug('devel-peer-request: pairs: %d bytes\n' % len(pairsarg)) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
252 ui.debug('sending between command\n') |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
253 |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
254 stdin.write(''.join(handshake)) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
255 stdin.flush() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
256 except IOError: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
257 badresponse() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
258 |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
259 # Assume version 1 of wire protocol by default. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
260 protoname = wireprotoserver.SSHV1 |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
261 reupgraded = re.compile(b'^upgraded %s (.*)$' % re.escape(token)) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
262 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
263 lines = ['', 'dummy'] |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
264 max_noise = 500 |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
265 while lines[-1] and max_noise: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
266 try: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
267 l = stdout.readline() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
268 _forwardoutput(ui, stderr) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
269 |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
270 # Look for reply to protocol upgrade request. It has a token |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
271 # in it, so there should be no false positives. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
272 m = reupgraded.match(l) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
273 if m: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
274 protoname = m.group(1) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
275 ui.debug('protocol upgraded to %s\n' % protoname) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
276 # If an upgrade was handled, the ``hello`` and ``between`` |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
277 # requests are ignored. The next output belongs to the |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
278 # protocol, so stop scanning lines. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
279 break |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
280 |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
281 # Otherwise it could be a banner, ``0\n`` response if server |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
282 # doesn't support upgrade. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
283 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
284 if lines[-1] == '1\n' and l == '\n': |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
285 break |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
286 if l: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
287 ui.debug('remote: ', l) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
288 lines.append(l) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
289 max_noise -= 1 |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
290 except IOError: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
291 badresponse() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
292 else: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
293 badresponse() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
294 |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
295 caps = set() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
296 |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
297 # For version 1, we should see a ``capabilities`` line in response to the |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
298 # ``hello`` command. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
299 if protoname == wireprotoserver.SSHV1: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
300 for l in reversed(lines): |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
301 # Look for response to ``hello`` command. Scan from the back so |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
302 # we don't misinterpret banner output as the command reply. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
303 if l.startswith('capabilities:'): |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
304 caps.update(l[:-1].split(':')[1].split()) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
305 break |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
306 elif protoname == wireprotoserver.SSHV2: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
307 # We see a line with number of bytes to follow and then a value |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
308 # looking like ``capabilities: *``. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
309 line = stdout.readline() |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
310 try: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
311 valuelen = int(line) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
312 except ValueError: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
313 badresponse() |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
314 |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
315 capsline = stdout.read(valuelen) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
316 if not capsline.startswith('capabilities: '): |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
317 badresponse() |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
318 |
36216
7218e93ade47
sshpeer: log remote capabilities after protocol upgrade
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36043
diff
changeset
|
319 ui.debug('remote: %s\n' % capsline) |
7218e93ade47
sshpeer: log remote capabilities after protocol upgrade
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36043
diff
changeset
|
320 |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
321 caps.update(capsline.split(':')[1].split()) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
322 # Trailing newline. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
323 stdout.read(1) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
324 |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
325 # Error if we couldn't find capabilities, this means: |
35940
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
326 # |
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
327 # 1. Remote isn't a Mercurial server |
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
328 # 2. Remote is a <0.9.1 Mercurial server |
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
329 # 3. Remote is a future Mercurial server that dropped ``hello`` |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
330 # and other attempted handshake mechanisms. |
35940
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
331 if not caps: |
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
332 badresponse() |
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
333 |
36370
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
334 # Flush any output on stderr before proceeding. |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
335 _forwardoutput(ui, stderr) |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
336 |
35978
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
337 return protoname, caps |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
338 |
35977
625038cb4b1d
sshpeer: rename sshpeer class to sshv1peer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35976
diff
changeset
|
339 class sshv1peer(wireproto.wirepeer): |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
340 def __init__(self, ui, url, proc, stdin, stdout, stderr, caps): |
35936
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
341 """Create a peer from an existing SSH connection. |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
342 |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
343 ``proc`` is a handle on the underlying SSH process. |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
344 ``stdin``, ``stdout``, and ``stderr`` are handles on the stdio |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
345 pipes for that process. |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
346 ``caps`` is a set of capabilities supported by the remote. |
35936
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
347 """ |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
348 self._url = url |
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
349 self._ui = ui |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
350 # self._subprocess is unused. Keeping a handle on the process |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
351 # holds a reference and prevents it from being garbage collected. |
35936
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
352 self._subprocess = proc |
36370
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
353 |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
354 # And we hook up our "doublepipe" wrapper to allow querying |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
355 # stderr any time we perform I/O. |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
356 stdout = doublepipe(ui, util.bufferedinputpipe(stdout), stderr) |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
357 stdin = doublepipe(ui, stdin, stderr) |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
358 |
35936
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
359 self._pipeo = stdin |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
360 self._pipei = stdout |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
361 self._pipee = stderr |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
362 self._caps = caps |
2549
e1831f06eef1
Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents:
2484
diff
changeset
|
363 |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
364 # Commands that have a "framed" response where the first line of the |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
365 # response contains the length of that response. |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
366 _FRAMED_COMMANDS = { |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
367 'batch', |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
368 } |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
369 |
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
370 # Begin of _basepeer interface. |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
371 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
372 @util.propertycache |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
373 def ui(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
374 return self._ui |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
375 |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
376 def url(self): |
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
377 return self._url |
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
378 |
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
379 def local(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
380 return None |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
381 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
382 def peer(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
383 return self |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
384 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
385 def canpush(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
386 return True |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
387 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
388 def close(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
389 pass |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
390 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
391 # End of _basepeer interface. |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
392 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
393 # Begin of _basewirecommands interface. |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
394 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
395 def capabilities(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
396 return self._caps |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
397 |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
398 # End of _basewirecommands interface. |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
399 |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
400 def _readerr(self): |
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
401 _forwardoutput(self.ui, self._pipee) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
402 |
11586
ddaaaa23bb8f
protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents:
11369
diff
changeset
|
403 def _abort(self, exception): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
404 self._cleanup() |
11586
ddaaaa23bb8f
protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents:
11369
diff
changeset
|
405 raise exception |
ddaaaa23bb8f
protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents:
11369
diff
changeset
|
406 |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
407 def _cleanup(self): |
35933
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
408 _cleanuppipes(self.ui, self._pipei, self._pipeo, self._pipee) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
409 |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
410 __del__ = _cleanup |
3034
2b0bc36a48d8
sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2859
diff
changeset
|
411 |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
412 def _sendrequest(self, cmd, args, framed=False): |
35699
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
413 if (self.ui.debugflag |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
414 and self.ui.configbool('devel', 'debug.peer-request')): |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
415 dbg = self.ui.debug |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
416 line = 'devel-peer-request: %s\n' |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
417 dbg(line % cmd) |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
418 for key, value in sorted(args.items()): |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
419 if not isinstance(value, dict): |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
420 dbg(line % ' %s: %d bytes' % (key, len(value))) |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
421 else: |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
422 for dk, dv in sorted(value.items()): |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
423 dbg(line % ' %s-%s: %d' % (key, dk, len(dv))) |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
8563
diff
changeset
|
424 self.ui.debug("sending %s command\n" % cmd) |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
425 self._pipeo.write("%s\n" % cmd) |
13721
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
426 _func, names = wireproto.commands[cmd] |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
427 keys = names.split() |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
428 wireargs = {} |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
429 for k in keys: |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
430 if k == '*': |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
431 wireargs['*'] = args |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
432 break |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
433 else: |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
434 wireargs[k] = args[k] |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
435 del args[k] |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
436 for k, v in sorted(wireargs.iteritems()): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
437 self._pipeo.write("%s %d\n" % (k, len(v))) |
13721
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
438 if isinstance(v, dict): |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
439 for dk, dv in v.iteritems(): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
440 self._pipeo.write("%s %d\n" % (dk, len(dv))) |
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
441 self._pipeo.write(dv) |
13721
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
442 else: |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
443 self._pipeo.write(v) |
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
444 self._pipeo.flush() |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
445 |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
446 # We know exactly how many bytes are in the response. So return a proxy |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
447 # around the raw output stream that allows reading exactly this many |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
448 # bytes. Callers then can read() without fear of overrunning the |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
449 # response. |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
450 if framed: |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
451 amount = self._getamount() |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
452 return util.cappedreader(self._pipei, amount) |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
453 |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
454 return self._pipei |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
455 |
36366
a34d5ef53c2e
sshpeer: move logic for sending a request into a new function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36363
diff
changeset
|
456 def _callstream(self, cmd, **args): |
a34d5ef53c2e
sshpeer: move logic for sending a request into a new function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36363
diff
changeset
|
457 args = pycompat.byteskwargs(args) |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
458 return self._sendrequest(cmd, args, framed=cmd in self._FRAMED_COMMANDS) |
36366
a34d5ef53c2e
sshpeer: move logic for sending a request into a new function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36363
diff
changeset
|
459 |
20905
167047ba3cfa
wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20794
diff
changeset
|
460 def _callcompressable(self, cmd, **args): |
36366
a34d5ef53c2e
sshpeer: move logic for sending a request into a new function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36363
diff
changeset
|
461 args = pycompat.byteskwargs(args) |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
462 return self._sendrequest(cmd, args, framed=cmd in self._FRAMED_COMMANDS) |
20905
167047ba3cfa
wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20794
diff
changeset
|
463 |
11589
e8d22fe2ddab
protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents:
11588
diff
changeset
|
464 def _call(self, cmd, **args): |
36366
a34d5ef53c2e
sshpeer: move logic for sending a request into a new function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36363
diff
changeset
|
465 args = pycompat.byteskwargs(args) |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
466 return self._sendrequest(cmd, args, framed=True).read() |
5978
7939c71f3132
sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5293
diff
changeset
|
467 |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
468 def _callpush(self, cmd, fp, **args): |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
469 # The server responds with an empty frame if the client should |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
470 # continue submitting the payload. |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
471 r = self._call(cmd, **args) |
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
472 if r: |
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
473 return '', r |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
474 |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
475 # The payload consists of frames with content followed by an empty |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
476 # frame. |
29727
0dbd788a2dfd
sshpeer: use `iter(callable, sentinel)` instead of while True
Augie Fackler <augie@google.com>
parents:
29389
diff
changeset
|
477 for d in iter(lambda: fp.read(4096), ''): |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
478 self._writeframed(d) |
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
479 self._writeframed("", flush=True) |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
480 |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
481 # In case of success, there is an empty frame and a frame containing |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
482 # the integer result (as a string). |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
483 # In case of error, there is a non-empty frame containing the error. |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
484 r = self._readframed() |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
485 if r: |
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
486 return '', r |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
487 return self._readframed(), '' |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
488 |
21073
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
489 def _calltwowaystream(self, cmd, fp, **args): |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
490 # The server responds with an empty frame if the client should |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
491 # continue submitting the payload. |
21073
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
492 r = self._call(cmd, **args) |
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
493 if r: |
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
494 # XXX needs to be made better |
29389
98e8313dcd9e
i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents:
28438
diff
changeset
|
495 raise error.Abort(_('unexpected remote reply: %s') % r) |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
496 |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
497 # The payload consists of frames with content followed by an empty |
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
498 # frame. |
29727
0dbd788a2dfd
sshpeer: use `iter(callable, sentinel)` instead of while True
Augie Fackler <augie@google.com>
parents:
29389
diff
changeset
|
499 for d in iter(lambda: fp.read(4096), ''): |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
500 self._writeframed(d) |
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
501 self._writeframed("", flush=True) |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
502 |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
503 return self._pipei |
11591
0d9cb3f3b0a1
protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents:
11590
diff
changeset
|
504 |
28438
48fd02dac1d4
wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents:
27798
diff
changeset
|
505 def _getamount(self): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
506 l = self._pipei.readline() |
15017
f4522df38c65
wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents:
14537
diff
changeset
|
507 if l == '\n': |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
508 self._readerr() |
25243
d65243d28749
sshpeer: break "OutOfBandError" feature for ssh (BC)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23684
diff
changeset
|
509 msg = _('check previous remote output') |
d65243d28749
sshpeer: break "OutOfBandError" feature for ssh (BC)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23684
diff
changeset
|
510 self._abort(error.OutOfBandError(hint=msg)) |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
511 self._readerr() |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
512 try: |
28438
48fd02dac1d4
wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents:
27798
diff
changeset
|
513 return int(l) |
14004
97ed99d1f419
eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents:
13827
diff
changeset
|
514 except ValueError: |
11590
0b15aee0a306
protocol: convert some ssh abort calls
Matt Mackall <mpm@selenic.com>
parents:
11589
diff
changeset
|
515 self._abort(error.ResponseError(_("unexpected response:"), l)) |
28438
48fd02dac1d4
wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents:
27798
diff
changeset
|
516 |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
517 def _readframed(self): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
518 return self._pipei.read(self._getamount()) |
5978
7939c71f3132
sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5293
diff
changeset
|
519 |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
520 def _writeframed(self, data, flush=False): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
521 self._pipeo.write("%d\n" % len(data)) |
5978
7939c71f3132
sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5293
diff
changeset
|
522 if data: |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
523 self._pipeo.write(data) |
5978
7939c71f3132
sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5293
diff
changeset
|
524 if flush: |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
525 self._pipeo.flush() |
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
526 self._readerr() |
2612
ffb895f16925
add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2549
diff
changeset
|
527 |
35978
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
528 class sshv2peer(sshv1peer): |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
529 """A peer that speakers version 2 of the transport protocol.""" |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
530 # Currently version 2 is identical to version 1 post handshake. |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
531 # And handshake is performed before the peer is instantiated. So |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
532 # we need no custom code. |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
533 |
35928
b0d2885c5945
sshpeer: make "instance" a function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35699
diff
changeset
|
534 def instance(ui, path, create): |
35931
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
535 """Create an SSH peer. |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
536 |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
537 The returned object conforms to the ``wireproto.wirepeer`` interface. |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
538 """ |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
539 u = util.url(path, parsequery=False, parsefragment=False) |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
540 if u.scheme != 'ssh' or not u.host or u.path is None: |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
541 raise error.RepoError(_("couldn't parse location %s") % path) |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
542 |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
543 util.checksafessh(path) |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
544 |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
545 if u.passwd is not None: |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
546 raise error.RepoError(_('password in URL not supported')) |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
547 |
35932
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
548 sshcmd = ui.config('ui', 'ssh') |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
549 remotecmd = ui.config('ui', 'remotecmd') |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
550 sshaddenv = dict(ui.configitems('sshenv')) |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
551 sshenv = util.shellenviron(sshaddenv) |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
552 remotepath = u.path or '.' |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
553 |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
554 args = util.sshargs(sshcmd, u.host, u.user, u.port) |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
555 |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
556 if create: |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
557 cmd = '%s %s %s' % (sshcmd, args, |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
558 util.shellquote('%s init %s' % |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
559 (_serverquote(remotecmd), _serverquote(remotepath)))) |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
560 ui.debug('running %s\n' % cmd) |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
561 res = ui.system(cmd, blockedtag='sshpeer', environ=sshenv) |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
562 if res != 0: |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
563 raise error.RepoError(_('could not create remote repo')) |
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
564 |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
565 proc, stdin, stdout, stderr = _makeconnection(ui, sshcmd, args, remotecmd, |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
566 remotepath, sshenv) |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
567 |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
568 try: |
35978
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
569 protoname, caps = _performhandshake(ui, stdin, stdout, stderr) |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
570 except Exception: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
571 _cleanuppipes(ui, stdout, stdin, stderr) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
572 raise |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
573 |
35978
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
574 if protoname == wireprotoserver.SSHV1: |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
575 return sshv1peer(ui, path, proc, stdin, stdout, stderr, caps) |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
576 elif protoname == wireprotoserver.SSHV2: |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
577 return sshv2peer(ui, path, proc, stdin, stdout, stderr, caps) |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
578 else: |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
579 _cleanuppipes(ui, stdout, stdin, stderr) |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
580 raise error.RepoError(_('unknown version of SSH protocol: %s') % |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
581 protoname) |