Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: third_party/twisted_8_1/twisted/conch/ssh/channel.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.conch.test.test_channel -*-
2 # Copyright (c) 2001-2008 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5 #
6 """
7 The parent class for all the SSH Channels. Currently implemented channels
8 are session. direct-tcp, and forwarded-tcp.
9
10 Maintainer: U{Paul Swartz<mailto:z3p@twistedmatrix.com>}
11 """
12
13 from twisted.python import log
14 from twisted.internet import interfaces
15 from zope.interface import implements
16
17
18 class SSHChannel(log.Logger):
19 """
20 A class that represents a multiplexed channel over an SSH connection.
21 The channel has a local window which is the maximum amount of data it will
22 receive, and a remote which is the maximum amount of data the remote side
23 will accept. There is also a maximum packet size for any individual data
24 packet going each way.
25
26 @ivar name: the name of the channel.
27 @type name: C{str}
28 @ivar localWindowSize: the maximum size of the local window in bytes.
29 @type localWindowSize: C{int}
30 @ivar localWindowLeft: how many bytes are left in the local window.
31 @type localWindowLeft: C{int}
32 @ivar localMaxPacket: the maximum size of packet we will accept in bytes.
33 @type localMaxPacket: C{int}
34 @ivar remoteWindowLeft: how many bytes are left in the remote window.
35 @type remoteWindowLeft: C{int}
36 @ivar remoteMaxPacket: the maximum size of a packet the remote side will
37 accept in bytes.
38 @type remoteMaxPacket: C{int}
39 @ivar conn: the connection this channel is multiplexed through.
40 @type conn: L{SSHConnection}
41 @ivar data: any data to send to the other size when the channel is
42 requested.
43 @type data: C{str}
44 @ivar avatar: an avatar for the logged-in user (if a server channel)
45 @ivar localClosed: True if we aren't accepting more data.
46 @type localClosed: C{bool}
47 @ivar remoteClosed: True if the other size isn't accepting more data.
48 @type remoteClosed: C{bool}
49 """
50
51 implements(interfaces.ITransport)
52
53 name = None # only needed for client channels
54
55 def __init__(self, localWindow = 0, localMaxPacket = 0,
56 remoteWindow = 0, remoteMaxPacket = 0,
57 conn = None, data=None, avatar = None):
58 self.localWindowSize = localWindow or 131072
59 self.localWindowLeft = self.localWindowSize
60 self.localMaxPacket = localMaxPacket or 32768
61 self.remoteWindowLeft = remoteWindow
62 self.remoteMaxPacket = remoteMaxPacket
63 self.areWriting = 1
64 self.conn = conn
65 self.data = data
66 self.avatar = avatar
67 self.specificData = ''
68 self.buf = ''
69 self.extBuf = []
70 self.closing = 0
71 self.localClosed = 0
72 self.remoteClosed = 0
73 self.id = None # gets set later by SSHConnection
74
75 def __str__(self):
76 return '<SSHChannel %s (lw %i rw %i)>' % (self.name,
77 self.localWindowLeft, self.remoteWindowLeft)
78
79 def logPrefix(self):
80 id = (self.id is not None and str(self.id)) or "unknown"
81 return "SSHChannel %s (%s) on %s" % (self.name, id,
82 self.conn.logPrefix())
83
84 def channelOpen(self, specificData):
85 """
86 Called when the channel is opened. specificData is any data that the
87 other side sent us when opening the channel.
88
89 @type specificData: C{str}
90 """
91 log.msg('channel open')
92
93 def openFailed(self, reason):
94 """
95 Called when the the open failed for some reason.
96 reason.desc is a string descrption, reason.code the the SSH error code.
97
98 @type reason: L{error.ConchError}
99 """
100 log.msg('other side refused open\nreason: %s'% reason)
101
102 def addWindowBytes(self, bytes):
103 """
104 Called when bytes are added to the remote window. By default it clears
105 the data buffers.
106
107 @type bytes: C{int}
108 """
109 self.remoteWindowLeft = self.remoteWindowLeft+bytes
110 if not self.areWriting and not self.closing:
111 self.areWriting = True
112 self.startWriting()
113 if self.buf:
114 b = self.buf
115 self.buf = ''
116 self.write(b)
117 if self.extBuf:
118 b = self.extBuf
119 self.extBuf = []
120 for (type, data) in b:
121 self.writeExtended(type, data)
122
123 def requestReceived(self, requestType, data):
124 """
125 Called when a request is sent to this channel. By default it delegates
126 to self.request_<requestType>.
127 If this function returns true, the request succeeded, otherwise it
128 failed.
129
130 @type requestType: C{str}
131 @type data: C{str}
132 @rtype: C{bool}
133 """
134 foo = requestType.replace('-', '_')
135 f = getattr(self, 'request_%s'%foo, None)
136 if f:
137 return f(data)
138 log.msg('unhandled request for %s'%requestType)
139 return 0
140
141 def dataReceived(self, data):
142 """
143 Called when we receive data.
144
145 @type data: C{str}
146 """
147 log.msg('got data %s'%repr(data))
148
149 def extReceived(self, dataType, data):
150 """
151 Called when we receive extended data (usually standard error).
152
153 @type dataType: C{int}
154 @type data: C{str}
155 """
156 log.msg('got extended data %s %s'%(dataType, repr(data)))
157
158 def eofReceived(self):
159 """
160 Called when the other side will send no more data.
161 """
162 log.msg('remote eof')
163
164 def closeReceived(self):
165 """
166 Called when the other side has closed the channel.
167 """
168 log.msg('remote close')
169 self.loseConnection()
170
171 def closed(self):
172 """
173 Called when the channel is closed. This means that both our side and
174 the remote side have closed the channel.
175 """
176 log.msg('closed')
177
178 # transport stuff
179 def write(self, data):
180 """
181 Write some data to the channel. If there is not enough remote window
182 available, buffer until it is. Otherwise, split the data into
183 packets of length remoteMaxPacket and send them.
184
185 @type data: C{str}
186 """
187 if self.buf:
188 self.buf += data
189 return
190 top = len(data)
191 if top > self.remoteWindowLeft:
192 data, self.buf = (data[:self.remoteWindowLeft],
193 data[self.remoteWindowLeft:])
194 self.areWriting = 0
195 self.stopWriting()
196 top = self.remoteWindowLeft
197 rmp = self.remoteMaxPacket
198 write = self.conn.sendData
199 r = range(0, top, rmp)
200 for offset in r:
201 write(self, data[offset: offset+rmp])
202 self.remoteWindowLeft -= top
203 if self.closing and not self.buf:
204 self.loseConnection() # try again
205
206 def writeExtended(self, dataType, data):
207 """
208 Send extended data to this channel. If there is not enough remote
209 window available, buffer until there is. Otherwise, split the data
210 into packets of length remoteMaxPacket and send them.
211
212 @type dataType: C{int}
213 @type data: C{str}
214 """
215 if self.extBuf:
216 if self.extBuf[-1][0] == dataType:
217 self.extBuf[-1][1] += data
218 else:
219 self.extBuf.append([dataType, data])
220 return
221 if len(data) > self.remoteWindowLeft:
222 data, self.extBuf = (data[:self.remoteWindowLeft],
223 [[dataType, data[self.remoteWindowLeft:]]])
224 self.areWriting = 0
225 self.stopWriting()
226 while len(data) > self.remoteMaxPacket:
227 self.conn.sendExtendedData(self, dataType,
228 data[:self.remoteMaxPacket])
229 data = data[self.remoteMaxPacket:]
230 self.remoteWindowLeft -= self.remoteMaxPacket
231 if data:
232 self.conn.sendExtendedData(self, dataType, data)
233 self.remoteWindowLeft -= len(data)
234 if self.closing:
235 self.loseConnection() # try again
236
237 def writeSequence(self, data):
238 """
239 Part of the Transport interface. Write a list of strings to the
240 channel.
241
242 @type data: C{list} of C{str}
243 """
244 self.write(''.join(data))
245
246 def loseConnection(self):
247 """
248 Close the channel if there is no buferred data. Otherwise, note the
249 request and return.
250 """
251 self.closing = 1
252 if not self.buf and not self.extBuf:
253 self.conn.sendClose(self)
254
255 def getPeer(self):
256 """
257 Return a tuple describing the other side of the connection.
258
259 @rtype: C{tuple}
260 """
261 return('SSH', )+self.conn.transport.getPeer()
262
263 def getHost(self):
264 """
265 Return a tuple describing our side of the connection.
266
267 @rtype: C{tuple}
268 """
269 return('SSH', )+self.conn.transport.getHost()
270
271 def stopWriting(self):
272 """
273 Called when the remote buffer is full, as a hint to stop writing.
274 This can be ignored, but it can be helpful.
275 """
276
277 def startWriting(self):
278 """
279 Called when the remote buffer has more room, as a hint to continue
280 writing.
281 """
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/conch/ssh/asn1.py ('k') | third_party/twisted_8_1/twisted/conch/ssh/common.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698