Represents a single SFTP session, running atop an SSH session.
- channel
- close
- close_channel
- connect
- do_attrs
- do_data
- do_handle
- do_name
- do_status
- get_file
- loop
- method_missing
- new
- open_handle
- put_file
- register
- respond_to?
- state
- support?
| [RW] | status | The status of the last synchronously executed operation. This is either nil, or an object that responds to :code, :message, and :language. |
[ show source ]
# File lib/net/sftp/session.rb, line 36
36: def initialize( session )
37: @session = session
38: @log = @session.registry.log_for( "sftp.session" )
39:
40: @session.registry.namespace_define :sftp do |ns|
41: ns.require "net/sftp/protocol/services", "Net::SFTP::Protocol"
42: ns.require "net/sftp/operations/services", "Net::SFTP::Operations"
43:
44: # register a reference to myself for other services to be able to
45: # access me.
46: ns.session( :pipeline => [] ) { self }
47:
48: @driver = ns.protocol.driver
49: @driver.on_open do |d|
50: d.on_attrs( &method( :do_attrs ))
51: d.on_data( &method( :do_data ))
52: d.on_handle(&method( :do_handle ))
53: d.on_name( &method( :do_name ))
54: d.on_status(&method( :do_status ))
55:
56: if block_given?
57: begin
58: yield self
59: ensure
60: d.close
61: end
62: end
63: end
64:
65: @operations = ns.operations
66: end
67:
68: @requests = Hash.new
69:
70: @session.loop if block_given?
71: end
Return the underlying SSH channel that supports this SFTP connection. Useful for adding custom callbacks for some events, or for accessing the underlying connection beneath the channel.
[ show source ]
# File lib/net/sftp/session.rb, line 88
88: def channel
89: @driver.channel
90: end
Closes the underlying SSH connection.
[ show source ]
# File lib/net/sftp/session.rb, line 98
98: def close
99: @session.close
100: end
Closes the SFTP connection, but leaves the SSH connection open.
[ show source ]
# File lib/net/sftp/session.rb, line 93
93: def close_channel
94: @driver.close
95: end
Waits for the underlying driver to reach a state of :open (or :closed). This makes it easier to use the SFTP routines synchronously without using the block form:
sftp = Net::SFTP::Session.new( ssh_session ) sftp.connect puts sftp.realpath( "." )
Without the call to connect, the call to realpath would fail because the SFTP protocol has not yet been negotiated and no underlying driver has been selected.
If no block is given, it returns self, so it can be chained easily to other method calls. If a block is given, the session is yielded to the block as soon as the driver successfully reports it‘s state as open, with the session‘s channel being closed automatically when the block finishes.
require 'net/ssh'
require 'net/sftp'
Net::SSH.start( 'localhost' ) do |session|
session.sftp.connect do |sftp|
puts sftp.realpath( "." )
end
end
[ show source ]
# File lib/net/sftp/session.rb, line 142
142: def connect
143: @session.loop do
144: @driver.state != :open &&
145: @driver.state != :closed
146: end
147: if @driver.state == :open && block_given?
148: begin
149: yield self
150: ensure
151: close_channel
152: end
153: else
154: self
155: end
156: end
[ show source ]
# File lib/net/sftp/session.rb, line 238
238: def do_attrs( driver, id, attributes )
239: @requests.delete( id ).do_attrs( attributes )
240: end
[ show source ]
# File lib/net/sftp/session.rb, line 214
214: def do_data( driver, id, data )
215: @requests.delete( id ).do_data( data )
216: end
[ show source ]
# File lib/net/sftp/session.rb, line 226
226: def do_handle( driver, id, handle )
227: @requests.delete( id ).do_handle( handle )
228: end
[ show source ]
# File lib/net/sftp/session.rb, line 232
232: def do_name( driver, id, items )
233: @requests.delete( id ).do_name( items )
234: end
[ show source ]
# File lib/net/sftp/session.rb, line 220
220: def do_status( driver, id, code, message, language )
221: @requests.delete( id ).do_status( code, message, language )
222: end
Retrieves the given remote file to the given local path. This will overwrite any file at the local path name. The remote file must exist.
[ show source ]
# File lib/net/sftp/session.rb, line 192
192: def get_file( remote_path, local_path )
193: open_handle( remote_path ) do |handle|
194: contents = read( handle )
195: File.open( local_path, "wb" ) { |f| f.write contents }
196: end
197: end
Delegates to Net::SSH::Session#loop. Causes the underlying SSH connection to process events as long as the given block returns true, or (if no block is given) until there are no more open channels.
[ show source ]
# File lib/net/sftp/session.rb, line 112
112: def loop( &block )
113: @session.loop( &block )
114: end
Delegates the message to the operation that has been registered with the given name. If no such operation exists, control is passed to the superclass’ implementation of method_missing.
[ show source ]
# File lib/net/sftp/session.rb, line 251
251: def method_missing( sym, *args, &block )
252: if @operations.has_key?( sym )
253: connect
254: @operations[ sym ].execute( *args, &block )
255: else
256: super
257: end
258: end
Opens the given remote file and returns a handle to it, which may be used with other operations (read, write, etc.). If a block is given, the handle will be yielded to it and closed when the block finishes, otherwise the handle will be returned. If the flags parameter is a numeric value, it must be a combination of IO constants, otherwise, it should be a string such as given to File.open.
[ show source ]
# File lib/net/sftp/session.rb, line 164
164: def open_handle( path, flags=IO::RDONLY, mode=0660 )
165: if String === flags
166: flags = case flags
167: when "r" then IO::RDONLY
168: when "r+" then IO:RDWR
169: when "w" then IO::WRONLY | IO::CREAT | IO::TRUNC
170: when "w+" then IO::RDWR | IO::CREAT | IO::TRUNC
171: when "a" then IO::APPEND | IO::CREAT
172: when "a+" then IO::APPEND | IO::CREAT
173: else IO::RDONLY
174: end
175: end
176:
177: handle = self.open( path, flags, mode )
178: if block_given?
179: begin
180: yield handle
181: ensure
182: close_handle( handle )
183: end
184: else
185: return handle
186: end
187: end
This stores the given local file at the given remote path. This will overwrite any file at the remote path name. The local file must exist.
[ show source ]
# File lib/net/sftp/session.rb, line 201
201: def put_file( local_path, remote_path )
202: contents = File.open( local_path, "rb" ) { |f| f.read }
203: open_handle( remote_path, "w" ) { |handle| write( handle, contents ) }
204: end
Registers the given handler with the given request id. This is used internally by the operations, so that the session knows who to delegate a response to that has been received from the server.
[ show source ]
# File lib/net/sftp/session.rb, line 105
105: def register( id, handler )
106: @requests[ id ] = handler
107: end
Returns true if the object responds to the given symbol, or if there is an operation registered under the given symbol.
[ show source ]
# File lib/net/sftp/session.rb, line 262
262: def respond_to?( sym )
263: super || @operations.has_key?( sym )
264: end
[ show source ]
# File lib/net/sftp/session.rb, line 81
81: def state
82: @driver.state
83: end
Returns true if the underlying driver responds to the given symbol. This can be used by clients to determine whether the SFTP protocol version in use supports a particular operation.
[ show source ]
# File lib/net/sftp/session.rb, line 269
269: def support?( sym )
270: @driver.respond_to?( sym )
271: end