net-sftp 2.1.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ci.yml +35 -0
  4. data/.gitignore +6 -0
  5. data/CHANGES.txt +4 -0
  6. data/Gemfile +15 -0
  7. data/README.rdoc +7 -4
  8. data/Rakefile +24 -30
  9. data/lib/net/sftp/operations/dir.rb +3 -3
  10. data/lib/net/sftp/operations/download.rb +8 -7
  11. data/lib/net/sftp/operations/file.rb +32 -9
  12. data/lib/net/sftp/operations/upload.rb +3 -3
  13. data/lib/net/sftp/session.rb +7 -5
  14. data/lib/net/sftp/version.rb +63 -13
  15. data/lib/net/sftp.rb +12 -4
  16. data/net-sftp-public_cert.pem +20 -0
  17. data/net-sftp.gemspec +35 -93
  18. data.tar.gz.sig +0 -0
  19. metadata +53 -82
  20. metadata.gz.sig +0 -0
  21. data/gem-public_cert.pem +0 -20
  22. data/test/common.rb +0 -184
  23. data/test/protocol/01/test_attributes.rb +0 -97
  24. data/test/protocol/01/test_base.rb +0 -210
  25. data/test/protocol/01/test_name.rb +0 -27
  26. data/test/protocol/02/test_base.rb +0 -26
  27. data/test/protocol/03/test_base.rb +0 -27
  28. data/test/protocol/04/test_attributes.rb +0 -148
  29. data/test/protocol/04/test_base.rb +0 -74
  30. data/test/protocol/04/test_name.rb +0 -53
  31. data/test/protocol/05/test_base.rb +0 -62
  32. data/test/protocol/06/test_attributes.rb +0 -124
  33. data/test/protocol/06/test_base.rb +0 -51
  34. data/test/protocol/test_base.rb +0 -42
  35. data/test/test_all.rb +0 -7
  36. data/test/test_dir.rb +0 -47
  37. data/test/test_download.rb +0 -287
  38. data/test/test_file.rb +0 -159
  39. data/test/test_file_factory.rb +0 -48
  40. data/test/test_packet.rb +0 -9
  41. data/test/test_protocol.rb +0 -17
  42. data/test/test_request.rb +0 -71
  43. data/test/test_response.rb +0 -53
  44. data/test/test_session.rb +0 -741
  45. data/test/test_upload.rb +0 -233
@@ -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