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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data/.gitignore +5 -0
- data/.travis.yml +20 -0
- data/{CHANGELOG.rdoc → CHANGES.txt} +18 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +19 -0
- data/README.rdoc +23 -1
- data/Rakefile +44 -21
- data/lib/net/sftp/operations/dir.rb +3 -3
- data/lib/net/sftp/operations/download.rb +8 -7
- data/lib/net/sftp/operations/file.rb +30 -8
- data/lib/net/sftp/operations/upload.rb +14 -6
- data/lib/net/sftp/session.rb +9 -7
- data/lib/net/sftp/version.rb +63 -13
- data/lib/net/sftp.rb +12 -4
- data/net-sftp-public_cert.pem +20 -0
- data/net-sftp.gemspec +38 -24
- data.tar.gz.sig +0 -0
- metadata +110 -127
- metadata.gz.sig +0 -0
- data/test/common.rb +0 -172
- data/test/protocol/01/test_attributes.rb +0 -97
- data/test/protocol/01/test_base.rb +0 -210
- data/test/protocol/01/test_name.rb +0 -27
- data/test/protocol/02/test_base.rb +0 -26
- data/test/protocol/03/test_base.rb +0 -27
- data/test/protocol/04/test_attributes.rb +0 -148
- data/test/protocol/04/test_base.rb +0 -74
- data/test/protocol/04/test_name.rb +0 -53
- data/test/protocol/05/test_base.rb +0 -62
- data/test/protocol/06/test_attributes.rb +0 -124
- data/test/protocol/06/test_base.rb +0 -51
- data/test/protocol/test_base.rb +0 -42
- data/test/test_all.rb +0 -7
- data/test/test_dir.rb +0 -47
- data/test/test_download.rb +0 -252
- data/test/test_file.rb +0 -159
- data/test/test_file_factory.rb +0 -48
- data/test/test_packet.rb +0 -9
- data/test/test_protocol.rb +0 -17
- data/test/test_request.rb +0 -71
- data/test/test_response.rb +0 -53
- data/test/test_session.rb +0 -741
- 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
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
|
-
|
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
|
-
|
2
|
-
require
|
1
|
+
require "rubygems"
|
2
|
+
require "rake"
|
3
|
+
require "rake/clean"
|
4
|
+
require "rdoc/task"
|
5
|
+
require "bundler/gem_tasks"
|
3
6
|
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
-
|
11
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
15
|
+
task :default => ["build"]
|
16
|
+
CLEAN.include [ 'pkg', 'rdoc' ]
|
17
|
+
name = "net-sftp"
|
18
18
|
|
19
|
-
|
20
|
-
|
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
|
-
|
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
|
-
|
27
|
-
|
36
|
+
require 'rake/testtask'
|
37
|
+
Rake::TestTask.new do |t|
|
38
|
+
t.libs = ["lib", "test"]
|
39
|
+
end
|
28
40
|
|
29
|
-
|
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
|
60
|
+
path = path.chop if path.end_with?('/') && path != '/'
|
61
61
|
|
62
62
|
results = [] unless block_given?
|
63
|
-
queue = entries(path).reject { |e|
|
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}
|
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}
|
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}
|
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}
|
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}
|
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}
|
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
|
-
|
87
|
-
|
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(
|
112
|
-
line = gets(
|
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
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
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.
|
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
|
data/lib/net/sftp/session.rb
CHANGED
@@ -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
|
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
|
data/lib/net/sftp/version.rb
CHANGED
@@ -1,18 +1,68 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
|
6
|
-
class Version < Net::SSH::Version
|
7
|
-
MAJOR = 2
|
8
|
-
MINOR = 0
|
9
|
-
TINY = 5
|
24
|
+
attr_reader :major, :minor, :tiny
|
10
25
|
|
11
|
-
|
12
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
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-----
|