net-sftp-backports 4.0.0.backports

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,91 @@
1
+ require 'net/sftp/constants'
2
+ require 'net/sftp/response'
3
+
4
+ module Net; module SFTP
5
+
6
+ # Encapsulates a single active SFTP request. This is instantiated
7
+ # automatically by the Net::SFTP::Session class when an operation is
8
+ # executed.
9
+ #
10
+ # request = sftp.open("/path/to/file")
11
+ # puts request.pending? #-> true
12
+ # request.wait
13
+ # puts request.pending? #-> false
14
+ # result = request.response
15
+ class Request
16
+ include Constants::PacketTypes
17
+
18
+ # The Net::SFTP session object that is servicing this request
19
+ attr_reader :session
20
+
21
+ # The SFTP packet identifier for this request
22
+ attr_reader :id
23
+
24
+ # The type of this request (e.g., :open, :symlink, etc.)
25
+ attr_reader :type
26
+
27
+ # The callback (if any) associated with this request. When the response
28
+ # is recieved for this request, the callback will be invoked.
29
+ attr_reader :callback
30
+
31
+ # The hash of properties associated with this request. Properties allow
32
+ # programmers to associate arbitrary data with a request, making state
33
+ # machines richer.
34
+ attr_reader :properties
35
+
36
+ # The response that was received for this request (see Net::SFTP::Response)
37
+ attr_reader :response
38
+
39
+ # Instantiate a new Request object, serviced by the given +session+, and
40
+ # being of the given +type+. The +id+ is the packet identifier for this
41
+ # request.
42
+ def initialize(session, type, id, &callback) #:nodoc:
43
+ @session, @id, @type, @callback = session, id, type, callback
44
+ @response = nil
45
+ @properties = {}
46
+ end
47
+
48
+ # Returns the value of property with the given +key+. If +key+ is not a
49
+ # symbol, it will be converted to a symbol before lookup.
50
+ def [](key)
51
+ properties[key.to_sym]
52
+ end
53
+
54
+ # Sets the value of the property with name +key+ to +value+. If +key+ is
55
+ # not a symbol, it will be converted to a symbol before lookup.
56
+ def []=(key, value)
57
+ properties[key.to_sym] = value
58
+ end
59
+
60
+ # Returns +true+ if the request is still waiting for a response from the
61
+ # server, and +false+ otherwise. The SSH event loop must be run in order
62
+ # for a request to be processed; see #wait.
63
+ def pending?
64
+ session.pending_requests.key?(id)
65
+ end
66
+
67
+ # Waits (blocks) until the server responds to this packet. If prior
68
+ # SFTP packets were also pending, they will be processed as well (since
69
+ # SFTP packets are processed in the order in which they are received by
70
+ # the server). Returns the request object itself.
71
+ def wait
72
+ session.loop { pending? }
73
+ self
74
+ end
75
+
76
+ public # but not "published". Internal use only
77
+
78
+ # When the server responds to this request, the packet is passed to
79
+ # this method, which parses the packet and builds a Net::SFTP::Response
80
+ # object to encapsulate it. If a #callback has been provided for this
81
+ # request, the callback is invoked with the new response object.
82
+ def respond_to(packet) #:nodoc:
83
+ data = session.protocol.parse(packet)
84
+ data[:type] = packet.type
85
+ @response = Response.new(self, data)
86
+
87
+ callback.call(@response) if callback
88
+ end
89
+ end
90
+
91
+ end; end
@@ -0,0 +1,76 @@
1
+ require 'net/sftp/constants'
2
+
3
+ module Net; module SFTP
4
+
5
+ # Encapsulates a response from the remote server, to a specific client
6
+ # request. Response objects are passed as parameters to callbacks when you
7
+ # are performing asynchronous operations; when you call Net::SFTP::Request#wait,
8
+ # you can get the corresponding response object via Net::SFTP::Request#response.
9
+ #
10
+ # sftp.open("/path/to/file") do |response|
11
+ # p response.ok?
12
+ # p response[:handle]
13
+ # end
14
+ #
15
+ # sftp.loop
16
+ class Response
17
+ include Net::SFTP::Constants::StatusCodes
18
+
19
+ # The request object that this object is in response to
20
+ attr_reader :request
21
+
22
+ # A hash of request-specific data, such as a file handle or attribute information
23
+ attr_reader :data
24
+
25
+ # The numeric code, one of the FX_* constants
26
+ attr_reader :code
27
+
28
+ # The textual message for this response (possibly blank)
29
+ attr_reader :message
30
+
31
+ # Create a new Response object for the given Net::SFTP::Request instance,
32
+ # and with the given data. If there is no :code key in the data, the
33
+ # code is assumed to be FX_OK.
34
+ def initialize(request, data={}) #:nodoc:
35
+ @request, @data = request, data
36
+ @code, @message = data[:code] || FX_OK, data[:message]
37
+ end
38
+
39
+ # Retrieve the data item with the given +key+. The key is converted to a
40
+ # symbol before being used to lookup the value.
41
+ def [](key)
42
+ data[key.to_sym]
43
+ end
44
+
45
+ # Returns a textual description of this response, including the status
46
+ # code and name.
47
+ def to_s
48
+ if message && !message.empty? && message.downcase != MAP[code]
49
+ "#{message} (#{MAP[code]}, #{code})"
50
+ else
51
+ "#{MAP[code]} (#{code})"
52
+ end
53
+ end
54
+
55
+ alias :to_str :to_s
56
+
57
+ # Returns +true+ if the status code is FX_OK; +false+ otherwise.
58
+ def ok?
59
+ code == FX_OK
60
+ end
61
+
62
+ # Returns +true+ if the status code is FX_EOF; +false+ otherwise.
63
+ def eof?
64
+ code == FX_EOF
65
+ end
66
+
67
+ #--
68
+ MAP = constants.inject({}) do |memo, name|
69
+ next memo unless name =~ /^FX_(.*)/
70
+ memo[const_get(name)] = $1.downcase.tr("_", " ")
71
+ memo
72
+ end
73
+ #++
74
+ end
75
+
76
+ end; end