Represents a single SFTP session, running atop an SSH session.
- 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. |
Create a new SFTP session on top of the given SSH session.
[ show source ]
# File lib/net/sftp/session.rb, line 32 32: def initialize( session ) 33: @session = session 34: @log = @session.registry.log_for( "sftp.session" ) 35: 36: @session.registry.namespace_define :sftp do |ns| 37: ns.require "net/sftp/protocol/services", "Net::SFTP::Protocol" 38: ns.require "net/sftp/operations/services", "Net::SFTP::Operations" 39: 40: # register a reference to myself for other services to be able to 41: # access me. 42: ns.session( :pipeline => [] ) { self } 43: 44: @driver = ns.protocol.driver 45: @driver.on_open do |d| 46: d.on_attrs &method( :do_attrs ) 47: d.on_data &method( :do_data ) 48: d.on_handle &method( :do_handle ) 49: d.on_name &method( :do_name ) 50: d.on_status &method( :do_status ) 51: 52: if block_given? 53: begin 54: yield self 55: ensure 56: d.close 57: end 58: end 59: end 60: 61: @operations = ns.operations 62: end 63: 64: @requests = Hash.new 65: 66: @session.loop if block_given? 67: end
Closes the underlying SSH connection.
[ show source ]
# File lib/net/sftp/session.rb, line 87 87: def close 88: @session.close 89: end
Closes the SFTP connection, but leaves the SSH connection open.
[ show source ]
# File lib/net/sftp/session.rb, line 82 82: def close_channel 83: @driver.close 84: 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 131 131: def connect 132: @session.loop do 133: @driver.state != :open && 134: @driver.state != :closed 135: end 136: if @driver.state == :open && block_given? 137: begin 138: yield self 139: ensure 140: close_channel 141: end 142: else 143: self 144: end 145: end
[ show source ]
# File lib/net/sftp/session.rb, line 227 227: def do_attrs( driver, id, attributes ) 228: @requests.delete( id ).do_attrs( attributes ) 229: end
[ show source ]
# File lib/net/sftp/session.rb, line 203 203: def do_data( driver, id, data ) 204: @requests.delete( id ).do_data( data ) 205: end
[ show source ]
# File lib/net/sftp/session.rb, line 215 215: def do_handle( driver, id, handle ) 216: @requests.delete( id ).do_handle( handle ) 217: end
[ show source ]
# File lib/net/sftp/session.rb, line 221 221: def do_name( driver, id, items ) 222: @requests.delete( id ).do_name( items ) 223: end
[ show source ]
# File lib/net/sftp/session.rb, line 209 209: def do_status( driver, id, code, message, language ) 210: @requests.delete( id ).do_status( code, message, language ) 211: 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 181 181: def get_file( remote_path, local_path ) 182: open_handle( remote_path ) do |handle| 183: contents = read( handle ) 184: File.open( local_path, "wb" ) { |f| f.write contents } 185: end 186: 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 101 101: def loop( &block ) 102: @session.loop( &block ) 103: 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 240 240: def method_missing( sym, *args, &block ) 241: if @operations.has_key?( sym ) 242: @operations[ sym ].execute( *args, &block ) 243: else 244: super 245: end 246: 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 153 153: def open_handle( path, flags=IO::RDONLY, mode=0660 ) 154: if String === flags 155: flags = case flags 156: when "r" then IO::RDONLY 157: when "r+" then IO:RDWR 158: when "w" then IO::WRONLY | IO::CREAT | IO::TRUNC 159: when "w+" then IO::RDWR | IO::CREAT | IO::TRUNC 160: when "a" then IO::APPEND | IO::CREAT 161: when "a+" then IO::APPEND | IO::CREAT 162: else IO::RDONLY 163: end 164: end 165: 166: handle = self.open( path, flags, mode ) 167: if block_given? 168: begin 169: yield handle 170: ensure 171: close_handle( handle ) 172: end 173: else 174: return handle 175: end 176: 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 190 190: def put_file( local_path, remote_path ) 191: contents = File.open( local_path, "rb" ) { |f| f.read } 192: open_handle( remote_path, "w" ) { |handle| write( handle, contents ) } 193: 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 94 94: def register( id, handler ) 95: @requests[ id ] = handler 96: 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 250 250: def respond_to?( sym ) 251: super || @operations.has_key?( sym ) 252: end
Return the state of the SFTP connection. (See Net::SFTP::Protocol::Driver#state.)
[ show source ]
# File lib/net/sftp/session.rb, line 77 77: def state 78: @driver.state 79: 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 257 257: def support?( sym ) 258: @driver.respond_to?( sym ) 259: end