net-sftp 2.1.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ci.yml +35 -0
  4. data/.gitignore +6 -0
  5. data/CHANGES.txt +4 -0
  6. data/Gemfile +15 -0
  7. data/README.rdoc +7 -4
  8. data/Rakefile +24 -30
  9. data/lib/net/sftp/operations/dir.rb +3 -3
  10. data/lib/net/sftp/operations/download.rb +8 -7
  11. data/lib/net/sftp/operations/file.rb +32 -9
  12. data/lib/net/sftp/operations/upload.rb +3 -3
  13. data/lib/net/sftp/session.rb +7 -5
  14. data/lib/net/sftp/version.rb +63 -13
  15. data/lib/net/sftp.rb +12 -4
  16. data/net-sftp-public_cert.pem +20 -0
  17. data/net-sftp.gemspec +35 -93
  18. data.tar.gz.sig +0 -0
  19. metadata +53 -82
  20. metadata.gz.sig +0 -0
  21. data/gem-public_cert.pem +0 -20
  22. data/test/common.rb +0 -184
  23. data/test/protocol/01/test_attributes.rb +0 -97
  24. data/test/protocol/01/test_base.rb +0 -210
  25. data/test/protocol/01/test_name.rb +0 -27
  26. data/test/protocol/02/test_base.rb +0 -26
  27. data/test/protocol/03/test_base.rb +0 -27
  28. data/test/protocol/04/test_attributes.rb +0 -148
  29. data/test/protocol/04/test_base.rb +0 -74
  30. data/test/protocol/04/test_name.rb +0 -53
  31. data/test/protocol/05/test_base.rb +0 -62
  32. data/test/protocol/06/test_attributes.rb +0 -124
  33. data/test/protocol/06/test_base.rb +0 -51
  34. data/test/protocol/test_base.rb +0 -42
  35. data/test/test_all.rb +0 -7
  36. data/test/test_dir.rb +0 -47
  37. data/test/test_download.rb +0 -287
  38. data/test/test_file.rb +0 -159
  39. data/test/test_file_factory.rb +0 -48
  40. data/test/test_packet.rb +0 -9
  41. data/test/test_protocol.rb +0 -17
  42. data/test/test_request.rb +0 -71
  43. data/test/test_response.rb +0 -53
  44. data/test/test_session.rb +0 -741
  45. data/test/test_upload.rb +0 -233
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4319de630f665ee342eb3c367bf1fbe1e71a057206379c5251ab2c3b073d0cb7
4
+ data.tar.gz: a35ca9f05cf5bd73f2e9b5ede7ed9f473d0025c7da530707a6470e0bdbcc1adb
5
+ SHA512:
6
+ metadata.gz: 37774670d3e3a6627f1070e5043316ccc590fd0c5049971ff36a5f83391b266a129b3f660f1b75a1d71819baef95c104f3c22bb21a1c90cdab05ff4c96ddd7a9
7
+ data.tar.gz: 0fd554d08be7d9151484f8fe8a5bb17a4f095918457a33ffc6dbebd06a7fbffc3fcbf6d79d159339e4f20c3bada94d1b3c9980936808012287b717296c4facf0
checksums.yaml.gz.sig ADDED
Binary file
@@ -0,0 +1,35 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-18.04
6
+ continue-on-error: ${{ matrix.flaky }}
7
+ strategy:
8
+ matrix:
9
+ ruby-version: ["2.5", "2.6", "2.7", "3.0", "3.1", "truffleruby-22", "truffleruby-21"]
10
+ flaky: [false]
11
+ include:
12
+ - ruby-version: "ruby-head"
13
+ flaky: true
14
+ - ruby-version: "jruby-9.2"
15
+ flaky: true
16
+ - ruby-version: "jruby-9.3"
17
+ flaky: true
18
+ - ruby-version: "jruby-head"
19
+ flaky: true
20
+ - ruby-version: "truffleruby-head"
21
+ flaky: true
22
+ steps:
23
+ - uses: actions/checkout@v1
24
+
25
+ - name: Set up Ruby ${{ matrix.ruby-version }}
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby-version }}
29
+
30
+ - name: Bundle install
31
+ run: |
32
+ gem install bundler
33
+ bundle install
34
+ - name: Run Tests
35
+ run: bundle exec rake test
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ pkg
2
+ doc
3
+ coverage
4
+ ri
5
+ *.swp
6
+ Gemfile.lock
data/CHANGES.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 3.0.0
2
+
3
+ * Pass protocol version via Net::SFTP.start [#107]
4
+ * Net-ssh 6.0 support [#106]
1
5
 
2
6
  === 2.1.2 / 07 May 2013
3
7
 
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mygem.gemspec
4
+ gemspec
5
+
6
+ # TODO: add to gemspec
7
+ gem "bundler", "~> 2.1"
8
+ gem "rake", "~> 12.0"
9
+
10
+ gem 'byebug', group: %i[development test] if !Gem.win_platform? && RUBY_ENGINE == "ruby"
11
+
12
+ if ENV["CI"]
13
+ gem 'codecov', require: false, group: :test
14
+ gem 'simplecov', require: false, group: :test
15
+ end
data/README.rdoc CHANGED
@@ -1,6 +1,9 @@
1
1
  = Net::SFTP
2
2
 
3
- * Docs: http://net-ssh.github.com/net-sftp
3
+ <em><b>Please note: this project is in maintenance mode. It is not under active development but pull requests are very much welcome. Just be sure to include tests! -- delano</b></em>
4
+
5
+
6
+ * Docs: http://net-ssh.github.io/net-sftp
4
7
  * Issues: https://github.com/net-ssh/net-sftp/issues
5
8
  * Codes: https://github.com/net-ssh/net-sftp
6
9
  * Email: net-ssh@solutious.com
@@ -69,12 +72,12 @@ If you wish to run the tests, you'll need:
69
72
 
70
73
  * gem install net-sftp (might need sudo privileges)
71
74
 
72
- However, in order to be sure the code you're installing hasn't been tampered with, it's recommended that you verify the signiture[http://docs.rubygems.org/read/chapter/21]. To do this, you need to add my public key as a trusted certificate (you only need to do this once):
75
+ However, in order to be sure the code you're installing hasn't been tampered with, it's recommended that you verify the signature[http://docs.rubygems.org/read/chapter/21]. To do this, you need to add my public key as a trusted certificate (you only need to do this once):
73
76
 
74
77
  # Add the public key as a trusted certificate
75
78
  # (You only need to do this once)
76
- $ curl -O https://raw.github.com/net-ssh/net-ssh/master/gem-public_cert.pem
77
- $ gem cert --add gem-public_cert.pem
79
+ $ curl -O https://raw.githubusercontent.com/net-ssh/net-sftp/master/net-sftp-public_cert.pem
80
+ $ gem cert --add net-sftp-public_cert.pem
78
81
 
79
82
  Then, when install the gem, do so with high security:
80
83
 
data/Rakefile CHANGED
@@ -2,40 +2,35 @@ require "rubygems"
2
2
  require "rake"
3
3
  require "rake/clean"
4
4
  require "rdoc/task"
5
+ require "bundler/gem_tasks"
6
+
7
+ desc "When releasing make sure NET_SSH_BUILDGEM_SIGNED is set"
8
+ task :check_NET_SSH_BUILDGEM_SIGNED do
9
+ raise "NET_SSH_BUILDGEM_SIGNED should be set to release" unless ENV['NET_SSH_BUILDGEM_SIGNED']
10
+ end
11
+
12
+ Rake::Task[:release].enhance [:check_NET_SSH_BUILDGEM_SIGNED]
13
+ Rake::Task[:release].prerequisites.unshift(:check_NET_SSH_BUILDGEM_SIGNED)
5
14
 
6
15
  task :default => ["build"]
7
16
  CLEAN.include [ 'pkg', 'rdoc' ]
8
17
  name = "net-sftp"
9
18
 
10
- $:.unshift File.join(File.dirname(__FILE__), 'lib')
11
- require "net/sftp/version"
12
- version = Net::SFTP::Version::STRING.dup
13
-
14
- begin
15
- require "jeweler"
16
- Jeweler::Tasks.new do |s|
17
- s.version = version
18
- s.name = name
19
- s.rubyforge_project = s.name
20
- s.summary = "A pure Ruby implementation of the SFTP client protocol"
21
- s.description = s.summary
22
- s.email = "net-ssh@solutious.com"
23
- s.homepage = "https://github.com/net-ssh/net-sftp"
24
- s.authors = ["Jamis Buck", "Delano Mandelbaum"]
25
-
26
- s.add_dependency 'net-ssh', ">=2.6.5"
27
-
28
- s.add_development_dependency 'test-unit'
29
- s.add_development_dependency 'mocha'
30
-
31
- s.license = "MIT"
32
-
33
- s.signing_key = File.join('/mnt/gem/', 'gem-private_key.pem')
34
- s.cert_chain = ['gem-public_cert.pem']
19
+ require_relative "lib/net/sftp/version"
20
+ version = Net::SFTP::Version::CURRENT
21
+
22
+ namespace :cert do
23
+ desc "Update public cert from private - only run if public is expired"
24
+ task :update_public_when_expired do
25
+ require 'openssl'
26
+ require 'time'
27
+ raw = File.read "net-sftp-public_cert.pem"
28
+ certificate = OpenSSL::X509::Certificate.new raw
29
+ raise Exception, "Not yet expired: #{certificate.not_after}" unless certificate.not_after < Time.now
30
+ sh "gem cert --build netssh@solutious.com --days 365*5 --private-key /mnt/gem/net-ssh-private_key.pem"
31
+ sh "mv gem-public_cert.pem net-sftp-public_cert.pem"
32
+ sh "gem cert --add net-sftp-public_cert.pem"
35
33
  end
36
- Jeweler::GemcutterTasks.new
37
- rescue LoadError
38
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
39
34
  end
40
35
 
41
36
  require 'rake/testtask'
@@ -53,7 +48,6 @@ RDoc::Task.new do |rdoc|
53
48
  rdoc.rdoc_files.include("bin/*.rb")
54
49
  rdoc.rdoc_files.include("lib/**/*.rb")
55
50
  extra_files.each { |file|
56
- rdoc.rdoc_files.include(file) if File.exists?(file)
51
+ rdoc.rdoc_files.include(file) if File.exist?(file)
57
52
  }
58
53
  end
59
-
@@ -57,10 +57,10 @@ module Net; module SFTP; module Operations
57
57
  # it should be able to handle modest numbers of files in each directory.
58
58
  def glob(path, pattern, flags=0)
59
59
  flags |= ::File::FNM_PATHNAME
60
- path = path.chop if path[-1,1] == "/"
60
+ path = path.chop if path.end_with?('/') && path != '/'
61
61
 
62
62
  results = [] unless block_given?
63
- queue = entries(path).reject { |e| e.name == "." || e.name == ".." }
63
+ queue = entries(path).reject { |e| %w(. ..).include?(e.name) }
64
64
  while queue.any?
65
65
  entry = queue.shift
66
66
 
@@ -90,4 +90,4 @@ module Net; module SFTP; module Operations
90
90
  end
91
91
  end
92
92
 
93
- end; end; end
93
+ end; end; end
@@ -27,7 +27,7 @@ module Net; module SFTP; module Operations
27
27
  #
28
28
  # sftp.download!("/path/to/remotedir", "/path/to/local", :recursive => true)
29
29
  #
30
- # This will download "/path/to/remotedir", it's contents, it's subdirectories,
30
+ # This will download "/path/to/remotedir", its contents, its subdirectories,
31
31
  # and their contents, recursively, to "/path/to/local" on the local host.
32
32
  # (If you specify :recursive => true and the source is not a directory,
33
33
  # you'll get an error!)
@@ -81,6 +81,7 @@ module Net; module SFTP; module Operations
81
81
  # puts "creating directory #{args[0]}"
82
82
  # when :finish then
83
83
  # puts "all done!"
84
+ # end
84
85
  # end
85
86
  #
86
87
  # However, for more complex implementations (e.g., GUI interfaces and such)
@@ -255,7 +256,7 @@ module Net; module SFTP; module Operations
255
256
  # operation was successful.
256
257
  def on_opendir(response)
257
258
  entry = response.request[:entry]
258
- raise "opendir #{entry.remote}: #{response}" unless response.ok?
259
+ raise StatusException.new(response, "opendir #{entry.remote}") unless response.ok?
259
260
  entry.handle = response[:handle]
260
261
  request = sftp.readdir(response[:handle], &method(:on_readdir))
261
262
  request[:parent] = entry
@@ -270,7 +271,7 @@ module Net; module SFTP; module Operations
270
271
  request = sftp.close(entry.handle, &method(:on_closedir))
271
272
  request[:parent] = entry
272
273
  elsif !response.ok?
273
- raise "readdir #{entry.remote}: #{response}"
274
+ raise StatusException.new(response, "readdir #{entry.remote}")
274
275
  else
275
276
  response[:names].each do |item|
276
277
  next if item.name == "." || item.name == ".."
@@ -296,7 +297,7 @@ module Net; module SFTP; module Operations
296
297
  def on_closedir(response)
297
298
  @active -= 1
298
299
  entry = response.request[:parent]
299
- raise "close #{entry.remote}: #{response}" unless response.ok?
300
+ raise StatusException.new(response, "close #{entry.remote}") unless response.ok?
300
301
  process_next_entry
301
302
  end
302
303
 
@@ -304,7 +305,7 @@ module Net; module SFTP; module Operations
304
305
  # to initiate the data transfer.
305
306
  def on_open(response)
306
307
  entry = response.request[:entry]
307
- raise "open #{entry.remote}: #{response}" unless response.ok?
308
+ raise StatusException.new(response, "open #{entry.remote}") unless response.ok?
308
309
 
309
310
  entry.handle = response[:handle]
310
311
  entry.sink = entry.local.respond_to?(:write) ? entry.local : ::File.open(entry.local, "wb")
@@ -332,7 +333,7 @@ module Net; module SFTP; module Operations
332
333
  request = sftp.close(entry.handle, &method(:on_close))
333
334
  request[:entry] = entry
334
335
  elsif !response.ok?
335
- raise "read #{entry.remote}: #{response}"
336
+ raise StatusException.new(response, "read #{entry.remote}")
336
337
  else
337
338
  entry.offset += response[:data].bytesize
338
339
  update_progress(:get, entry, response.request[:offset], response[:data])
@@ -345,7 +346,7 @@ module Net; module SFTP; module Operations
345
346
  def on_close(response)
346
347
  @active -= 1
347
348
  entry = response.request[:entry]
348
- raise "close #{entry.remote}: #{response}" unless response.ok?
349
+ raise StatusException.new(response, "close #{entry.remote}") unless response.ok?
349
350
  process_next_entry
350
351
  end
351
352
 
@@ -81,21 +81,35 @@ module Net; module SFTP; module Operations
81
81
  # Reads up to the next instance of +sep_string+ in the stream, and
82
82
  # returns the bytes read (including +sep_string+). If +sep_string+ is
83
83
  # omitted, it defaults to +$/+. If EOF is encountered before any data
84
- # could be read, #gets will return +nil+.
85
- def gets(sep_string=$/)
86
- delim = if sep_string.length == 0
84
+ # could be read, #gets will return +nil+. If the first argument is an
85
+ # integer, or optional second argument is given, the returning string
86
+ # would not be longer than the given value in bytes.
87
+ def gets(sep_or_limit=$/, limit=Float::INFINITY)
88
+ if sep_or_limit.is_a? Integer
89
+ sep_string = $/
90
+ lim = sep_or_limit
91
+ else
92
+ sep_string = sep_or_limit
93
+ lim = limit
94
+ end
95
+
96
+ delim = if sep_string && sep_string.length == 0
87
97
  "#{$/}#{$/}"
88
98
  else
89
99
  sep_string
90
100
  end
91
101
 
92
102
  loop do
93
- at = @buffer.index(delim)
103
+ at = @buffer.index(delim) if delim
94
104
  if at
95
- offset = at + delim.length
105
+ offset = [at + delim.length, lim].min
96
106
  @pos += offset
97
107
  line, @buffer = @buffer[0,offset], @buffer[offset..-1]
98
108
  return line
109
+ elsif lim < @buffer.length
110
+ @pos += lim
111
+ line, @buffer = @buffer[0,lim], @buffer[lim..-1]
112
+ return line
99
113
  elsif !fill
100
114
  return nil if @buffer.empty?
101
115
  @pos += @buffer.length
@@ -107,8 +121,8 @@ module Net; module SFTP; module Operations
107
121
 
108
122
  # Same as #gets, but raises EOFError if EOF is encountered before any
109
123
  # data could be read.
110
- def readline(sep_string=$/)
111
- line = gets(sep_string)
124
+ def readline(sep_or_limit=$/, limit=Float::INFINITY)
125
+ line = gets(sep_or_limit, limit)
112
126
  raise EOFError if line.nil?
113
127
  return line
114
128
  end
@@ -118,9 +132,9 @@ module Net; module SFTP; module Operations
118
132
  def write(data)
119
133
  data = data.to_s
120
134
  sftp.write!(handle, @real_pos, data)
121
- @real_pos += data.length
135
+ @real_pos += data.bytes.length
122
136
  @pos = @real_pos
123
- data.length
137
+ data.bytes.length
124
138
  end
125
139
 
126
140
  # Writes each argument to the stream. If +$\+ is set, it will be written
@@ -131,6 +145,15 @@ module Net; module SFTP; module Operations
131
145
  nil
132
146
  end
133
147
 
148
+ def size
149
+ stat.size
150
+ end
151
+
152
+ # Resets position to beginning of file
153
+ def rewind
154
+ self.pos = 0
155
+ end
156
+
134
157
  # Writes each argument to the stream, appending a newline to any item
135
158
  # that does not already end in a newline. Array arguments are flattened.
136
159
  def puts(*items)
@@ -27,14 +27,14 @@ module Net; module SFTP; module Operations
27
27
  #
28
28
  # sftp.upload!("/path/to/directory", "/path/to/remote")
29
29
  #
30
- # This will upload "/path/to/directory", it's contents, it's subdirectories,
30
+ # This will upload "/path/to/directory", its contents, its subdirectories,
31
31
  # and their contents, recursively, to "/path/to/remote" on the remote server.
32
32
  #
33
33
  # For uploading a directory without creating it, do
34
34
  # sftp.upload!("/path/to/directory", "/path/to/remote", :mkdir => false)
35
35
  #
36
36
  # If you want to send data to a file on the remote server, but the data is
37
- # in memory, you can pass an IO object and upload it's contents:
37
+ # in memory, you can pass an IO object and upload its contents:
38
38
  #
39
39
  # require 'stringio'
40
40
  # io = StringIO.new(data)
@@ -173,7 +173,7 @@ module Net; module SFTP; module Operations
173
173
  process_next_entry
174
174
  end
175
175
  else
176
- raise ArgumentError, "expected a file to upload" unless local.respond_to?(:read) || ::File.exists?(local)
176
+ raise ArgumentError, "expected a file to upload" unless local.respond_to?(:read) || ::File.exist?(local)
177
177
  @stack = [[local]]
178
178
  process_next_entry
179
179
  end
@@ -75,11 +75,13 @@ module Net; module SFTP
75
75
  #
76
76
  # sftp = Net::SFTP::Session.new(ssh)
77
77
  # sftp.loop { sftp.opening? }
78
- def initialize(session, &block)
78
+ def initialize(session, version = nil, &block)
79
79
  @session = session
80
+ @version = version
80
81
  @input = Net::SSH::Buffer.new
81
82
  self.logger = session.logger
82
83
  @state = :closed
84
+ @pending_requests = {}
83
85
 
84
86
  connect(&block)
85
87
  end
@@ -106,7 +108,7 @@ module Net; module SFTP
106
108
  # Initiates a download from +remote+ to +local+, asynchronously. This
107
109
  # method will return a new Net::SFTP::Operations::Download instance, and requires
108
110
  # that the event loop be run in order for the download to progress. See
109
- # Net::SFTP::Operations::Download for a full discussion of hos this method can be
111
+ # Net::SFTP::Operations::Download for a full discussion of how this method can be
110
112
  # used.
111
113
  #
112
114
  # download = sftp.download("/remote/path", "/local/path")
@@ -417,7 +419,7 @@ module Net; module SFTP
417
419
 
418
420
  # :call-seq:
419
421
  # readdir(handle) -> request
420
- # raeddir(handle) { |response| ... } -> request
422
+ # readdir(handle) { |response| ... } -> request
421
423
  #
422
424
  # Reads a set of entries from the given directory handle (which must
423
425
  # have been obtained via #opendir). If the response is EOF, then there
@@ -876,7 +878,7 @@ module Net; module SFTP
876
878
  channel.on_close(&method(:when_channel_closed))
877
879
  channel.on_process(&method(:when_channel_polled))
878
880
 
879
- send_packet(FXP_INIT, :long, HIGHEST_PROTOCOL_VERSION_SUPPORTED)
881
+ send_packet(FXP_INIT, :long, @version || HIGHEST_PROTOCOL_VERSION_SUPPORTED)
880
882
  end
881
883
 
882
884
  # Called when the SSH server closes the underlying channel.
@@ -949,4 +951,4 @@ module Net; module SFTP
949
951
  end
950
952
  end
951
953
 
952
- end; end
954
+ end; end
@@ -1,18 +1,68 @@
1
- require 'net/ssh/version'
1
+ module Net
2
+ module SFTP
3
+ # A class for describing the current version of a library. The version
4
+ # consists of three parts: the +major+ number, the +minor+ number, and the
5
+ # +tiny+ (or +patch+) number.
6
+ #
7
+ # Two Version instances may be compared, so that you can test that a version
8
+ # of a library is what you require:
9
+ #
10
+ # require 'net/sftp/version'
11
+ #
12
+ # if Net::SFTP::Version::CURRENT < Net::SFTP::Version[2,1,0]
13
+ # abort "your software is too old!"
14
+ # end
15
+ class Version
16
+ include Comparable
2
17
 
3
- module Net; module SFTP
18
+ # A convenience method for instantiating a new Version instance with the
19
+ # given +major+, +minor+, and +tiny+ components.
20
+ def self.[](major, minor, tiny, pre = nil)
21
+ new(major, minor, tiny, pre)
22
+ end
4
23
 
5
- # Describes the current version of the Net::SFTP library.
6
- class Version < Net::SSH::Version
7
- MAJOR = 2
8
- MINOR = 1
9
- TINY = 2
24
+ attr_reader :major, :minor, :tiny
10
25
 
11
- # The current version, as a Version instance
12
- CURRENT = new(MAJOR, MINOR, TINY)
26
+ # Create a new Version object with the given components.
27
+ def initialize(major, minor, tiny, pre = nil)
28
+ @major, @minor, @tiny, @pre = major, minor, tiny, pre
29
+ end
13
30
 
14
- # The current version, as a String instance
15
- STRING = CURRENT.to_s
16
- end
31
+ # Compare this version to the given +version+ object.
32
+ def <=>(version)
33
+ to_i <=> version.to_i
34
+ end
35
+
36
+ # Converts this version object to a string, where each of the three
37
+ # version components are joined by the '.' character. E.g., 2.0.0.
38
+ def to_s
39
+ @to_s ||= [@major, @minor, @tiny, @pre].compact.join(".")
40
+ end
41
+
42
+ # Converts this version to a canonical integer that may be compared
43
+ # against other version objects.
44
+ def to_i
45
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
46
+ end
47
+
48
+ # The major component of this version of the Net::SFTP library
49
+ MAJOR = 4
50
+
51
+ # The minor component of this version of the Net::SFTP library
52
+ MINOR = 0
17
53
 
18
- end; end
54
+ # The tiny component of this version of the Net::SFTP library
55
+ TINY = 0
56
+
57
+ # The prerelease component of this version of the Net::SFTP library
58
+ # nil allowed
59
+ PRE = nil
60
+
61
+ # The current version of the Net::SFTP library as a Version instance
62
+ CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
63
+
64
+ # The current version of the Net::SFTP library as a String
65
+ STRING = CURRENT.to_s
66
+ end
67
+ end
68
+ end
data/lib/net/sftp.rb CHANGED
@@ -27,9 +27,17 @@ module Net
27
27
  # Net::SFTP.start("localhost", "user") do |sftp|
28
28
  # sftp.upload! "/local/file.tgz", "/remote/file.tgz"
29
29
  # end
30
- def self.start(host, user, options={}, &block)
31
- session = Net::SSH.start(host, user, options)
32
- sftp = Net::SFTP::Session.new(session, &block).connect!
30
+ #
31
+ # Extra parameters can be passed:
32
+ # - The Net::SSH connection options (see Net::SSH for more information)
33
+ # - The Net::SFTP connection options (only :version is supported, to let you
34
+ # set the SFTP protocol version to be used)
35
+ def self.start(host, user, ssh_options={}, sftp_options={}, &block)
36
+ session = Net::SSH.start(host, user, ssh_options)
37
+ # We only use a single option here, but this leaves room for more later
38
+ # without breaking the external API.
39
+ version = sftp_options.fetch(:version, nil)
40
+ sftp = Net::SFTP::Session.new(session, version, &block).connect!
33
41
 
34
42
  if block_given?
35
43
  sftp.loop
@@ -56,7 +64,7 @@ class Net::SSH::Connection::Session
56
64
  # SSH session. Blocks until the SFTP session is fully open, and then
57
65
  # returns the SFTP session.
58
66
  #
59
- # Net::SSH.start("localhost", "user", "password") do |ssh|
67
+ # Net::SSH.start("localhost", "user", :password => "password") do |ssh|
60
68
  # ssh.sftp.upload!("/local/file.tgz", "/remote/file.tgz")
61
69
  # ssh.exec! "cd /some/path && tar xf /remote/file.tgz && rm /remote/file.tgz"
62
70
  # end
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpuZXRz
3
+ c2gvREM9c29sdXRpb3VzL0RDPWNvbTAeFw0yMjA5MjIxMTUwMDJaFw0yMzA5MjIx
4
+ MTUwMDJaMCUxIzAhBgNVBAMMGm5ldHNzaC9EQz1zb2x1dGlvdXMvREM9Y29tMIIB
5
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxieE22fR/qmdPKUHyYTyUx2g
6
+ wskLwrCkxay+Tvc97ZZUOwf85LDDDPqhQaTWLvRwnIOMgQE2nBPzwalVclK6a+pW
7
+ x/18KDeZY15vm3Qn5p42b0wi9hUxOqPm3J2hdCLCcgtENgdX21nVzejn39WVqFJO
8
+ lntgSDNW5+kCS8QaRsmIbzj17GKKkrsw39kiQw7FhWfJFeTjddzoZiWwc59KA/Bx
9
+ fBbmDnsMLAtAtauMOxORrbx3EOY7sHku/kSrMg3FXFay7jc6BkbbUij+MjJ/k82l
10
+ 4o8o0YO4BAnya90xgEmgOG0LCCxRhuXQFnMDuDjK2XnUe0h4/6NCn94C+z9GsQID
11
+ AQABo3sweTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUBfKiwO2e
12
+ M4NEiRrVG793qEPLYyMwHwYDVR0RBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20w
13
+ HwYDVR0SBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20wDQYJKoZIhvcNAQELBQAD
14
+ ggEBABI2ORK5kzUL7uOF0EHI4ECMWxQMiN+pURyGp9u7DU0H8eSdZN52jbUGHzSB
15
+ j7bB6GpqElEWjOe0IbH3vR52IVXq2bOF4P4vFchGAb4OuzJD8aJmrC/SPLHbWBuV
16
+ 2GpbRQRJyYPWN6Rt/4EHOxoFnhXOBEB6CGIy0dt7YezycVbzqtHoiI2Qf/bIFJQZ
17
+ mpJAAUBkRiWksE7zrsE5DGK8kL2GVos7f8kdM71zT8p7VBwkMdY277T29TG2xD0D
18
+ 66Oev0C3/x89NXqCHkl1JElSzEFbOoxan16z7xNEf2MKcBKGhsYfzWVNyEtJm785
19
+ g+97rn/AuO6dcxJnW2qBGYQa7pQ=
20
+ -----END CERTIFICATE-----