net-sftp 2.0.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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-----
|