net-sftp 2.0.5 → 3.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 +2 -0
  3. data/.gitignore +5 -0
  4. data/.travis.yml +20 -0
  5. data/{CHANGELOG.rdoc → CHANGES.txt} +18 -0
  6. data/Gemfile +15 -0
  7. data/LICENSE.txt +19 -0
  8. data/README.rdoc +23 -1
  9. data/Rakefile +44 -21
  10. data/lib/net/sftp/operations/dir.rb +3 -3
  11. data/lib/net/sftp/operations/download.rb +8 -7
  12. data/lib/net/sftp/operations/file.rb +30 -8
  13. data/lib/net/sftp/operations/upload.rb +14 -6
  14. data/lib/net/sftp/session.rb +9 -7
  15. data/lib/net/sftp/version.rb +63 -13
  16. data/lib/net/sftp.rb +12 -4
  17. data/net-sftp-public_cert.pem +20 -0
  18. data/net-sftp.gemspec +38 -24
  19. data.tar.gz.sig +0 -0
  20. metadata +110 -127
  21. metadata.gz.sig +0 -0
  22. data/test/common.rb +0 -172
  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 -252
  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 -219
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 64f5637e6c346349fb65a3346258e6a87d55219d651d3b48d042dde87d502099
4
+ data.tar.gz: e84621e188f86616e5a702650c2cb96210bc08d814c0c28c3cc8960dc042a73f
5
+ SHA512:
6
+ metadata.gz: 04252f3c3448dac1a637e9623ed2a5af6dbfb482d738ae407d44006c7c8d32b82a5ef4e477bb28ab6c666cf651349cf1ee685b58304073db03a3d7317a927ee7
7
+ data.tar.gz: 0da6c4055f0f7f488e772e3c4914fcabb2ea893823a9e0ad1ff5b12e0cbe7ad6c72f494c417a70f92c7989e26bff0f486628e17ad278d42a7f716b05267be8aa
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ P6ޝ1먨���_���jEZN+�zA�q�3v��(��d�7d� t���-=PV���V�c N �M§:�*�P���t\tQ$Q�m�u}?��Ry�R�,U�̜ojz�<�^�dbs7� �be ����]���&�We[$��1E�vOF6LN��o(/�X�.�)����)���ӂf��a������l����(�\_����\)6
2
+ Y�Ws�a![��5����+��A�4}����6���*Ȣ|�shG^�
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ pkg
2
+ doc
3
+ coverage
4
+ ri
5
+ *.swp
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ sudo: false
3
+ rvm:
4
+ - 2.3.7
5
+ - 2.4.5
6
+ - 2.5.3
7
+ - 2.6.5
8
+ - 2.7.1
9
+ - ruby-head
10
+ - jruby-head
11
+ - rbx-3.107
12
+
13
+ install: gem install net-ssh test-unit mocha
14
+
15
+ script: rake test
16
+
17
+ matrix:
18
+ allow_failures:
19
+ - rvm: jruby-head
20
+ - rvm: rbx-3.107
@@ -1,3 +1,21 @@
1
+ === 3.0.0
2
+
3
+ * Pass protocol version via Net::SFTP.start [#107]
4
+ * Net-ssh 6.0 support [#106]
5
+
6
+ === 2.1.2 / 07 May 2013
7
+
8
+ * Fix fragmentation download failure [accardi]
9
+
10
+ === 2.1.0 / 06 Feb 2013
11
+
12
+ * Added public cert. All gem releases are now signed. See INSTALL in readme.
13
+ * Remove self-require, it causes a warning in Ruby 1.9.2. [jbarnette]
14
+ * Allow for upload to use the filename of the local file by default [czarneckid]
15
+ * Properly handle receiving less data than requested. [thedarkone]
16
+ * Added option to create directory on directory upload [Pablo Merino]
17
+ * Remove a warnings in tests [kachick]
18
+
1
19
 
2
20
  === 2.0.5 / 19 Aug 2010
3
21
 
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/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright © 2008 Jamis Buck
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the ‘Software’), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.rdoc CHANGED
@@ -1,6 +1,15 @@
1
1
  = Net::SFTP
2
2
 
3
- * http://net-ssh.rubyforge.org/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.com/net-sftp
7
+ * Issues: https://github.com/net-ssh/net-sftp/issues
8
+ * Codes: https://github.com/net-ssh/net-sftp
9
+ * Email: net-ssh@solutious.com
10
+
11
+ <em>As of v2.1.0, all gem releases are signed. See INSTALL.</em>
12
+
4
13
 
5
14
  == DESCRIPTION:
6
15
 
@@ -63,6 +72,19 @@ If you wish to run the tests, you'll need:
63
72
 
64
73
  * gem install net-sftp (might need sudo privileges)
65
74
 
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):
76
+
77
+ # Add the public key as a trusted certificate
78
+ # (You only need to do this once)
79
+ $ curl -O https://raw.github.com/net-ssh/net-ssh/master/gem-public_cert.pem
80
+ $ gem cert --add gem-public_cert.pem
81
+
82
+ Then, when install the gem, do so with high security:
83
+
84
+ $ gem install net-sftp -P HighSecurity
85
+
86
+ If you don't add the public key, you'll see an error like "Couldn't verify data signature". If you're still having trouble let me know and I'll give you a hand.
87
+
66
88
  Or, if you prefer to do it the hard way (sans Rubygems):
67
89
 
68
90
  * tar xzf net-ssh-*.tgz
data/Rakefile CHANGED
@@ -1,30 +1,53 @@
1
- $LOAD_PATH.unshift "../net-ssh/lib"
2
- require './lib/net/sftp/version'
1
+ require "rubygems"
2
+ require "rake"
3
+ require "rake/clean"
4
+ require "rdoc/task"
5
+ require "bundler/gem_tasks"
3
6
 
4
- begin
5
- require 'echoe'
6
- rescue LoadError
7
- abort "You'll need to have `echoe' installed to use Net::SFTP's Rakefile"
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']
8
10
  end
9
11
 
10
- version = Net::SFTP::Version::STRING.dup
11
- if ENV['SNAPSHOT'].to_i == 1
12
- version << "." << Time.now.utc.strftime("%Y%m%d%H%M%S")
13
- end
12
+ Rake::Task[:release].enhance [:check_NET_SSH_BUILDGEM_SIGNED]
13
+ Rake::Task[:release].prerequisites.unshift(:check_NET_SSH_BUILDGEM_SIGNED)
14
14
 
15
- Echoe.new('net-sftp', version) do |p|
16
- p.project = "net-ssh"
17
- p.changelog = "CHANGELOG.rdoc"
15
+ task :default => ["build"]
16
+ CLEAN.include [ 'pkg', 'rdoc' ]
17
+ name = "net-sftp"
18
18
 
19
- p.author = "Jamis Buck"
20
- p.email = "netsftp@solutious.com"
21
- p.summary = "A pure Ruby implementation of the SFTP client protocol"
22
- p.url = "http://net-ssh.rubyforge.org/sftp"
19
+ require_relative "lib/net/sftp/version"
20
+ version = Net::SFTP::Version::CURRENT
23
21
 
24
- p.dependencies = ["net-ssh >=2.0.9"]
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"
33
+ end
34
+ end
25
35
 
26
- p.need_zip = true
27
- p.include_rakefile = true
36
+ require 'rake/testtask'
37
+ Rake::TestTask.new do |t|
38
+ t.libs = ["lib", "test"]
39
+ end
28
40
 
29
- p.rdoc_pattern = /^(lib|README.rdoc|CHANGELOG.rdoc)/
41
+ extra_files = %w[LICENSE.txt THANKS.txt CHANGES.txt ]
42
+ RDoc::Task.new do |rdoc|
43
+ rdoc.rdoc_dir = "rdoc"
44
+ rdoc.title = "#{name} #{version}"
45
+ rdoc.generator = 'hanna' # gem install hanna-nouveau
46
+ rdoc.main = 'README.rdoc'
47
+ rdoc.rdoc_files.include("README*")
48
+ rdoc.rdoc_files.include("bin/*.rb")
49
+ rdoc.rdoc_files.include("lib/**/*.rb")
50
+ extra_files.each { |file|
51
+ rdoc.rdoc_files.include(file) if File.exist?(file)
52
+ }
30
53
  end
@@ -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
@@ -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")
@@ -318,7 +319,6 @@ module Net; module SFTP; module Operations
318
319
  request = sftp.read(entry.handle, entry.offset, read_size, &method(:on_read))
319
320
  request[:entry] = entry
320
321
  request[:offset] = entry.offset
321
- entry.offset += read_size
322
322
  end
323
323
 
324
324
  # Called when a read from a file finishes. If the read was successful
@@ -333,8 +333,9 @@ module Net; module SFTP; module Operations
333
333
  request = sftp.close(entry.handle, &method(:on_close))
334
334
  request[:entry] = entry
335
335
  elsif !response.ok?
336
- raise "read #{entry.remote}: #{response}"
336
+ raise StatusException.new(response, "read #{entry.remote}")
337
337
  else
338
+ entry.offset += response[:data].bytesize
338
339
  update_progress(:get, entry, response.request[:offset], response[:data])
339
340
  entry.sink.write(response[:data])
340
341
  download_next_chunk(entry)
@@ -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
 
@@ -1,5 +1,4 @@
1
1
  require 'net/ssh/loggable'
2
- require 'net/sftp/operations/file'
3
2
 
4
3
  module Net; module SFTP; module Operations
5
4
 
@@ -82,21 +81,35 @@ module Net; module SFTP; module Operations
82
81
  # Reads up to the next instance of +sep_string+ in the stream, and
83
82
  # returns the bytes read (including +sep_string+). If +sep_string+ is
84
83
  # omitted, it defaults to +$/+. If EOF is encountered before any data
85
- # could be read, #gets will return +nil+.
86
- def gets(sep_string=$/)
87
- 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
88
97
  "#{$/}#{$/}"
89
98
  else
90
99
  sep_string
91
100
  end
92
101
 
93
102
  loop do
94
- at = @buffer.index(delim)
103
+ at = @buffer.index(delim) if delim
95
104
  if at
96
- offset = at + delim.length
105
+ offset = [at + delim.length, lim].min
97
106
  @pos += offset
98
107
  line, @buffer = @buffer[0,offset], @buffer[offset..-1]
99
108
  return line
109
+ elsif lim < @buffer.length
110
+ @pos += lim
111
+ line, @buffer = @buffer[0,lim], @buffer[lim..-1]
112
+ return line
100
113
  elsif !fill
101
114
  return nil if @buffer.empty?
102
115
  @pos += @buffer.length
@@ -108,8 +121,8 @@ module Net; module SFTP; module Operations
108
121
 
109
122
  # Same as #gets, but raises EOFError if EOF is encountered before any
110
123
  # data could be read.
111
- def readline(sep_string=$/)
112
- line = gets(sep_string)
124
+ def readline(sep_or_limit=$/, limit=Float::INFINITY)
125
+ line = gets(sep_or_limit, limit)
113
126
  raise EOFError if line.nil?
114
127
  return line
115
128
  end
@@ -132,6 +145,15 @@ module Net; module SFTP; module Operations
132
145
  nil
133
146
  end
134
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
+
135
157
  # Writes each argument to the stream, appending a newline to any item
136
158
  # that does not already end in a newline. Array arguments are flattened.
137
159
  def puts(*items)
@@ -30,6 +30,9 @@ module Net; module SFTP; module Operations
30
30
  # This will upload "/path/to/directory", it's contents, it's subdirectories,
31
31
  # and their contents, recursively, to "/path/to/remote" on the remote server.
32
32
  #
33
+ # For uploading a directory without creating it, do
34
+ # sftp.upload!("/path/to/directory", "/path/to/remote", :mkdir => false)
35
+ #
33
36
  # If you want to send data to a file on the remote server, but the data is
34
37
  # in memory, you can pass an IO object and upload it's contents:
35
38
  #
@@ -157,15 +160,20 @@ module Net; module SFTP; module Operations
157
160
  @remote_cwd = remote
158
161
 
159
162
  @active += 1
160
- sftp.mkdir(remote) do |response|
161
- @active -= 1
162
- raise StatusException.new(response, "mkdir `#{remote}'") unless response.ok?
163
- (options[:requests] || RECURSIVE_READERS).to_i.times do
164
- break unless process_next_entry
163
+ if @options[:mkdir]
164
+ sftp.mkdir(remote) do |response|
165
+ @active -= 1
166
+ raise StatusException.new(response, "mkdir `#{remote}'") unless response.ok?
167
+ (options[:requests] || RECURSIVE_READERS).to_i.times do
168
+ break unless process_next_entry
169
+ end
165
170
  end
171
+ else
172
+ @active -= 1
173
+ process_next_entry
166
174
  end
167
175
  else
168
- 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)
169
177
  @stack = [[local]]
170
178
  process_next_entry
171
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
@@ -94,19 +96,19 @@ module Net; module SFTP
94
96
  #
95
97
  # uploader = sftp.upload("/local/path", "/remote/path")
96
98
  # uploader.wait
97
- def upload(local, remote, options={}, &block)
99
+ def upload(local, remote = File.basename(local), options={}, &block)
98
100
  Operations::Upload.new(self, local, remote, options, &block)
99
101
  end
100
102
 
101
103
  # Identical to #upload, but blocks until the upload is complete.
102
- def upload!(local, remote, options={}, &block)
104
+ def upload!(local, remote = File.basename(local), options={}, &block)
103
105
  upload(local, remote, options, &block).wait
104
106
  end
105
107
 
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")
@@ -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.
@@ -898,7 +900,7 @@ module Net; module SFTP
898
900
  @packet_length = input.read_long
899
901
  end
900
902
 
901
- return unless input.length >= @packet_length
903
+ return unless input.length >= @packet_length + 4
902
904
  packet = Net::SFTP::Packet.new(input.read(@packet_length))
903
905
  input.consume!
904
906
  @packet_length = nil
@@ -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 = 0
9
- TINY = 5
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 = 3
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
+ c2gvREM9c29sdXRpb3VzL0RDPWNvbTAeFw0yMDA0MjYwNjI0NTFaFw0yMTA0MjYw
4
+ NjI0NTFaMCUxIzAhBgNVBAMMGm5ldHNzaC9EQz1zb2x1dGlvdXMvREM9Y29tMIIB
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
+ ggEBAHZOpj9ZNefc4eoie/20zX4iOgk3i+Rmjo04sMYWEtj0+4zLHXqSjune7+hd
15
+ ruP+u5xmEy9ueGQ/0kcLlDDM+8eQo6gjCY4GIQtwAzVLsUVeejE4291/GyfPf24v
16
+ 1dLWRtPwth0nyN5EOwOPqeiYiLAr5lO3wHTgfIgFhvdZpcXG8zB6JojuFJjDpKvO
17
+ HBV0P82HXjocnjusBt1YykGCvK4cDnaRruZJh6w2XeYQJJjlbqbDfBSQVesg97yM
18
+ bwwLGaqsVz0cC6q3EpU57oyyTu529o0HnDatc94Cz8t9p6ogkKtSM+jwsnnC6wmI
19
+ MMzdZVhRg3QdHAGYfd+TfsS3Mps=
20
+ -----END CERTIFICATE-----