annotate mercurial/sshpeer.py @ 47387:75e1104f23a2

revlog: use dedicated code for reading sidedata We are about to introduce a new, dedicated, file to store sidedata. Before doing so, we make sidedata reading go through different code as reading data chunk. This will simplify some of the complexity of the next changesets. The reading is very simple right now and will need some improvement later to reuse some of the caching strategy we use for the data file. Differential Revision: https://phab.mercurial-scm.org/D10785
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 27 May 2021 04:09:30 +0200
parents ffd3e823a7e5
children 04688c51f81f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
17192
1ac628cd7113 peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 16688
diff changeset
1 # sshpeer.py - ssh repository proxy class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46671
diff changeset
3 # Copyright 2005, 2006 Olivia Mackall <olivia@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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9878
diff changeset
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,
46907
ffd3e823a7e5 urlutil: extract `url` related code from `util` into the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
27 urlutil,
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36833
diff changeset
28 )
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
29
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
30
15581
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
31 def _serverquote(s):
35459
b520c8f98e1e sshpeer: move docstring to top
Yuya Nishihara <yuya@tcha.org>
parents: 35436
diff changeset
32 """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
33 if not s:
e3f30068d2eb sshpeer: more thorough shell quoting
Matt Mackall <mpm@selenic.com>
parents: 22935
diff changeset
34 return s
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
35 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
36 return s
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
37 return b"'%s'" % s.replace(b"'", b"'\\''")
15581
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
38
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
39
44860
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
40 def _forwardoutput(ui, pipe, warn=False):
25244
cf90764f40a4 sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25243
diff changeset
41 """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
42
cf90764f40a4 sshpeer: extract the forward output logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25243
diff changeset
43 This is non blocking."""
46671
fa30292b680b sshpeer: don't fail forwarding output from closed connections
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 46663
diff changeset
44 if pipe and not pipe.closed:
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36833
diff changeset
45 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
46 if s:
44860
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
47 display = ui.warn if warn else ui.status
36833
46f4d71ed505 sshpeer: check pipe validity before forwarding output from it
Matt Harbison <matt_harbison@yahoo.com>
parents: 36628
diff changeset
48 for l in s.splitlines():
44860
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
49 display(_(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
50
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
51
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
52 class doublepipe(object):
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
53 """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
54
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
55 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
56 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
57 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
58 call on the "main" pipe.
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
59
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
60 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
61 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
62 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
63 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
64
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
65 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
66 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
67 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
68
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
69 def __init__(self, ui, main, side):
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
70 self._ui = ui
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
71 self._main = main
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
72 self._side = side
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
73
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
74 def _wait(self):
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
75 """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
76
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
77 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
78
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
79 (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
80 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
81 if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
82 isinstance(self._main, util.bufferedinputpipe)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
83 and self._main.hasbuffer
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
84 ):
36369
066e6a9d52bb sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36367
diff changeset
85 # 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
86 return True, True
066e6a9d52bb sshpeer: make pipe polling code more explicit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36367
diff changeset
87
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
88 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
89 try:
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
90 act = util.poll(fds)
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
91 except NotImplementedError:
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
92 # 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
93 act = fds
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
94 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
95
25456
408b7979bf03 sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25455
diff changeset
96 def write(self, data):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
97 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
98
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
99 def read(self, size):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
100 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
101 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
102 # 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
103 # 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
104 # 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
105 # 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
106 # closed prematurely.
ad6c5497cd15 sshpeer: try harder to snag stderr when stdout closes unexpectedly
Augie Fackler <augie@google.com>
parents: 31953
diff changeset
107 _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
108 return r
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
109
38713
27391d74aaa2 ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents: 38475
diff changeset
110 def unbufferedread(self, size):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
111 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
112 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
113 # 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
114 # 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
115 # 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
116 # 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
117 # closed prematurely.
27391d74aaa2 ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents: 38475
diff changeset
118 _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
119 return r
27391d74aaa2 ssh: avoid reading beyond the end of stream when using compression
Joerg Sonnenberger <joerg@bec.de>
parents: 38475
diff changeset
120
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
121 def readline(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
122 return self._call(b'readline')
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
123
25455
dc02a284e034 sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25422
diff changeset
124 def _call(self, methname, data=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44867
diff changeset
125 """call <methname> on "main", forward output of "side" while blocking"""
25455
dc02a284e034 sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25422
diff changeset
126 # 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
127 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
128 _forwardoutput(self._ui, self._side)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
129 return b''
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
130 while True:
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
131 mainready, sideready = self._wait()
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
132 if sideready:
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
133 _forwardoutput(self._ui, self._side)
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
134 if mainready:
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
135 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
136 if data is None:
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
137 return meth()
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
138 else:
25455
dc02a284e034 sshpeer: rename 'size' to 'data' in doublepipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25422
diff changeset
139 return meth(data)
25421
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
140
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
141 def close(self):
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
142 return self._main.close()
3dd3ccf7b807 sshpeer: introduce a "doublepipe" class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25408
diff changeset
143
46660
0738bc25d6ac sshpeer: add a method to check if a doublepipe is closed
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46659
diff changeset
144 @property
0738bc25d6ac sshpeer: add a method to check if a doublepipe is closed
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46659
diff changeset
145 def closed(self):
0738bc25d6ac sshpeer: add a method to check if a doublepipe is closed
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46659
diff changeset
146 return self._main.closed
0738bc25d6ac sshpeer: add a method to check if a doublepipe is closed
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46659
diff changeset
147
25456
408b7979bf03 sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25455
diff changeset
148 def flush(self):
408b7979bf03 sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25455
diff changeset
149 return self._main.flush()
408b7979bf03 sshpeer: allow write operations through double pipe
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25455
diff changeset
150
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
151
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
152 def _cleanuppipes(ui, pipei, pipeo, pipee, warn):
35933
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
153 """Clean up pipes used by an SSH connection."""
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
154 didsomething = False
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
155 if pipeo and not pipeo.closed:
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
156 didsomething = True
35933
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
157 pipeo.close()
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
158 if pipei and not pipei.closed:
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
159 didsomething = True
35933
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
160 pipei.close()
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
161
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
162 if pipee and not pipee.closed:
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
163 didsomething = True
35933
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
164 # 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
165 try:
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
166 for l in pipee:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
167 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
168 except (IOError, ValueError):
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
169 pass
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
170
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
171 pipee.close()
805edf16e8e0 sshpeer: extract pipe cleanup logic to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35932
diff changeset
172
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
173 if didsomething and warn is not None:
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
174 # Encourage explicit close of sshpeers. Closing via __del__ is
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
175 # not very predictable when exceptions are thrown, which has led
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
176 # to deadlocks due to a peer get gc'ed in a fork
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
177 # We add our own stack trace, because the stacktrace when called
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
178 # from __del__ is useless.
46663
a4c19a162615 sshpeer: enable+fix warning about sshpeers not being closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46662
diff changeset
179 ui.develwarn(b'missing close on SSH connection created at:\n%s' % warn)
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
180
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
181
35935
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
182 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
183 """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
184
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
185 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
186 spawned process.
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
187 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
188 cmd = b'%s %s %s' % (
35935
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
189 sshcmd,
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
190 args,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
191 procutil.shellquote(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
192 b'%s -R %s serve --stdio'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
193 % (_serverquote(remotecmd), _serverquote(path))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
194 ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
195 )
35935
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
196
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
197 ui.debug(b'running %s\n' % cmd)
35935
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
198
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
199 # 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
200 # 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
201 # move to threading.
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36833
diff changeset
202 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
203
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
204 return proc, stdin, stdout, stderr
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
205
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
206
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
207 def _clientcapabilities():
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
208 """Return list of capabilities of this client.
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
209
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
210 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
211 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
212 protoparams = {b'partial-pull'}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
213 comps = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
214 e.wireprotosupport().name
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
215 for e in util.compengines.supportedwireengines(util.CLIENTROLE)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
216 ]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
217 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
218 return protoparams
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
219
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
220
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
221 def _performhandshake(ui, stdin, stdout, stderr):
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
222 def badresponse():
44860
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
223 # Flush any output on stderr. In general, the stderr contains errors
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
224 # from the remote (ssh errors, some hg errors), and status indications
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
225 # (like "adding changes"), with no current way to tell them apart.
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
226 # Here we failed so early that it's almost certainly only errors, so
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
227 # use warn=True so -q doesn't hide them.
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
228 _forwardoutput(ui, stderr, warn=True)
36370
11ba1a96f946 sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36369
diff changeset
229
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
230 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
231 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
232 raise error.RepoError(msg, hint=hint)
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
233
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
234 # 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
235 # 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
236 # to one of them.
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
237 #
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
238 # Those commands (from oldest to newest) are:
35939
a622a927fe03 sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35938
diff changeset
239 #
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
240 # ``between``
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
241 # 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
242 # present in all Mercurial server implementations.
35939
a622a927fe03 sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35938
diff changeset
243 #
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
244 # ``hello``
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
245 # 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
246 # Mercurial 0.9.1.
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
247 #
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
248 # ``upgrade``
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
249 # 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
250 # 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
251 # feature.
35939
a622a927fe03 sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35938
diff changeset
252 #
a622a927fe03 sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35938
diff changeset
253 # 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
254 # 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
255 # 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
256 # 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
257 # 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
258 # 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
259 #
a622a927fe03 sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35938
diff changeset
260 # 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
261 # 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
262 # 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
263 # 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
264 # 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
265 # the capabilities of the server.
a622a927fe03 sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35938
diff changeset
266 #
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
267 # 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
268 # 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
269 # 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
270 # 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
271 #
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
272 # 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
273 # 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
274 # 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
275 # ``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
276 # 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
277 # protocol and server state.
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
278 #
35939
a622a927fe03 sshpeer: document the handshake mechanism
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35938
diff changeset
279 # 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
280 # 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
281 # 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
282 # 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
283 # 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
284 # 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
285
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
286 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
287
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
288 # 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
289 # upgrade request.
36043
223ed0b53f08 py3: more robustly cast UUID to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35978
diff changeset
290 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
291 upgradecaps = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
292 (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
293 ]
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
294 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
295
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
296 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
297 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
298 handshake = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
299 b'hello\n',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
300 b'between\n',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
301 b'pairs %d\n' % len(pairsarg),
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
302 pairsarg,
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
303 ]
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
304
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
305 # 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
306 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
307 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
308 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
309
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
310 if requestlog:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
311 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
312 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
313 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
314 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
315
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
316 stdin.write(b''.join(handshake))
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
317 stdin.flush()
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
318 except IOError:
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
319 badresponse()
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
320
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
321 # 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
322 protoname = wireprototypes.SSHV1
38475
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 37813
diff changeset
323 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
324
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
325 lines = [b'', b'dummy']
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
326 max_noise = 500
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
327 while lines[-1] and max_noise:
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
328 try:
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
329 l = stdout.readline()
44860
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
330 _forwardoutput(ui, stderr, warn=True)
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
331
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
332 # 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
333 # 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
334 m = reupgraded.match(l)
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
335 if m:
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
336 protoname = m.group(1)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
337 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
338 # 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
339 # 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
340 # 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
341 break
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
342
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
343 # 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
344 # doesn't support upgrade.
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
345
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
346 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
347 break
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
348 if l:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
349 ui.debug(b'remote: ', l)
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
350 lines.append(l)
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
351 max_noise -= 1
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
352 except IOError:
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
353 badresponse()
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
354 else:
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
355 badresponse()
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
356
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
357 caps = set()
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
358
35976
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
359 # 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
360 # ``hello`` command.
36536
3cd245945ef3 wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36533
diff changeset
361 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
362 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
363 # 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
364 # 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
365 if l.startswith(b'capabilities:'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
366 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
367 break
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
368 elif protoname == wireprotoserver.SSHV2:
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
369 # 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
370 # looking like ``capabilities: *``.
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
371 line = stdout.readline()
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
372 try:
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
373 valuelen = int(line)
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
374 except ValueError:
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
375 badresponse()
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
376
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
377 capsline = stdout.read(valuelen)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
378 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
379 badresponse()
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
380
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
381 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
382
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
383 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
384 # Trailing newline.
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
385 stdout.read(1)
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
386
48a3a9283f09 sshpeer: initial definition and implementation of new SSH protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35940
diff changeset
387 # 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
388 #
556218e08e25 sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35939
diff changeset
389 # 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
390 # 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
391 # 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
392 # 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
393 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
394 badresponse()
556218e08e25 sshpeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35939
diff changeset
395
36370
11ba1a96f946 sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36369
diff changeset
396 # Flush any output on stderr before proceeding.
44860
5d77f571a563 sshpeer: make client print (likely) server errors on stderr (BC)
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43106
diff changeset
397 _forwardoutput(ui, stderr, warn=True)
36370
11ba1a96f946 sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36369
diff changeset
398
35978
59e4a7781a36 sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35977
diff changeset
399 return protoname, caps
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
400
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
401
37614
a81d02ea65db wireproto: move version 1 peer functionality to standalone module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37498
diff changeset
402 class sshv1peer(wireprotov1peer.wirepeer):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
403 def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
404 self, ui, url, proc, stdin, stdout, stderr, caps, autoreadstderr=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
405 ):
35936
f8f034344b39 sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35935
diff changeset
406 """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
407
f8f034344b39 sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35935
diff changeset
408 ``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
409 ``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
410 pipes for that process.
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
411 ``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
412 ``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
413 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
414 """
f8f034344b39 sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35935
diff changeset
415 self._url = url
37321
e826fe7a08c7 peer: make ui an attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37320
diff changeset
416 self.ui = ui
35935
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
417 # 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
418 # 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
419 self._subprocess = proc
36370
11ba1a96f946 sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36369
diff changeset
420
11ba1a96f946 sshpeer: defer pipe buffering and stderr sidechannel binding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36369
diff changeset
421 # 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
422 # 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
423 if autoreadstderr:
1a36ef7df70a sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36487
diff changeset
424 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
425 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
426
35936
f8f034344b39 sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35935
diff changeset
427 self._pipeo = stdin
f8f034344b39 sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35935
diff changeset
428 self._pipei = stdout
f8f034344b39 sshpeer: clean up API for sshpeer.__init__ (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35935
diff changeset
429 self._pipee = stderr
35938
80a2b8ae42a1 sshpeer: move handshake outside of sshpeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35937
diff changeset
430 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
431 self._autoreadstderr = autoreadstderr
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
432 self._initstack = b''.join(util.getstackframes(1))
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
433
36367
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
434 # 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
435 # 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
436 _FRAMED_COMMANDS = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
437 b'batch',
36367
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
438 }
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
439
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
440 # Begin of ipeerconnection interface.
33804
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
441
2673
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
442 def url(self):
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
443 return self._url
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
444
33804
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
445 def local(self):
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
446 return None
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
447
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
448 def peer(self):
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
449 return self
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
450
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
451 def canpush(self):
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
452 return True
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
453
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
454 def close(self):
46659
8c4906105f37 sshpeer: make sshpeer.close() close the underlying connection
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 45942
diff changeset
455 self._cleanup()
33804
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
456
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
457 # End of ipeerconnection interface.
33804
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
458
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
459 # Begin of ipeercommands interface.
33804
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
460
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
461 def capabilities(self):
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
462 return self._caps
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
463
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
464 # End of ipeercommands interface.
33804
1f8460b55986 sshpeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33768
diff changeset
465
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
466 def _readerr(self):
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
467 _forwardoutput(self.ui, self._pipee)
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
468
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
469 def _abort(self, exception):
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
470 self._cleanup()
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
471 raise exception
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
472
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
473 def _cleanup(self, warn=None):
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
474 _cleanuppipes(self.ui, self._pipei, self._pipeo, self._pipee, warn=warn)
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
475
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
476 def __del__(self):
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
477 self._cleanup(warn=self._initstack)
3034
2b0bc36a48d8 sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
478
36367
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
479 def _sendrequest(self, cmd, args, framed=False):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
480 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
481 b'devel', b'debug.peer-request'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
482 ):
35699
f7ef49e44d7c sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents: 35459
diff changeset
483 dbg = self.ui.debug
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
484 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
485 dbg(line % cmd)
f7ef49e44d7c sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents: 35459
diff changeset
486 for key, value in sorted(args.items()):
f7ef49e44d7c sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents: 35459
diff changeset
487 if not isinstance(value, dict):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
488 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
489 else:
f7ef49e44d7c sshpeer: add support for request tracing
Boris Feld <boris.feld@octobus.net>
parents: 35459
diff changeset
490 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
491 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
492 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
493 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
494 _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
495 keys = names.split()
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
496 wireargs = {}
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
497 for k in keys:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
498 if k == b'*':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
499 wireargs[b'*'] = args
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
500 break
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
501 else:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
502 wireargs[k] = args[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
503 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
504 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
505 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
506 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
507 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
508 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
509 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
510 else:
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
511 self._pipeo.write(v)
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
512 self._pipeo.flush()
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
513
36367
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
514 # 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
515 # 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
516 # 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
517 # response.
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
518 if framed:
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
519 amount = self._getamount()
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
520 return util.cappedreader(self._pipei, amount)
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
521
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
522 return self._pipei
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
523
36366
a34d5ef53c2e sshpeer: move logic for sending a request into a new function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36363
diff changeset
524 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
525 args = pycompat.byteskwargs(args)
36367
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
526 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
527
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
528 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
529 args = pycompat.byteskwargs(args)
36367
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
530 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
531
11589
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
532 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
533 args = pycompat.byteskwargs(args)
36367
043e77f3be09 sshpeer: return framed file object when needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36366
diff changeset
534 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
535
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
536 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
537 # 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
538 # continue submitting the payload.
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
539 r = self._call(cmd, **args)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
540 if r:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
541 return b'', 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
b8d0761a85c7 wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36370
diff changeset
549 # 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
550 # 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
551 # 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
552 r = self._readframed()
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
553 if r:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
554 return b'', r
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
555 return self._readframed(), b''
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
556
21073
83ce71ef7804 sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
557 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
558 # 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
559 # continue submitting the payload.
21073
83ce71ef7804 sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
560 r = self._call(cmd, **args)
83ce71ef7804 sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
561 if r:
83ce71ef7804 sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
562 # 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
563 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
564
b8d0761a85c7 wireproto: document the wonky push protocol for SSH
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36370
diff changeset
565 # 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
566 # frame.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
567 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
568 self._writeframed(d)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
569 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
570
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
571 return self._pipei
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11590
diff changeset
572
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 27798
diff changeset
573 def _getamount(self):
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
574 l = self._pipei.readline()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
575 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
576 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
577 self._readerr()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
578 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
579 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
580 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
581 self._readerr()
646
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
582 try:
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 27798
diff changeset
583 return int(l)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13827
diff changeset
584 except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
585 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
586
36363
7f8f74531b0b sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36216
diff changeset
587 def _readframed(self):
36628
70415568ea65 sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36608
diff changeset
588 size = self._getamount()
70415568ea65 sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36608
diff changeset
589 if not size:
70415568ea65 sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36608
diff changeset
590 return b''
70415568ea65 sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36608
diff changeset
591
70415568ea65 sshpeer: don't read(0)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36608
diff changeset
592 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
593
36363
7f8f74531b0b sshpeer: rename _recv and _send to _readframed and _writeframed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36216
diff changeset
594 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
595 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
596 if data:
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
597 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
598 if flush:
33768
82d564d5ac4f sshpeer: make instance attributes and methods internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33737
diff changeset
599 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
600 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
601 self._readerr()
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2549
diff changeset
602
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
603
35978
59e4a7781a36 sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35977
diff changeset
604 class sshv2peer(sshv1peer):
59e4a7781a36 sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35977
diff changeset
605 """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
606
35978
59e4a7781a36 sshpeer: implement peer for version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35977
diff changeset
607 # 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
608 # 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
609 # 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
610
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
611
36533
1a36ef7df70a sshpeer: support not reading and forwarding stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36487
diff changeset
612 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
613 """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
614
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
615 ``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
616 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
617
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
618 ``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
619 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
620
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
621 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
622 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
623 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
624 testing.
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
625 """
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
626 try:
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
627 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
628 except Exception:
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
629 _cleanuppipes(ui, stdout, stdin, stderr, warn=None)
36487
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
630 raise
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
631
36536
3cd245945ef3 wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36533
diff changeset
632 if protoname == wireprototypes.SSHV1:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
633 return sshv1peer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
634 ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
635 path,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
636 proc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
637 stdin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
638 stdout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
639 stderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
640 caps,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
641 autoreadstderr=autoreadstderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
642 )
36536
3cd245945ef3 wireprotoserver: move SSHV1 and SSHV2 constants to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36533
diff changeset
643 elif protoname == wireprototypes.SSHV2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
644 return sshv2peer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
645 ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
646 path,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
647 proc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
648 stdin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
649 stdout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
650 stderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
651 caps,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
652 autoreadstderr=autoreadstderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
653 )
36487
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
654 else:
46662
db8037e38085 sshpeer: add a develwarning if an sshpeer is not closed explicitly
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46660
diff changeset
655 _cleanuppipes(ui, stdout, stdin, stderr, warn=None)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
656 raise error.RepoError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
657 _(b'unknown version of SSH protocol: %s') % protoname
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
658 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
659
36487
dabf86721200 sshpeer: factor out code for creating peers from pipes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36372
diff changeset
660
39549
089fc0db0954 hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38713
diff changeset
661 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
662 """Create an SSH peer.
b202d360d2a4 sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35928
diff changeset
663
37614
a81d02ea65db wireproto: move version 1 peer functionality to standalone module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37498
diff changeset
664 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
665 """
46907
ffd3e823a7e5 urlutil: extract `url` related code from `util` into the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
666 u = urlutil.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
667 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
668 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
669
46907
ffd3e823a7e5 urlutil: extract `url` related code from `util` into the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
670 urlutil.checksafessh(path)
35931
b202d360d2a4 sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35928
diff changeset
671
b202d360d2a4 sshpeer: move URL validation out of sshpeer.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35928
diff changeset
672 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
673 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
674
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
675 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
676 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
677 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
678 sshenv = procutil.shellenviron(sshaddenv)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
679 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
680
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36833
diff changeset
681 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
682
31449baf0936 sshpeer: move ssh command and repo creation logic out of __init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35931
diff changeset
683 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
684 # 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
685 # 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
686 # 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
687 # 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
688 if createopts:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
689 raise error.RepoError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
690 _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
691 b'cannot create remote SSH repositories '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
692 b'with extra options'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
693 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
694 )
39549
089fc0db0954 hg: allow extra arguments to be passed to repo creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38713
diff changeset
695
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
696 cmd = b'%s %s %s' % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
697 sshcmd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
698 args,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
699 procutil.shellquote(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
700 b'%s init %s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
701 % (_serverquote(remotecmd), _serverquote(remotepath))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
702 ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
703 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
704 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
705 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
706 if res != 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
707 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
708
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
709 proc, stdin, stdout, stderr = _makeconnection(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
710 ui, sshcmd, args, remotecmd, remotepath, sshenv
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
711 )
35935
00b9e26d727b sshpeer: establish SSH connection before class instantiation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35934
diff changeset
712
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
713 peer = makepeer(ui, path, proc, stdin, stdout, stderr)
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
714
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
715 # 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
716 # capabilities.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
717 if b'protocaps' in peer.capabilities():
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
718 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
719 peer._call(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
720 b"protocaps", caps=b' '.join(sorted(_clientcapabilities()))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39549
diff changeset
721 )
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
722 except IOError:
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
723 peer._cleanup()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
724 raise error.RepoError(_(b'capability exchange failed'))
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
725
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37321
diff changeset
726 return peer