Class: Net::SSH::Proxy::Command
- Inherits:
-
Object
- Object
- Net::SSH::Proxy::Command
- Defined in:
- lib/net/ssh/proxy/command.rb
Overview
An implementation of a command proxy. To use it, instantiate it, then pass the instantiated object via the :proxy key to Net::SSH.start:
require 'net/ssh/proxy/command'
proxy = Net::SSH::Proxy::Command.new('ssh relay nc %h %p')
Net::SSH.start('host', 'user', :proxy => proxy) do |ssh|
...
end
Direct Known Subclasses
Instance Attribute Summary collapse
-
#command_line ⇒ Object
readonly
The command line for the session.
-
#command_line_template ⇒ Object
readonly
The command line template.
-
#timeout ⇒ Object
Timeout in seconds in open, defaults to 60.
Instance Method Summary collapse
- #close_on_error(io) ⇒ Object
-
#initialize(command_line_template) ⇒ Command
constructor
Create a new socket factory that tunnels via a command executed with the user’s shell, which is composed from the given command template.
-
#open(host, port, connection_options = nil) ⇒ Object
Return a new socket connected to the given host and port via the proxy that was requested when the socket factory was instantiated.
Constructor Details
#initialize(command_line_template) ⇒ Command
Create a new socket factory that tunnels via a command executed with the user’s shell, which is composed from the given command template. In the command template, ‘%h’ will be substituted by the host name to connect and ‘%p’ by the port.
32 33 34 35 36 |
# File 'lib/net/ssh/proxy/command.rb', line 32 def initialize(command_line_template) @command_line_template = command_line_template @command_line = nil @timeout = 60 end |
Instance Attribute Details
#command_line ⇒ Object (readonly)
The command line for the session
23 24 25 |
# File 'lib/net/ssh/proxy/command.rb', line 23 def command_line @command_line end |
#command_line_template ⇒ Object (readonly)
The command line template
20 21 22 |
# File 'lib/net/ssh/proxy/command.rb', line 20 def command_line_template @command_line_template end |
#timeout ⇒ Object
Timeout in seconds in open, defaults to 60
26 27 28 |
# File 'lib/net/ssh/proxy/command.rb', line 26 def timeout @timeout end |
Instance Method Details
#close_on_error(io) ⇒ Object
116 117 118 119 |
# File 'lib/net/ssh/proxy/command.rb', line 116 def close_on_error(io) Process.kill('TERM', io.pid) Thread.new { io.close } end |
#open(host, port, connection_options = nil) ⇒ Object
Return a new socket connected to the given host and port via the proxy that was requested when the socket factory was instantiated.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/net/ssh/proxy/command.rb', line 40 def open(host, port, = nil) command_line = @command_line_template.gsub(/%(.)/) { case $1 when 'h' host when 'p' port.to_s when 'r' remote_user = && [:remote_user] if remote_user remote_user else raise ArgumentError, "remote user name not available" end when '%' '%' else raise ArgumentError, "unknown key: #{$1}" end } begin io = IO.popen(command_line, "r+") begin if result = IO.select([io], nil, [io], @timeout) if result.last.any? || io.eof? raise "command failed" end else raise "command timed out" end rescue StandardError close_on_error(io) raise end rescue StandardError => e raise ConnectError, "#{e}: #{command_line}" end @command_line = command_line if Gem.win_platform? # read_nonblock and write_nonblock are not available on Windows # pipe. Use sysread and syswrite as a replacement works. def io.send(data, flag) syswrite(data) end def io.recv(size) sysread(size) end else def io.send(data, flag) begin result = write_nonblock(data) rescue IO::WaitWritable, Errno::EINTR IO.select(nil, [self]) retry end result end def io.recv(size) begin result = read_nonblock(size) rescue IO::WaitReadable, Errno::EINTR timeout_in_seconds = 20 if IO.select([self], nil, [self], timeout_in_seconds) == nil raise "Unexpected spurious read wakeup" end retry end result end end io end |