author | Augie Fackler <augie@google.com> |
Thu, 14 Nov 2019 15:49:21 -0500 | |
changeset 43706 | ac8fd215a776 |
parent 43106 | d783f945a701 |
child 44860 | 5d77f571a563 |
permissions | -rw-r--r-- |
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 _ |
43089
c59eb1560c44
py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43077
diff
changeset
|
14 |
from .pycompat import getattr |
25975
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
15 |
from . import ( |
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
16 |
error, |
33100
05906b8e1d23
py3: use pycompat.byteskwargs() to convert kwargs' keys to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32062
diff
changeset
|
17 |
pycompat, |
25975
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
18 |
util, |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
19 |
wireprotoserver, |
36536
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36533
diff
changeset
|
20 |
wireprototypes, |
37614
a81d02ea65db
wireproto: move version 1 peer functionality to standalone module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
21 |
wireprotov1peer, |
37785
b4d85bc122bd
wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37717
diff
changeset
|
22 |
wireprotov1server, |
25975
de7a3893ee65
sshpeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25458
diff
changeset
|
23 |
) |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
24 |
from .utils import ( |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
25 |
procutil, |
38475
67dc32d4e790
cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents:
37813
diff
changeset
|
26 |
stringutil, |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
27 |
) |
60 | 28 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
29 |
|
15581
d8fa35c28335
ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15017
diff
changeset
|
30 |
def _serverquote(s): |
35459
b520c8f98e1e
sshpeer: move docstring to top
Yuya Nishihara <yuya@tcha.org>
parents:
35436
diff
changeset
|
31 |
"""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
|
32 |
if not s: |
e3f30068d2eb
sshpeer: more thorough shell quoting
Matt Mackall <mpm@selenic.com>
parents:
22935
diff
changeset
|
33 |
return s |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
34 |
if re.match(b'[a-zA-Z0-9@%_+=:,./-]*$', s): |
15622
86fc364ca5f8
sshrepo: don't quote obviously safe strings (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15581
diff
changeset
|
35 |
return s |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
36 |
return b"'%s'" % s.replace(b"'", b"'\\''") |
15581
d8fa35c28335
ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents:
15017
diff
changeset
|
37 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
38 |
|
25244
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
39 |
def _forwardoutput(ui, pipe): |
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
40 |
"""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
|
41 |
|
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
42 |
This is non blocking.""" |
36833
46f4d71ed505
sshpeer: check pipe validity before forwarding output from it
Matt Harbison <matt_harbison@yahoo.com>
parents:
36628
diff
changeset
|
43 |
if pipe: |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
44 |
s = procutil.readpipe(pipe) |
36833
46f4d71ed505
sshpeer: check pipe validity before forwarding output from it
Matt Harbison <matt_harbison@yahoo.com>
parents:
36628
diff
changeset
|
45 |
if s: |
46f4d71ed505
sshpeer: check pipe validity before forwarding output from it
Matt Harbison <matt_harbison@yahoo.com>
parents:
36628
diff
changeset
|
46 |
for l in s.splitlines(): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
47 |
ui.status(_(b"remote: "), l, b'\n') |
25244
cf90764f40a4
sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25243
diff
changeset
|
48 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
49 |
|
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
50 |
class doublepipe(object): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
51 |
"""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
|
52 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
53 |
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
|
54 |
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
|
55 |
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
|
56 |
call on the "main" pipe. |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
57 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
58 |
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
|
59 |
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
|
60 |
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
|
61 |
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
|
62 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
63 |
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
|
64 |
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
|
65 |
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
|
66 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
67 |
def __init__(self, ui, main, side): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
68 |
self._ui = ui |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
69 |
self._main = main |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
70 |
self._side = side |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
71 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
72 |
def _wait(self): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
73 |
"""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
|
74 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
75 |
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
|
76 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
77 |
(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
|
78 |
""" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
79 |
if ( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
80 |
isinstance(self._main, util.bufferedinputpipe) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
81 |
and self._main.hasbuffer |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
82 |
): |
36369
066e6a9d52bb
sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36367
diff
changeset
|
83 |
# 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
|
84 |
return True, True |
066e6a9d52bb
sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36367
diff
changeset
|
85 |
|
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
86 |
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
|
87 |
try: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
88 |
act = util.poll(fds) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
89 |
except NotImplementedError: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
90 |
# 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
|
91 |
act = fds |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
92 |
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
|
93 |
|
25456
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
94 |
def write(self, data): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
95 |
return self._call(b'write', data) |
25456
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
96 |
|
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
97 |
def read(self, size): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
98 |
r = self._call(b'read', size) |
32062
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
99 |
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
|
100 |
# 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
|
101 |
# 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
|
102 |
# 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
|
103 |
# 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
|
104 |
# closed prematurely. |
ad6c5497cd15
sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents:
31953
diff
changeset
|
105 |
_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
|
106 |
return r |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
107 |
|
38713
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
108 |
def unbufferedread(self, size): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
109 |
r = self._call(b'unbufferedread', size) |
38713
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
110 |
if size != 0 and not r: |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
111 |
# We've observed a condition that indicates the |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
112 |
# stdout closed unexpectedly. Check stderr one |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
113 |
# more time and snag anything that's there before |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
114 |
# letting anyone know the main part of the pipe |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
115 |
# closed prematurely. |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
116 |
_forwardoutput(self._ui, self._side) |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
117 |
return r |
27391d74aaa2
ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents:
38475
diff
changeset
|
118 |
|
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
119 |
def readline(self): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
120 |
return self._call(b'readline') |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
121 |
|
25455
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
122 |
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
|
123 |
"""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
|
124 |
""" |
25455
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
125 |
# 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
|
126 |
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
|
127 |
_forwardoutput(self._ui, self._side) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
128 |
return b'' |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
129 |
while True: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
130 |
mainready, sideready = self._wait() |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
131 |
if sideready: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
132 |
_forwardoutput(self._ui, self._side) |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
133 |
if mainready: |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
134 |
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
|
135 |
if data is None: |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
136 |
return meth() |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
137 |
else: |
25455
dc02a284e034
sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25422
diff
changeset
|
138 |
return meth(data) |
25421
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
139 |
|
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
140 |
def close(self): |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
141 |
return self._main.close() |
3dd3ccf7b807
sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25408
diff
changeset
|
142 |
|
25456
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
143 |
def flush(self): |
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
144 |
return self._main.flush() |
408b7979bf03
sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25455
diff
changeset
|
145 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
146 |
|
35933
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
147 |
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
|
148 |
"""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
|
149 |
if pipeo: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
150 |
pipeo.close() |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
151 |
if pipei: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
152 |
pipei.close() |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
153 |
|
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
154 |
if pipee: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
155 |
# 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
|
156 |
try: |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
157 |
for l in pipee: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
158 |
ui.status(_(b'remote: '), l) |
35933
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
159 |
except (IOError, ValueError): |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
160 |
pass |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
161 |
|
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
162 |
pipee.close() |
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
163 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
164 |
|
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
165 |
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
|
166 |
"""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
|
167 |
|
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
168 |
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
|
169 |
spawned process. |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
170 |
""" |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
171 |
cmd = b'%s %s %s' % ( |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
172 |
sshcmd, |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
173 |
args, |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
174 |
procutil.shellquote( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
175 |
b'%s -R %s serve --stdio' |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
176 |
% (_serverquote(remotecmd), _serverquote(path)) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
177 |
), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
178 |
) |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
179 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
180 |
ui.debug(b'running %s\n' % cmd) |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
181 |
cmd = procutil.quotecommand(cmd) |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
182 |
|
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
183 |
# 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
|
184 |
# 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
|
185 |
# move to threading. |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
186 |
stdin, stdout, stderr, proc = procutil.popen4(cmd, bufsize=0, env=sshenv) |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
187 |
|
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
188 |
return proc, stdin, stdout, stderr |
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
189 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
190 |
|
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
191 |
def _clientcapabilities(): |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
192 |
"""Return list of capabilities of this client. |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
193 |
|
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
194 |
Returns a list of capabilities that are supported by this client. |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
195 |
""" |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
196 |
protoparams = {b'partial-pull'} |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
197 |
comps = [ |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
198 |
e.wireprotosupport().name |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
199 |
for e in util.compengines.supportedwireengines(util.CLIENTROLE) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
200 |
] |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
201 |
protoparams.add(b'comp=%s' % b','.join(comps)) |
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
202 |
return protoparams |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
203 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
204 |
|
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
205 |
def _performhandshake(ui, stdin, stdout, stderr): |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
206 |
def badresponse(): |
36370
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
207 |
# Flush any output on stderr. |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
208 |
_forwardoutput(ui, stderr) |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
209 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
210 |
msg = _(b'no suitable response from remote hg') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
211 |
hint = ui.config(b'ui', b'ssherrorhint') |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
212 |
raise error.RepoError(msg, hint=hint) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
213 |
|
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
214 |
# 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
|
215 |
# 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
|
216 |
# to one of them. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
217 |
# |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
218 |
# Those commands (from oldest to newest) are: |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
219 |
# |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
220 |
# ``between`` |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
221 |
# 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
|
222 |
# present in all Mercurial server implementations. |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
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 |
# ``hello`` |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
225 |
# 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
|
226 |
# Mercurial 0.9.1. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
227 |
# |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
228 |
# ``upgrade`` |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
229 |
# 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
|
230 |
# 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
|
231 |
# feature. |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
232 |
# |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
233 |
# 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
|
234 |
# 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
|
235 |
# 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
|
236 |
# 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
|
237 |
# 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
|
238 |
# 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
|
239 |
# |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
240 |
# 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
|
241 |
# 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
|
242 |
# 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
|
243 |
# 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
|
244 |
# 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
|
245 |
# the capabilities of the server. |
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
246 |
# |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
247 |
# 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
|
248 |
# 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
|
249 |
# 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
|
250 |
# 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
|
251 |
# |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
252 |
# 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
|
253 |
# 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
|
254 |
# 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
|
255 |
# ``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
|
256 |
# 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
|
257 |
# protocol and server state. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
258 |
# |
35939
a622a927fe03
sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35938
diff
changeset
|
259 |
# 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
|
260 |
# 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
|
261 |
# 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
|
262 |
# 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
|
263 |
# 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
|
264 |
# 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
|
265 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
266 |
requestlog = ui.configbool(b'devel', b'debug.peer-request') |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
267 |
|
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
268 |
# 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
|
269 |
# upgrade request. |
36043
223ed0b53f08
py3: more robustly cast UUID to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35978
diff
changeset
|
270 |
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
|
271 |
upgradecaps = [ |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
272 |
(b'proto', wireprotoserver.SSHV2), |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
273 |
] |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
274 |
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
|
275 |
|
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
276 |
try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
277 |
pairsarg = b'%s-%s' % (b'0' * 40, b'0' * 40) |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
278 |
handshake = [ |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
279 |
b'hello\n', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
280 |
b'between\n', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
281 |
b'pairs %d\n' % len(pairsarg), |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
282 |
pairsarg, |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
283 |
] |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
284 |
|
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
285 |
# Request upgrade to version 2 if configured. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
286 |
if ui.configbool(b'experimental', b'sshpeer.advertise-v2'): |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
287 |
ui.debug(b'sending upgrade request: %s %s\n' % (token, upgradecaps)) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
288 |
handshake.insert(0, b'upgrade %s %s\n' % (token, upgradecaps)) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
289 |
|
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
290 |
if requestlog: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
291 |
ui.debug(b'devel-peer-request: hello+between\n') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
292 |
ui.debug(b'devel-peer-request: pairs: %d bytes\n' % len(pairsarg)) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
293 |
ui.debug(b'sending hello command\n') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
294 |
ui.debug(b'sending between command\n') |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
295 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
296 |
stdin.write(b''.join(handshake)) |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
297 |
stdin.flush() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
298 |
except IOError: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
299 |
badresponse() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
300 |
|
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
301 |
# Assume version 1 of wire protocol by default. |
36536
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36533
diff
changeset
|
302 |
protoname = wireprototypes.SSHV1 |
38475
67dc32d4e790
cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents:
37813
diff
changeset
|
303 |
reupgraded = re.compile(b'^upgraded %s (.*)$' % stringutil.reescape(token)) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
304 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
305 |
lines = [b'', b'dummy'] |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
306 |
max_noise = 500 |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
307 |
while lines[-1] and max_noise: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
308 |
try: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
309 |
l = stdout.readline() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
310 |
_forwardoutput(ui, stderr) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
311 |
|
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
312 |
# 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
|
313 |
# 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
|
314 |
m = reupgraded.match(l) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
315 |
if m: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
316 |
protoname = m.group(1) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
317 |
ui.debug(b'protocol upgraded to %s\n' % protoname) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
318 |
# 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
|
319 |
# 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
|
320 |
# 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
|
321 |
break |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
322 |
|
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
323 |
# 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
|
324 |
# doesn't support upgrade. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
325 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
326 |
if lines[-1] == b'1\n' and l == b'\n': |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
327 |
break |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
328 |
if l: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
329 |
ui.debug(b'remote: ', l) |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
330 |
lines.append(l) |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
331 |
max_noise -= 1 |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
332 |
except IOError: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
333 |
badresponse() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
334 |
else: |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
335 |
badresponse() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
336 |
|
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
337 |
caps = set() |
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
338 |
|
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
339 |
# 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
|
340 |
# ``hello`` command. |
36536
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36533
diff
changeset
|
341 |
if protoname == wireprototypes.SSHV1: |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
342 |
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
|
343 |
# 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
|
344 |
# we don't misinterpret banner output as the command reply. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
345 |
if l.startswith(b'capabilities:'): |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
346 |
caps.update(l[:-1].split(b':')[1].split()) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
347 |
break |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
348 |
elif protoname == wireprotoserver.SSHV2: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
349 |
# 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
|
350 |
# looking like ``capabilities: *``. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
351 |
line = stdout.readline() |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
352 |
try: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
353 |
valuelen = int(line) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
354 |
except ValueError: |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
355 |
badresponse() |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
356 |
|
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
357 |
capsline = stdout.read(valuelen) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
358 |
if not capsline.startswith(b'capabilities: '): |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
359 |
badresponse() |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
360 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
361 |
ui.debug(b'remote: %s\n' % capsline) |
36216
7218e93ade47
sshpeer: log remote capabilities after protocol upgrade
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36043
diff
changeset
|
362 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
363 |
caps.update(capsline.split(b':')[1].split()) |
35976
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
364 |
# Trailing newline. |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
365 |
stdout.read(1) |
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
366 |
|
48a3a9283f09
sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35940
diff
changeset
|
367 |
# 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
|
368 |
# |
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
369 |
# 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
|
370 |
# 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
|
371 |
# 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
|
372 |
# 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
|
373 |
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
|
374 |
badresponse() |
556218e08e25
sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35939
diff
changeset
|
375 |
|
36370
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
376 |
# 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
|
377 |
_forwardoutput(ui, stderr) |
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
378 |
|
35978
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
379 |
return protoname, caps |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
380 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
381 |
|
37614
a81d02ea65db
wireproto: move version 1 peer functionality to standalone module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
382 |
class sshv1peer(wireprotov1peer.wirepeer): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
383 |
def __init__( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
384 |
self, ui, url, proc, stdin, stdout, stderr, caps, autoreadstderr=True |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
385 |
): |
35936
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
386 |
"""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
|
387 |
|
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
388 |
``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
|
389 |
``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
|
390 |
pipes for that process. |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
391 |
``caps`` is a set of capabilities supported by the remote. |
36533
1a36ef7df70a
sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36487
diff
changeset
|
392 |
``autoreadstderr`` denotes whether to automatically read from |
1a36ef7df70a
sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36487
diff
changeset
|
393 |
stderr and to forward its output. |
35936
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
394 |
""" |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
395 |
self._url = url |
37321
e826fe7a08c7
peer: make ui an attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37320
diff
changeset
|
396 |
self.ui = ui |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
397 |
# 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
|
398 |
# 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
|
399 |
self._subprocess = proc |
36370
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
400 |
|
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
401 |
# 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
|
402 |
# stderr any time we perform I/O. |
36533
1a36ef7df70a
sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36487
diff
changeset
|
403 |
if autoreadstderr: |
1a36ef7df70a
sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36487
diff
changeset
|
404 |
stdout = doublepipe(ui, util.bufferedinputpipe(stdout), stderr) |
1a36ef7df70a
sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36487
diff
changeset
|
405 |
stdin = doublepipe(ui, stdin, stderr) |
36370
11ba1a96f946
sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36369
diff
changeset
|
406 |
|
35936
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
407 |
self._pipeo = stdin |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
408 |
self._pipei = stdout |
f8f034344b39
sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35935
diff
changeset
|
409 |
self._pipee = stderr |
35938
80a2b8ae42a1
sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35937
diff
changeset
|
410 |
self._caps = caps |
36608
1151c731686e
sshpeer: don't read from stderr when that behavior is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36536
diff
changeset
|
411 |
self._autoreadstderr = autoreadstderr |
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
|
412 |
|
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
413 |
# 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
|
414 |
# 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
|
415 |
_FRAMED_COMMANDS = { |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
416 |
b'batch', |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
417 |
} |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
418 |
|
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37120
diff
changeset
|
419 |
# Begin of ipeerconnection interface. |
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
420 |
|
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
421 |
def url(self): |
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
422 |
return self._url |
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
423 |
|
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
424 |
def local(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
425 |
return None |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
426 |
|
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
427 |
def peer(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
428 |
return self |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
429 |
|
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
430 |
def canpush(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
431 |
return True |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
432 |
|
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
433 |
def close(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
434 |
pass |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
435 |
|
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37120
diff
changeset
|
436 |
# End of ipeerconnection interface. |
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
437 |
|
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37120
diff
changeset
|
438 |
# Begin of ipeercommands interface. |
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
439 |
|
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
440 |
def capabilities(self): |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
441 |
return self._caps |
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
442 |
|
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37120
diff
changeset
|
443 |
# End of ipeercommands interface. |
33804
1f8460b55986
sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33768
diff
changeset
|
444 |
|
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
445 |
def _readerr(self): |
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
446 |
_forwardoutput(self.ui, self._pipee) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
447 |
|
11586
ddaaaa23bb8f
protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents:
11369
diff
changeset
|
448 |
def _abort(self, exception): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
449 |
self._cleanup() |
11586
ddaaaa23bb8f
protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents:
11369
diff
changeset
|
450 |
raise exception |
ddaaaa23bb8f
protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents:
11369
diff
changeset
|
451 |
|
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
452 |
def _cleanup(self): |
35933
805edf16e8e0
sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35932
diff
changeset
|
453 |
_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
|
454 |
|
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
455 |
__del__ = _cleanup |
3034
2b0bc36a48d8
sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2859
diff
changeset
|
456 |
|
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
457 |
def _sendrequest(self, cmd, args, framed=False): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
458 |
if self.ui.debugflag and self.ui.configbool( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
459 |
b'devel', b'debug.peer-request' |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
460 |
): |
35699
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
461 |
dbg = self.ui.debug |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
462 |
line = b'devel-peer-request: %s\n' |
35699
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
463 |
dbg(line % cmd) |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
464 |
for key, value in sorted(args.items()): |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
465 |
if not isinstance(value, dict): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
466 |
dbg(line % b' %s: %d bytes' % (key, len(value))) |
35699
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
467 |
else: |
f7ef49e44d7c
sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents:
35459
diff
changeset
|
468 |
for dk, dv in sorted(value.items()): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
469 |
dbg(line % b' %s-%s: %d' % (key, dk, len(dv))) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
470 |
self.ui.debug(b"sending %s command\n" % cmd) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
471 |
self._pipeo.write(b"%s\n" % cmd) |
37785
b4d85bc122bd
wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37717
diff
changeset
|
472 |
_func, names = wireprotov1server.commands[cmd] |
13721
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
473 |
keys = names.split() |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
474 |
wireargs = {} |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
475 |
for k in keys: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
476 |
if k == b'*': |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
477 |
wireargs[b'*'] = args |
13721
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
478 |
break |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
479 |
else: |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
480 |
wireargs[k] = args[k] |
3458c15ab2f0
wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13464
diff
changeset
|
481 |
del args[k] |
43106
d783f945a701
py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43089
diff
changeset
|
482 |
for k, v in sorted(pycompat.iteritems(wireargs)): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
483 |
self._pipeo.write(b"%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
|
484 |
if isinstance(v, dict): |
43106
d783f945a701
py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43089
diff
changeset
|
485 |
for dk, dv in pycompat.iteritems(v): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
486 |
self._pipeo.write(b"%s %d\n" % (dk, len(dv))) |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
487 |
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
|
488 |
else: |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
489 |
self._pipeo.write(v) |
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
490 |
self._pipeo.flush() |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
491 |
|
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
492 |
# 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
|
493 |
# 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
|
494 |
# 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
|
495 |
# response. |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
496 |
if framed: |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
497 |
amount = self._getamount() |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
498 |
return util.cappedreader(self._pipei, amount) |
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
499 |
|
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
500 |
return self._pipei |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
501 |
|
36366
a34d5ef53c2e
sshpeer: move logic for sending a request into a new function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36363
diff
changeset
|
502 |
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
|
503 |
args = pycompat.byteskwargs(args) |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
504 |
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
|
505 |
|
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
|
506 |
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
|
507 |
args = pycompat.byteskwargs(args) |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
508 |
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
|
509 |
|
11589
e8d22fe2ddab
protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents:
11588
diff
changeset
|
510 |
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
|
511 |
args = pycompat.byteskwargs(args) |
36367
043e77f3be09
sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36366
diff
changeset
|
512 |
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
|
513 |
|
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
514 |
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
|
515 |
# 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
|
516 |
# continue submitting the payload. |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
517 |
r = self._call(cmd, **args) |
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
518 |
if r: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
519 |
return b'', r |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
520 |
|
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
521 |
# 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
|
522 |
# frame. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
523 |
for d in iter(lambda: fp.read(4096), b''): |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
524 |
self._writeframed(d) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
525 |
self._writeframed(b"", flush=True) |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
526 |
|
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
527 |
# 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
|
528 |
# 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
|
529 |
# 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
|
530 |
r = self._readframed() |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
531 |
if r: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
532 |
return b'', r |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
533 |
return self._readframed(), b'' |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
534 |
|
21073
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
535 |
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
|
536 |
# 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
|
537 |
# continue submitting the payload. |
21073
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
538 |
r = self._call(cmd, **args) |
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
539 |
if r: |
83ce71ef7804
sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
540 |
# XXX needs to be made better |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
541 |
raise error.Abort(_(b'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
|
542 |
|
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
543 |
# 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
|
544 |
# frame. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
545 |
for d in iter(lambda: fp.read(4096), b''): |
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
546 |
self._writeframed(d) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
547 |
self._writeframed(b"", flush=True) |
36372
b8d0761a85c7
wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36370
diff
changeset
|
548 |
|
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
549 |
return self._pipei |
11591
0d9cb3f3b0a1
protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents:
11590
diff
changeset
|
550 |
|
28438
48fd02dac1d4
wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents:
27798
diff
changeset
|
551 |
def _getamount(self): |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
552 |
l = self._pipei.readline() |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
553 |
if l == b'\n': |
36608
1151c731686e
sshpeer: don't read from stderr when that behavior is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36536
diff
changeset
|
554 |
if self._autoreadstderr: |
1151c731686e
sshpeer: don't read from stderr when that behavior is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36536
diff
changeset
|
555 |
self._readerr() |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
556 |
msg = _(b'check previous remote output') |
25243
d65243d28749
sshpeer: break "OutOfBandError" feature for ssh (BC)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23684
diff
changeset
|
557 |
self._abort(error.OutOfBandError(hint=msg)) |
36608
1151c731686e
sshpeer: don't read from stderr when that behavior is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36536
diff
changeset
|
558 |
if self._autoreadstderr: |
1151c731686e
sshpeer: don't read from stderr when that behavior is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36536
diff
changeset
|
559 |
self._readerr() |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
560 |
try: |
28438
48fd02dac1d4
wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents:
27798
diff
changeset
|
561 |
return int(l) |
14004
97ed99d1f419
eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents:
13827
diff
changeset
|
562 |
except ValueError: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
563 |
self._abort(error.ResponseError(_(b"unexpected response:"), l)) |
28438
48fd02dac1d4
wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents:
27798
diff
changeset
|
564 |
|
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
565 |
def _readframed(self): |
36628
70415568ea65
sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36608
diff
changeset
|
566 |
size = self._getamount() |
70415568ea65
sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36608
diff
changeset
|
567 |
if not size: |
70415568ea65
sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36608
diff
changeset
|
568 |
return b'' |
70415568ea65
sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36608
diff
changeset
|
569 |
|
70415568ea65
sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36608
diff
changeset
|
570 |
return self._pipei.read(size) |
5978
7939c71f3132
sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5293
diff
changeset
|
571 |
|
36363
7f8f74531b0b
sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36216
diff
changeset
|
572 |
def _writeframed(self, data, flush=False): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
573 |
self._pipeo.write(b"%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
|
574 |
if data: |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
575 |
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
|
576 |
if flush: |
33768
82d564d5ac4f
sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33737
diff
changeset
|
577 |
self._pipeo.flush() |
36608
1151c731686e
sshpeer: don't read from stderr when that behavior is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36536
diff
changeset
|
578 |
if self._autoreadstderr: |
1151c731686e
sshpeer: don't read from stderr when that behavior is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36536
diff
changeset
|
579 |
self._readerr() |
2612
ffb895f16925
add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2549
diff
changeset
|
580 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
581 |
|
35978
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
582 |
class sshv2peer(sshv1peer): |
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
583 |
"""A peer that speakers version 2 of the transport protocol.""" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
584 |
|
35978
59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35977
diff
changeset
|
585 |
# 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
|
586 |
# 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
|
587 |
# 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
|
588 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
589 |
|
36533
1a36ef7df70a
sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36487
diff
changeset
|
590 |
def makepeer(ui, path, proc, stdin, stdout, stderr, autoreadstderr=True): |
36487
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
591 |
"""Make a peer instance from existing pipes. |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
592 |
|
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
593 |
``path`` and ``proc`` are stored on the eventual peer instance and may |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
594 |
not be used for anything meaningful. |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
595 |
|
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
596 |
``stdin``, ``stdout``, and ``stderr`` are the pipes connected to the |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
597 |
SSH server's stdio handles. |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
598 |
|
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
599 |
This function is factored out to allow creating peers that don't |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
600 |
actually spawn a new process. It is useful for starting SSH protocol |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
601 |
servers and clients via non-standard means, which can be useful for |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
602 |
testing. |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
603 |
""" |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
604 |
try: |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
605 |
protoname, caps = _performhandshake(ui, stdin, stdout, stderr) |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
606 |
except Exception: |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
607 |
_cleanuppipes(ui, stdout, stdin, stderr) |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
608 |
raise |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
609 |
|
36536
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36533
diff
changeset
|
610 |
if protoname == wireprototypes.SSHV1: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
611 |
return sshv1peer( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
612 |
ui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
613 |
path, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
614 |
proc, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
615 |
stdin, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
616 |
stdout, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
617 |
stderr, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
618 |
caps, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
619 |
autoreadstderr=autoreadstderr, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
620 |
) |
36536
3cd245945ef3
wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36533
diff
changeset
|
621 |
elif protoname == wireprototypes.SSHV2: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
622 |
return sshv2peer( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
623 |
ui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
624 |
path, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
625 |
proc, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
626 |
stdin, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
627 |
stdout, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
628 |
stderr, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
629 |
caps, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
630 |
autoreadstderr=autoreadstderr, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
631 |
) |
36487
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
632 |
else: |
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
633 |
_cleanuppipes(ui, stdout, stdin, stderr) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
634 |
raise error.RepoError( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
635 |
_(b'unknown version of SSH protocol: %s') % protoname |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
636 |
) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
637 |
|
36487
dabf86721200
sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36372
diff
changeset
|
638 |
|
39549
089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38713
diff
changeset
|
639 |
def instance(ui, path, create, intents=None, createopts=None): |
35931
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
640 |
"""Create an SSH peer. |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
641 |
|
37614
a81d02ea65db
wireproto: move version 1 peer functionality to standalone module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
642 |
The returned object conforms to the ``wireprotov1peer.wirepeer`` interface. |
35931
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
643 |
""" |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
644 |
u = util.url(path, parsequery=False, parsefragment=False) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
645 |
if u.scheme != b'ssh' or not u.host or u.path is None: |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
646 |
raise error.RepoError(_(b"couldn't parse location %s") % path) |
35931
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
647 |
|
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
648 |
util.checksafessh(path) |
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
649 |
|
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
650 |
if u.passwd is not None: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
651 |
raise error.RepoError(_(b'password in URL not supported')) |
35931
b202d360d2a4
sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35928
diff
changeset
|
652 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
653 |
sshcmd = ui.config(b'ui', b'ssh') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
654 |
remotecmd = ui.config(b'ui', b'remotecmd') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
655 |
sshaddenv = dict(ui.configitems(b'sshenv')) |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
656 |
sshenv = procutil.shellenviron(sshaddenv) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
657 |
remotepath = u.path or b'.' |
35932
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
658 |
|
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36833
diff
changeset
|
659 |
args = procutil.sshargs(sshcmd, u.host, u.user, u.port) |
35932
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
660 |
|
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
661 |
if create: |
39549
089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38713
diff
changeset
|
662 |
# We /could/ do this, but only if the remote init command knows how to |
089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38713
diff
changeset
|
663 |
# handle them. We don't yet make any assumptions about that. And without |
089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38713
diff
changeset
|
664 |
# querying the remote, there's no way of knowing if the remote even |
089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38713
diff
changeset
|
665 |
# supports said requested feature. |
089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38713
diff
changeset
|
666 |
if createopts: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
667 |
raise error.RepoError( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
668 |
_( |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
669 |
b'cannot create remote SSH repositories ' |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
670 |
b'with extra options' |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
671 |
) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
672 |
) |
39549
089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38713
diff
changeset
|
673 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
674 |
cmd = b'%s %s %s' % ( |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
675 |
sshcmd, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
676 |
args, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
677 |
procutil.shellquote( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
678 |
b'%s init %s' |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
679 |
% (_serverquote(remotecmd), _serverquote(remotepath)) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
680 |
), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
681 |
) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
682 |
ui.debug(b'running %s\n' % cmd) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
683 |
res = ui.system(cmd, blockedtag=b'sshpeer', environ=sshenv) |
35932
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
684 |
if res != 0: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
685 |
raise error.RepoError(_(b'could not create remote repo')) |
35932
31449baf0936
sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35931
diff
changeset
|
686 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
687 |
proc, stdin, stdout, stderr = _makeconnection( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
688 |
ui, sshcmd, args, remotecmd, remotepath, sshenv |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
689 |
) |
35935
00b9e26d727b
sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35934
diff
changeset
|
690 |
|
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
691 |
peer = makepeer(ui, path, proc, stdin, stdout, stderr) |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
692 |
|
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
693 |
# Finally, if supported by the server, notify it about our own |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
694 |
# capabilities. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
695 |
if b'protocaps' in peer.capabilities(): |
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
696 |
try: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
697 |
peer._call( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
698 |
b"protocaps", caps=b' '.join(sorted(_clientcapabilities())) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
39549
diff
changeset
|
699 |
) |
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
700 |
except IOError: |
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
701 |
peer._cleanup() |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
702 |
raise error.RepoError(_(b'capability exchange failed')) |
37393
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
703 |
|
afcfdf53e4b5
wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
704 |
return peer |