diff options
author | Jamis Buck <jamis@37signals.com> | 2009-01-31 22:08:47 -0700 |
---|---|---|
committer | Jamis Buck <jamis@37signals.com> | 2009-01-31 22:08:47 -0700 |
commit | f09d124a2b4cbf6e03549f1bb32cace57601738c (patch) | |
tree | c427edfcc97c3f37df100a0019a75a169b83c52a | |
parent | 07ba76a53e659414d9b9dae17bce8e16d394f333 (diff) | |
download | net-ssh-f09d124a2b4cbf6e03549f1bb32cace57601738c.tar.gz |
Ignore requests for non-existent channels
This works around a bug in some ssh servers, where channel requests
are sent to channels after the channels have been closed.
-rw-r--r-- | CHANGELOG.rdoc | 2 | ||||
-rw-r--r-- | lib/net/ssh/connection/session.rb | 12 | ||||
-rw-r--r-- | test/connection/test_session.rb | 7 |
3 files changed, 19 insertions, 2 deletions
diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index a78ad4b..9f208dd 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,5 +1,7 @@ === unreleased +* Ignore requests for non-existent channels (workaround ssh server bug) [Jamis Buck] + * Add terminate! method for hard shutdown scenarios [Jamis Buck] * Revert to pre-2.0.7 key-loading behavior by default, but load private-key if public-key doesn't exist [Jamis Buck] diff --git a/lib/net/ssh/connection/session.rb b/lib/net/ssh/connection/session.rb index eb9b259..4dd32f7 100644 --- a/lib/net/ssh/connection/session.rb +++ b/lib/net/ssh/connection/session.rb @@ -46,6 +46,16 @@ module Net; module SSH; module Connection # The list of callbacks for pending requests. See #send_global_request. attr_reader :pending_requests #:nodoc: + class NilChannel + def initialize(session) + @session = session + end + + def method_missing(sym, *args) + @session.lwarn { "ignoring request #{sym.inspect} for non-existent (closed?) channel; probably ssh server bug" } + end + end + # Create a new connection service instance atop the given transport # layer. Initializes the listeners to be only the underlying socket object. def initialize(transport, options={}) @@ -55,7 +65,7 @@ module Net; module SSH; module Connection @options = options @channel_id_counter = -1 - @channels = {} + @channels = Hash.new(NilChannel.new(self)) @listeners = { transport.socket => nil } @pending_requests = [] @channel_open_handlers = {} diff --git a/test/connection/test_session.rb b/test/connection/test_session.rb index ba9c34f..05c3ad8 100644 --- a/test/connection/test_session.rb +++ b/test/connection/test_session.rb @@ -257,6 +257,11 @@ module Connection process_times(2) end + def test_channel_request_for_nonexistant_channel_should_be_ignored + transport.return(CHANNEL_REQUEST, :long, 14, :string, "testing", :bool, false) + assert_nothing_raised { process_times(2) } + end + def test_channel_request_packet_should_be_routed_to_corresponding_channel channel_at(14).expects(:do_request).with("testing", false, Net::SSH::Buffer.new) transport.return(CHANNEL_REQUEST, :long, 14, :string, "testing", :bool, false) @@ -480,4 +485,4 @@ module Connection end end -end
\ No newline at end of file +end |