net-sftp 2.1.2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,124 +0,0 @@
1
- require 'common'
2
-
3
- module Etc; end
4
-
5
- class Protocol::V06::TestAttributes < Net::SFTP::TestCase
6
- def test_from_buffer_should_correctly_parse_buffer_and_return_attribute_object
7
- attributes = attributes_factory.from_buffer(full_buffer)
8
-
9
- assert_equal 9, attributes.type
10
- assert_equal 1234567890, attributes.size
11
- assert_equal 2345678901, attributes.allocation_size
12
- assert_equal "jamis", attributes.owner
13
- assert_equal "users", attributes.group
14
- assert_equal 0755, attributes.permissions
15
- assert_equal 1234567890, attributes.atime
16
- assert_equal 12345, attributes.atime_nseconds
17
- assert_equal 2345678901, attributes.createtime
18
- assert_equal 23456, attributes.createtime_nseconds
19
- assert_equal 3456789012, attributes.mtime
20
- assert_equal 34567, attributes.mtime_nseconds
21
- assert_equal 4567890123, attributes.ctime
22
- assert_equal 45678, attributes.ctime_nseconds
23
-
24
- assert_equal 2, attributes.acl.length
25
-
26
- assert_equal 1, attributes.acl.first.type
27
- assert_equal 2, attributes.acl.first.flag
28
- assert_equal 3, attributes.acl.first.mask
29
- assert_equal "foo", attributes.acl.first.who
30
-
31
- assert_equal 4, attributes.acl.last.type
32
- assert_equal 5, attributes.acl.last.flag
33
- assert_equal 6, attributes.acl.last.mask
34
- assert_equal "bar", attributes.acl.last.who
35
-
36
- assert_equal 0x12341234, attributes.attrib_bits
37
- assert_equal 0x23452345, attributes.attrib_bits_valid
38
- assert_equal 0x3, attributes.text_hint
39
- assert_equal "text/html", attributes.mime_type
40
- assert_equal 144, attributes.link_count
41
- assert_equal "an untranslated name", attributes.untranslated_name
42
-
43
- assert_equal "second", attributes.extended["first"]
44
- end
45
-
46
- def test_from_buffer_should_correctly_parse_buffer_with_attribute_subset_and_return_attribute_object
47
- buffer = Net::SSH::Buffer.from(:long, 0x4, :byte, 1, :long, 0755)
48
-
49
- attributes = attributes_factory.from_buffer(buffer)
50
-
51
- assert_equal 1, attributes.type
52
- assert_equal 0755, attributes.permissions
53
-
54
- assert_nil attributes.size
55
- assert_nil attributes.allocation_size
56
- assert_nil attributes.owner
57
- assert_nil attributes.group
58
- assert_nil attributes.atime
59
- assert_nil attributes.atime_nseconds
60
- assert_nil attributes.createtime
61
- assert_nil attributes.createtime_nseconds
62
- assert_nil attributes.mtime
63
- assert_nil attributes.mtime_nseconds
64
- assert_nil attributes.ctime
65
- assert_nil attributes.ctime_nseconds
66
- assert_nil attributes.acl
67
- assert_nil attributes.attrib_bits
68
- assert_nil attributes.attrib_bits_valid
69
- assert_nil attributes.text_hint
70
- assert_nil attributes.mime_type
71
- assert_nil attributes.link_count
72
- assert_nil attributes.untranslated_name
73
- assert_nil attributes.extended
74
- end
75
-
76
- def test_attributes_to_s_should_build_binary_representation
77
- attributes = attributes_factory.new(
78
- :type => 9,
79
- :size => 1234567890, :allocation_size => 2345678901,
80
- :owner => "jamis", :group => "users",
81
- :permissions => 0755,
82
- :atime => 1234567890, :atime_nseconds => 12345,
83
- :createtime => 2345678901, :createtime_nseconds => 23456,
84
- :mtime => 3456789012, :mtime_nseconds => 34567,
85
- :ctime => 4567890123, :ctime_nseconds => 45678,
86
- :acl => [attributes_factory::ACL.new(1,2,3,"foo"),
87
- attributes_factory::ACL.new(4,5,6,"bar")],
88
- :attrib_bits => 0x12341234, :attrib_bits_valid => 0x23452345,
89
- :text_hint => 0x3, :mime_type => "text/html",
90
- :link_count => 144, :untranslated_name => "an untranslated name",
91
- :extended => { "first" => "second" })
92
-
93
- assert_equal full_buffer.to_s, attributes.to_s
94
- end
95
-
96
- def test_attributes_to_s_should_build_binary_representation_when_subset_is_present
97
- attributes = attributes_factory.new(:permissions => 0755)
98
- assert_equal Net::SSH::Buffer.from(:long, 0x4, :byte, 1, :long, 0755).to_s, attributes.to_s
99
- end
100
-
101
- private
102
-
103
- def full_buffer
104
- Net::SSH::Buffer.from(:long, 0x8000fffd,
105
- :byte, 9, :int64, 1234567890, :int64, 2345678901,
106
- :string, "jamis", :string, "users",
107
- :long, 0755,
108
- :int64, 1234567890, :long, 12345,
109
- :int64, 2345678901, :long, 23456,
110
- :int64, 3456789012, :long, 34567,
111
- :int64, 4567890123, :long, 45678,
112
- :string, raw(:long, 2,
113
- :long, 1, :long, 2, :long, 3, :string, "foo",
114
- :long, 4, :long, 5, :long, 6, :string, "bar"),
115
- :long, 0x12341234, :long, 0x23452345,
116
- :byte, 0x3, :string, "text/html", :long, 144,
117
- :string, "an untranslated name",
118
- :long, 1, :string, "first", :string, "second")
119
- end
120
-
121
- def attributes_factory
122
- Net::SFTP::Protocol::V06::Attributes
123
- end
124
- end
@@ -1,51 +0,0 @@
1
- require 'common'
2
- require 'protocol/05/test_base'
3
-
4
- class Protocol::V06::TestBase < Protocol::V05::TestBase
5
- include Net::SFTP::Constants::OpenFlags
6
- include Net::SFTP::Constants
7
-
8
- def test_version
9
- assert_equal 6, @base.version
10
- end
11
-
12
- def test_parse_attrs_packet_should_use_correct_attributes_class
13
- Net::SFTP::Protocol::V06::Attributes.expects(:from_buffer).with(:packet).returns(:result)
14
- assert_equal({ :attrs => :result }, @base.parse_attrs_packet(:packet))
15
- end
16
-
17
- undef test_link_should_raise_not_implemented_error
18
- undef test_block_should_raise_not_implemented_error
19
- undef test_unblock_should_raise_not_implemented_error
20
- undef test_symlink_should_send_symlink_packet
21
-
22
- def test_link_should_send_link_packet
23
- @session.expects(:send_packet).with(FXP_LINK, :long, 0, :string, "/path/to/link", :string, "/path/to/file", :bool, true)
24
- assert_equal 0, @base.link("/path/to/link", "/path/to/file", true)
25
- end
26
-
27
- def test_symlink_should_send_link_packet_as_symlink
28
- @session.expects(:send_packet).with(FXP_LINK, :long, 0, :string, "/path/to/link", :string, "/path/to/file", :bool, true)
29
- assert_equal 0, @base.symlink("/path/to/link", "/path/to/file")
30
- end
31
-
32
- def test_block_should_send_block_packet
33
- @session.expects(:send_packet).with(FXP_BLOCK, :long, 0, :string, "handle", :int64, 1234, :int64, 4567, :long, 0x40)
34
- assert_equal 0, @base.block("handle", 1234, 4567, 0x40)
35
- end
36
-
37
- def test_unblock_should_send_unblock_packet
38
- @session.expects(:send_packet).with(FXP_UNBLOCK, :long, 0, :string, "handle", :int64, 1234, :int64, 4567)
39
- assert_equal 0, @base.unblock("handle", 1234, 4567)
40
- end
41
-
42
- private
43
-
44
- def driver
45
- Net::SFTP::Protocol::V06::Base
46
- end
47
-
48
- def attributes
49
- Net::SFTP::Protocol::V06::Attributes
50
- end
51
- end
@@ -1,42 +0,0 @@
1
- require 'common'
2
-
3
- class Protocol::TestBase < Net::SFTP::TestCase
4
- def setup
5
- @base = Net::SFTP::Protocol::Base.new(stub('session', :logger => nil))
6
- end
7
-
8
- def test_parse_with_status_packet_should_delegate_to_parse_status_packet
9
- packet = stub('packet', :type => FXP_STATUS)
10
- @base.expects(:parse_status_packet).with(packet).returns(:result)
11
- assert_equal :result, @base.parse(packet)
12
- end
13
-
14
- def test_parse_with_handle_packet_should_delegate_to_parse_handle_packet
15
- packet = stub('packet', :type => FXP_HANDLE)
16
- @base.expects(:parse_handle_packet).with(packet).returns(:result)
17
- assert_equal :result, @base.parse(packet)
18
- end
19
-
20
- def test_parse_with_data_packet_should_delegate_to_parse_data_packet
21
- packet = stub('packet', :type => FXP_DATA)
22
- @base.expects(:parse_data_packet).with(packet).returns(:result)
23
- assert_equal :result, @base.parse(packet)
24
- end
25
-
26
- def test_parse_with_name_packet_should_delegate_to_parse_name_packet
27
- packet = stub('packet', :type => FXP_NAME)
28
- @base.expects(:parse_name_packet).with(packet).returns(:result)
29
- assert_equal :result, @base.parse(packet)
30
- end
31
-
32
- def test_parse_with_attrs_packet_should_delegate_to_parse_attrs_packet
33
- packet = stub('packet', :type => FXP_ATTRS)
34
- @base.expects(:parse_attrs_packet).with(packet).returns(:result)
35
- assert_equal :result, @base.parse(packet)
36
- end
37
-
38
- def test_parse_with_unknown_packet_should_raise_exception
39
- packet = stub('packet', :type => FXP_WRITE)
40
- assert_raises(NotImplementedError) { @base.parse(packet) }
41
- end
42
- end
data/test/test_all.rb DELETED
@@ -1,7 +0,0 @@
1
- # $ ruby -I../net-ssh/lib -Ilib -Itest -rrubygems test/test_all.rb
2
- #require 'net/ssh'
3
- #puts Net::SSH::Version::CURRENT
4
- require 'common'
5
- Dir.chdir(File.dirname(__FILE__)) do
6
- Dir['**/test_*.rb'].each { |file| require(file) unless file == File.basename(__FILE__) }
7
- end
data/test/test_dir.rb DELETED
@@ -1,47 +0,0 @@
1
- require 'common'
2
-
3
- class DirOperationsTest < Net::SFTP::TestCase
4
- def setup
5
- @sftp = mock("sftp")
6
- @dir = Net::SFTP::Operations::Dir.new(@sftp)
7
- end
8
-
9
- def test_foreach_should_iterate_over_all_entries_in_directory
10
- @sftp.expects(:opendir!).with("/path/to/remote").returns("handle")
11
- @sftp.expects(:readdir!).with("handle").returns([:e1, :e2, :e3], [:e4, :e5], nil).times(3)
12
- @sftp.expects(:close!).with("handle")
13
-
14
- entries = []
15
- @dir.foreach("/path/to/remote") { |entry| entries << entry }
16
- assert_equal [:e1, :e2, :e3, :e4, :e5], entries
17
- end
18
-
19
- def test_entries_should_return_all_entries_in_a_single_array
20
- @sftp.expects(:opendir!).with("/path/to/remote").returns("handle")
21
- @sftp.expects(:readdir!).with("handle").returns([:e1, :e2, :e3], [:e4, :e5], nil).times(3)
22
- @sftp.expects(:close!).with("handle")
23
-
24
- assert_equal [:e1, :e2, :e3, :e4, :e5], @dir.entries("/path/to/remote")
25
- end
26
-
27
- def test_glob_should_search_under_path_for_matching_entries
28
- @sftp.expects(:opendir!).with("/path/to/remote").returns("handle")
29
- @sftp.expects(:opendir!).with("/path/to/remote/e3").returns("handle-e3")
30
- @sftp.expects(:opendir!).with("/path/to/remote/e5").returns("handle-e5")
31
- @sftp.expects(:readdir!).with("handle").returns([n(".", true), n("..", true), n("e1"), n("e2"), n("e3", true)], [n("e4"), n("e5", true)], nil).times(3)
32
- @sftp.expects(:readdir!).with("handle-e3").returns([n(".", true), n("..", true), n("e3e1"), n("e3e2")], nil).times(2)
33
- @sftp.expects(:readdir!).with("handle-e5").returns([n(".", true), n("..", true), n("e5e1"), n("e5e2"), n("e5e3")], nil).times(2)
34
- @sftp.expects(:close!).with("handle")
35
- @sftp.expects(:close!).with("handle-e3")
36
- @sftp.expects(:close!).with("handle-e5")
37
-
38
- assert_equal %w(e3/e3e2 e5/e5e2), @dir.glob("/path/to/remote", "**/e?e2").map { |e| e.name }
39
- end
40
-
41
- private
42
-
43
- def n(name, directory=false)
44
- Net::SFTP::Protocol::V01::Name.new(name.to_s, "longname for #{name}",
45
- Net::SFTP::Protocol::V01::Attributes.new(:permissions => directory ? 040755 : 0100644))
46
- end
47
- end
@@ -1,287 +0,0 @@
1
- require "common"
2
-
3
- class DownloadTest < Net::SFTP::TestCase
4
- FXP_DATA_CHUNK_SIZE = 1024
5
-
6
- def setup
7
- prepare_progress!
8
- end
9
-
10
- def test_download_file_should_transfer_remote_to_local
11
- local = "/path/to/local"
12
- remote = "/path/to/remote"
13
- text = "this is some text\n"
14
-
15
- expect_file_transfer(remote, text)
16
-
17
- file = StringIO.new
18
- File.stubs(:open).with(local, "wb").returns(file)
19
-
20
- assert_scripted_command { sftp.download(remote, local) }
21
- assert_equal text, file.string
22
- end
23
-
24
- def test_download_file_should_transfer_remote_to_local_in_spite_of_fragmentation
25
- local = "/path/to/local"
26
- remote = "/path/to/remote"
27
- text = "this is some text\n"
28
-
29
- expect_file_transfer(remote, text, :fragment_len => 1)
30
-
31
- file = StringIO.new
32
- File.stubs(:open).with(local, "wb").returns(file)
33
-
34
- assert_scripted_command { sftp.download(remote, local) }
35
- assert_equal text, file.string
36
- end
37
-
38
- def test_download_large_file_should_transfer_remote_to_local
39
- local = "/path/to/local"
40
- remote = "/path/to/remote"
41
- text = "0123456789" * 1024
42
-
43
- file = prepare_large_file_download(local, remote, text)
44
-
45
- assert_scripted_command { sftp.download(remote, local, :read_size => 1024) }
46
- assert_equal text, file.string
47
- end
48
-
49
- def test_download_large_file_should_handle_too_large_read_size
50
- local = "/path/to/local"
51
- remote = "/path/to/remote"
52
- text = "0123456789" * 1024
53
-
54
- # some servers put upper bound on the max read_size value and send less data than requested
55
- too_large_read_size = FXP_DATA_CHUNK_SIZE + 1
56
- file = prepare_large_file_download(local, remote, text, too_large_read_size)
57
-
58
- assert_scripted_command { sftp.download(remote, local, :read_size => too_large_read_size) }
59
- assert_equal text, file.string
60
- end
61
-
62
- def test_download_large_file_with_progress_should_report_progress
63
- local = "/path/to/local"
64
- remote = "/path/to/remote"
65
- text = "0123456789" * 1024
66
-
67
- file = prepare_large_file_download(local, remote, text)
68
-
69
- assert_scripted_command do
70
- sftp.download(remote, local, :read_size => 1024) do |*args|
71
- record_progress(args)
72
- end
73
- end
74
-
75
- assert_equal text, file.string
76
-
77
- assert_progress_reported_open :remote => "/path/to/remote"
78
- assert_progress_reported_get 0, 1024
79
- assert_progress_reported_get 1024, 1024
80
- assert_progress_reported_get 2048, 1024
81
- assert_progress_reported_get 3072, 1024
82
- assert_progress_reported_get 4096, 1024
83
- assert_progress_reported_get 5120, 1024
84
- assert_progress_reported_get 6144, 1024
85
- assert_progress_reported_get 7168, 1024
86
- assert_progress_reported_get 8192, 1024
87
- assert_progress_reported_get 9216, 1024
88
- assert_progress_reported_close
89
- assert_progress_reported_finish
90
- assert_no_more_reported_events
91
- end
92
-
93
- def test_download_directory_should_mirror_directory_locally
94
- file1, file2 = prepare_directory_tree_download("/path/to/local", "/path/to/remote")
95
-
96
- assert_scripted_command do
97
- sftp.download("/path/to/remote", "/path/to/local", :recursive => true)
98
- end
99
-
100
- assert_equal "contents of file1", file1.string
101
- assert_equal "contents of file2", file2.string
102
- end
103
-
104
- def test_download_directory_with_progress_should_report_progress
105
- file1, file2 = prepare_directory_tree_download("/path/to/local", "/path/to/remote")
106
-
107
- assert_scripted_command do
108
- sftp.download("/path/to/remote", "/path/to/local", :recursive => true) do |*args|
109
- record_progress(args)
110
- end
111
- end
112
-
113
- assert_equal "contents of file1", file1.string
114
- assert_equal "contents of file2", file2.string
115
-
116
- assert_progress_reported_mkdir "/path/to/local"
117
- assert_progress_reported_mkdir "/path/to/local/subdir1"
118
- assert_progress_reported_open :remote => "/path/to/remote/file1"
119
- assert_progress_reported_open :remote => "/path/to/remote/subdir1/file2"
120
- assert_progress_reported_get 0, "contents of file1"
121
- assert_progress_reported_close :remote => "/path/to/remote/file1"
122
- assert_progress_reported_get 0, "contents of file2"
123
- assert_progress_reported_close :remote => "/path/to/remote/subdir1/file2"
124
- assert_progress_reported_finish
125
- assert_no_more_reported_events
126
- end
127
-
128
- def test_download_file_should_transfer_remote_to_local_buffer
129
- remote = "/path/to/remote"
130
- text = "this is some text\n"
131
-
132
- expect_file_transfer(remote, text)
133
-
134
- local = StringIO.new
135
-
136
- assert_scripted_command { sftp.download(remote, local) }
137
- assert_equal text, local.string
138
- end
139
-
140
- def test_download_directory_to_buffer_should_fail
141
- expect_sftp_session :server_version => 3
142
- assert_raises(ArgumentError) { sftp.download("/path/to/remote", StringIO.new, :recursive => true) }
143
- end
144
-
145
- private
146
-
147
- def expect_file_transfer(remote, text, opts={})
148
- expect_sftp_session :server_version => 3 do |channel|
149
- channel.sends_packet(FXP_OPEN, :long, 0, :string, remote, :long, 0x01, :long, 0)
150
- channel.gets_packet(FXP_HANDLE, :long, 0, :string, "handle")
151
- channel.sends_packet(FXP_READ, :long, 1, :string, "handle", :int64, 0, :long, 32_000)
152
- channel.gets_packet_in_two(opts[:fragment_len], FXP_DATA, :long, 1, :string, text)
153
- channel.sends_packet(FXP_READ, :long, 2, :string, "handle", :int64, text.bytesize, :long, 32_000)
154
- channel.gets_packet(FXP_STATUS, :long, 2, :long, 1)
155
- channel.sends_packet(FXP_CLOSE, :long, 3, :string, "handle")
156
- channel.gets_packet(FXP_STATUS, :long, 3, :long, 0)
157
- end
158
- end
159
-
160
- def prepare_large_file_download(local, remote, text, requested_chunk_size = FXP_DATA_CHUNK_SIZE)
161
- expect_sftp_session :server_version => 3 do |channel|
162
- channel.sends_packet(FXP_OPEN, :long, 0, :string, remote, :long, 0x01, :long, 0)
163
- channel.gets_packet(FXP_HANDLE, :long, 0, :string, "handle")
164
- offset = 0
165
- data_packet_count = (text.bytesize / FXP_DATA_CHUNK_SIZE.to_f).ceil
166
- data_packet_count.times do |n|
167
- payload = text[n*FXP_DATA_CHUNK_SIZE,FXP_DATA_CHUNK_SIZE]
168
- channel.sends_packet(FXP_READ, :long, n+1, :string, "handle", :int64, offset, :long, requested_chunk_size)
169
- offset += payload.bytesize
170
- channel.gets_packet(FXP_DATA, :long, n+1, :string, payload)
171
- end
172
- channel.sends_packet(FXP_READ, :long, data_packet_count + 1, :string, "handle", :int64, offset, :long, requested_chunk_size)
173
- channel.gets_packet(FXP_STATUS, :long, data_packet_count + 1, :long, 1)
174
- channel.sends_packet(FXP_CLOSE, :long, data_packet_count + 2, :string, "handle")
175
- channel.gets_packet(FXP_STATUS, :long, data_packet_count + 2, :long, 0)
176
- end
177
-
178
- file = StringIO.new
179
- File.stubs(:open).with(local, "wb").returns(file)
180
-
181
- return file
182
- end
183
-
184
- # 0:OPENDIR(remote) ->
185
- # <- 0:HANDLE("dir1")
186
- # 1:READDIR("dir1") ->
187
- # <- 1:NAME("..", ".", "subdir1", "file1")
188
- # 2:OPENDIR(remote/subdir1) ->
189
- # 3:OPEN(remote/file1) ->
190
- # 4:READDIR("dir1") ->
191
- # <- 2:HANDLE("dir2")
192
- # 5:READDIR("dir2") ->
193
- # <- 3:HANDLE("file1")
194
- # 6:READ("file1", 0, 32k) ->
195
- # <- 4:STATUS(1)
196
- # 7:CLOSE("dir1") ->
197
- # <- 5:NAME("..", ".", "file2")
198
- # 8:OPEN(remote/subdir1/file2) ->
199
- # 9:READDIR("dir2") ->
200
- # <- 6:DATA("blah blah blah")
201
- # 10:READ("file1", n, 32k)
202
- # <- 7:STATUS(0)
203
- # <- 8:HANDLE("file2")
204
- # 11:READ("file2", 0, 32k) ->
205
- # <- 9:STATUS(1)
206
- # 12:CLOSE("dir2") ->
207
- # <- 10:STATUS(1)
208
- # 13:CLOSE("file1") ->
209
- # <- 11:DATA("blah blah blah")
210
- # 14:READ("file2", n, 32k) ->
211
- # <- 12:STATUS(0)
212
- # <- 13:STATUS(0)
213
- # <- 14:STATUS(1)
214
- # 15:CLOSE("file2") ->
215
- # <- 15:STATUS(0)
216
-
217
- def prepare_directory_tree_download(local, remote)
218
- file1_contents = "contents of file1"
219
- file2_contents = "contents of file2"
220
- expect_sftp_session :server_version => 3 do |channel|
221
- channel.sends_packet(FXP_OPENDIR, :long, 0, :string, remote)
222
- channel.gets_packet(FXP_HANDLE, :long, 0, :string, "dir1")
223
-
224
- channel.sends_packet(FXP_READDIR, :long, 1, :string, "dir1")
225
- channel.gets_packet(FXP_NAME, :long, 1, :long, 4,
226
- :string, "..", :string, "drwxr-xr-x 4 bob bob 136 Aug 1 ..", :long, 0x04, :long, 040755,
227
- :string, ".", :string, "drwxr-xr-x 4 bob bob 136 Aug 1 .", :long, 0x04, :long, 040755,
228
- :string, "subdir1", :string, "drwxr-xr-x 4 bob bob 136 Aug 1 subdir1", :long, 0x04, :long, 040755,
229
- :string, "file1", :string, "-rw-rw-r-- 1 bob bob 100 Aug 1 file1", :long, 0x04, :long, 0100644)
230
-
231
- channel.sends_packet(FXP_OPENDIR, :long, 2, :string, File.join(remote, "subdir1"))
232
- channel.sends_packet(FXP_OPEN, :long, 3, :string, File.join(remote, "file1"), :long, 0x01, :long, 0)
233
- channel.sends_packet(FXP_READDIR, :long, 4, :string, "dir1")
234
-
235
- channel.gets_packet(FXP_HANDLE, :long, 2, :string, "dir2")
236
- channel.sends_packet(FXP_READDIR, :long, 5, :string, "dir2")
237
-
238
- channel.gets_packet(FXP_HANDLE, :long, 3, :string, "file1")
239
- channel.sends_packet(FXP_READ, :long, 6, :string, "file1", :int64, 0, :long, 32_000)
240
-
241
- channel.gets_packet(FXP_STATUS, :long, 4, :long, 1)
242
- channel.sends_packet(FXP_CLOSE, :long, 7, :string, "dir1")
243
-
244
- channel.gets_packet(FXP_NAME, :long, 5, :long, 3,
245
- :string, "..", :string, "drwxr-xr-x 4 bob bob 136 Aug 1 ..", :long, 0x04, :long, 040755,
246
- :string, ".", :string, "drwxr-xr-x 4 bob bob 136 Aug 1 .", :long, 0x04, :long, 040755,
247
- :string, "file2", :string, "-rw-rw-r-- 1 bob bob 100 Aug 1 file2", :long, 0x04, :long, 0100644)
248
-
249
- channel.sends_packet(FXP_OPEN, :long, 8, :string, File.join(remote, "subdir1", "file2"), :long, 0x01, :long, 0)
250
- channel.sends_packet(FXP_READDIR, :long, 9, :string, "dir2")
251
-
252
- channel.gets_packet(FXP_DATA, :long, 6, :string, file1_contents)
253
- channel.sends_packet(FXP_READ, :long, 10, :string, "file1", :int64, file1_contents.bytesize, :long, 32_000)
254
-
255
- channel.gets_packet(FXP_STATUS, :long, 7, :long, 0)
256
- channel.gets_packet(FXP_HANDLE, :long, 8, :string, "file2")
257
- channel.sends_packet(FXP_READ, :long, 11, :string, "file2", :int64, 0, :long, 32_000)
258
-
259
- channel.gets_packet(FXP_STATUS, :long, 9, :long, 1)
260
- channel.sends_packet(FXP_CLOSE, :long, 12, :string, "dir2")
261
-
262
- channel.gets_packet(FXP_STATUS, :long, 10, :long, 1)
263
- channel.sends_packet(FXP_CLOSE, :long, 13, :string, "file1")
264
-
265
- channel.gets_packet(FXP_DATA, :long, 11, :string, file2_contents)
266
- channel.sends_packet(FXP_READ, :long, 14, :string, "file2", :int64, file2_contents.bytesize, :long, 32_000)
267
-
268
- channel.gets_packet(FXP_STATUS, :long, 12, :long, 0)
269
- channel.gets_packet(FXP_STATUS, :long, 13, :long, 0)
270
- channel.gets_packet(FXP_STATUS, :long, 14, :long, 1)
271
- channel.sends_packet(FXP_CLOSE, :long, 15, :string, "file2")
272
- channel.gets_packet(FXP_STATUS, :long, 15, :long, 0)
273
- end
274
-
275
- File.expects(:directory?).with(local).returns(false)
276
- File.expects(:directory?).with(File.join(local, "subdir1")).returns(false)
277
- Dir.expects(:mkdir).with(local)
278
- Dir.expects(:mkdir).with(File.join(local, "subdir1"))
279
-
280
- file1 = StringIO.new
281
- file2 = StringIO.new
282
- File.expects(:open).with(File.join(local, "file1"), "wb").returns(file1)
283
- File.expects(:open).with(File.join(local, "subdir1", "file2"), "wb").returns(file2)
284
-
285
- [file1, file2]
286
- end
287
- end