ftpd 2.0.1 → 2.0.2

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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +6 -0
  3. data/Gemfile +2 -15
  4. data/Gemfile.lock +12 -51
  5. data/README.md +12 -0
  6. data/VERSION +1 -1
  7. data/bin/ftpdrb +17 -12
  8. data/examples/write_only.rb +61 -0
  9. data/ftpd.gemspec +59 -261
  10. data/lib/ftpd/session.rb +51 -51
  11. metadata +11 -153
  12. data/.travis.yml +0 -6
  13. data/features/example/eplf.feature +0 -14
  14. data/features/example/example.feature +0 -18
  15. data/features/example/read_only.feature +0 -63
  16. data/features/example/step_definitions/example_server.rb +0 -13
  17. data/features/ftp_server/abort.feature +0 -13
  18. data/features/ftp_server/allo.feature +0 -33
  19. data/features/ftp_server/append.feature +0 -94
  20. data/features/ftp_server/cdup.feature +0 -36
  21. data/features/ftp_server/command_errors.feature +0 -13
  22. data/features/ftp_server/concurrent_sessions.feature +0 -14
  23. data/features/ftp_server/delay_after_failed_login.feature +0 -23
  24. data/features/ftp_server/delete.feature +0 -60
  25. data/features/ftp_server/directory_navigation.feature +0 -59
  26. data/features/ftp_server/disconnect_after_failed_logins.feature +0 -25
  27. data/features/ftp_server/eprt.feature +0 -56
  28. data/features/ftp_server/epsv.feature +0 -37
  29. data/features/ftp_server/features.feature +0 -38
  30. data/features/ftp_server/file_structure.feature +0 -43
  31. data/features/ftp_server/get.feature +0 -80
  32. data/features/ftp_server/get_ipv6.feature +0 -46
  33. data/features/ftp_server/get_tls.feature +0 -23
  34. data/features/ftp_server/help.feature +0 -21
  35. data/features/ftp_server/implicit_tls.feature +0 -23
  36. data/features/ftp_server/invertability.feature +0 -15
  37. data/features/ftp_server/list.feature +0 -94
  38. data/features/ftp_server/list_tls.feature +0 -29
  39. data/features/ftp_server/logging.feature +0 -11
  40. data/features/ftp_server/login_auth_level_account.feature +0 -51
  41. data/features/ftp_server/login_auth_level_password.feature +0 -59
  42. data/features/ftp_server/login_auth_level_user.feature +0 -31
  43. data/features/ftp_server/max_connections.feature +0 -39
  44. data/features/ftp_server/mdtm.feature +0 -53
  45. data/features/ftp_server/mkdir.feature +0 -70
  46. data/features/ftp_server/mode.feature +0 -43
  47. data/features/ftp_server/name_list.feature +0 -77
  48. data/features/ftp_server/name_list_tls.feature +0 -30
  49. data/features/ftp_server/noop.feature +0 -17
  50. data/features/ftp_server/options.feature +0 -17
  51. data/features/ftp_server/pasv.feature +0 -30
  52. data/features/ftp_server/port.feature +0 -49
  53. data/features/ftp_server/put.feature +0 -79
  54. data/features/ftp_server/put_tls.feature +0 -23
  55. data/features/ftp_server/put_unique.feature +0 -56
  56. data/features/ftp_server/quit.feature +0 -23
  57. data/features/ftp_server/reinitialize.feature +0 -13
  58. data/features/ftp_server/rename.feature +0 -97
  59. data/features/ftp_server/rmdir.feature +0 -71
  60. data/features/ftp_server/site.feature +0 -13
  61. data/features/ftp_server/size.feature +0 -69
  62. data/features/ftp_server/status.feature +0 -18
  63. data/features/ftp_server/step_definitions/logging.rb +0 -10
  64. data/features/ftp_server/step_definitions/test_server.rb +0 -71
  65. data/features/ftp_server/structure_mount.feature +0 -13
  66. data/features/ftp_server/syntax_errors.feature +0 -18
  67. data/features/ftp_server/syst.feature +0 -18
  68. data/features/ftp_server/timeout.feature +0 -26
  69. data/features/ftp_server/type.feature +0 -59
  70. data/features/step_definitions/append.rb +0 -17
  71. data/features/step_definitions/client.rb +0 -27
  72. data/features/step_definitions/client_and_server_files.rb +0 -26
  73. data/features/step_definitions/client_files.rb +0 -16
  74. data/features/step_definitions/command.rb +0 -7
  75. data/features/step_definitions/connect.rb +0 -39
  76. data/features/step_definitions/delete.rb +0 -17
  77. data/features/step_definitions/directory_navigation.rb +0 -28
  78. data/features/step_definitions/error_replies.rb +0 -117
  79. data/features/step_definitions/features.rb +0 -23
  80. data/features/step_definitions/file_structure.rb +0 -18
  81. data/features/step_definitions/generic_send.rb +0 -11
  82. data/features/step_definitions/get.rb +0 -18
  83. data/features/step_definitions/help.rb +0 -20
  84. data/features/step_definitions/invalid_commands.rb +0 -13
  85. data/features/step_definitions/ipv6.rb +0 -11
  86. data/features/step_definitions/line_endings.rb +0 -9
  87. data/features/step_definitions/list.rb +0 -75
  88. data/features/step_definitions/login.rb +0 -84
  89. data/features/step_definitions/mkdir.rb +0 -11
  90. data/features/step_definitions/mode.rb +0 -17
  91. data/features/step_definitions/mtime.rb +0 -25
  92. data/features/step_definitions/noop.rb +0 -17
  93. data/features/step_definitions/options.rb +0 -11
  94. data/features/step_definitions/passive.rb +0 -10
  95. data/features/step_definitions/pending.rb +0 -5
  96. data/features/step_definitions/port.rb +0 -7
  97. data/features/step_definitions/put.rb +0 -31
  98. data/features/step_definitions/quit.rb +0 -17
  99. data/features/step_definitions/rename.rb +0 -13
  100. data/features/step_definitions/rmdir.rb +0 -11
  101. data/features/step_definitions/server_files.rb +0 -63
  102. data/features/step_definitions/server_title.rb +0 -14
  103. data/features/step_definitions/size.rb +0 -22
  104. data/features/step_definitions/status.rb +0 -11
  105. data/features/step_definitions/success_replies.rb +0 -9
  106. data/features/step_definitions/system.rb +0 -12
  107. data/features/step_definitions/timing.rb +0 -21
  108. data/features/step_definitions/type.rb +0 -17
  109. data/features/support/env.rb +0 -6
  110. data/features/support/example_server.rb +0 -69
  111. data/features/support/file_templates/ascii_unix +0 -4
  112. data/features/support/file_templates/ascii_windows +0 -4
  113. data/features/support/file_templates/binary +0 -0
  114. data/features/support/test_client.rb +0 -258
  115. data/features/support/test_file_templates.rb +0 -35
  116. data/features/support/test_server.rb +0 -304
  117. data/features/support/test_server_files.rb +0 -59
  118. data/rake_tasks/cucumber.rake +0 -9
  119. data/rake_tasks/default.rake +0 -1
  120. data/rake_tasks/jeweler.rake +0 -52
  121. data/rake_tasks/spec.rake +0 -3
  122. data/rake_tasks/test.rake +0 -2
  123. data/rake_tasks/yard.rake +0 -3
  124. data/spec/command_sequence_checker_spec.rb +0 -85
  125. data/spec/connection_throttle_spec.rb +0 -101
  126. data/spec/connection_tracker_spec.rb +0 -99
  127. data/spec/data_server_factory_spec.rb +0 -104
  128. data/spec/disk_file_system_spec.rb +0 -322
  129. data/spec/exception_translator_spec.rb +0 -38
  130. data/spec/file_info_spec.rb +0 -61
  131. data/spec/ftp_server_error_spec.rb +0 -15
  132. data/spec/list_format/eplf_spec.rb +0 -63
  133. data/spec/list_format/ls_spec.rb +0 -272
  134. data/spec/list_path_spec.rb +0 -23
  135. data/spec/null_logger_spec.rb +0 -26
  136. data/spec/protocols_spec.rb +0 -159
  137. data/spec/server_spec.rb +0 -83
  138. data/spec/spec_helper.rb +0 -17
  139. data/spec/telnet_spec.rb +0 -77
  140. data/spec/translate_exceptions_spec.rb +0 -42
  141. data/testlib/network.rb +0 -17
@@ -1,322 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('spec_helper', File.dirname(__FILE__))
4
-
5
- module Ftpd
6
- describe DiskFileSystem do
7
-
8
- let(:data_dir) {Ftpd::TempDir.make}
9
- let(:disk_file_system) {DiskFileSystem.new(data_dir)}
10
- let(:missing_file_error) do
11
- [Ftpd::PermanentFileSystemError, /No such file or directory/]
12
- end
13
- let(:is_a_directory_error) do
14
- [Ftpd::PermanentFileSystemError, /Is a directory/]
15
- end
16
- let(:missing_path) {'missing_path'}
17
-
18
- def data_path(path)
19
- File.join(data_dir, path)
20
- end
21
-
22
- def make_directory(path)
23
- Dir.mkdir data_path(path)
24
- end
25
-
26
- def write_file(path)
27
- File.open(data_path(path), 'wb') do |file|
28
- file.write canned_contents(path)
29
- end
30
- end
31
-
32
- def read_file(path)
33
- File.open(data_path(path), 'rb', &:read)
34
- end
35
-
36
- def directory?(path)
37
- File.directory?(data_path(path))
38
- end
39
-
40
- def exists?(path)
41
- File.exists?(data_path(path))
42
- end
43
-
44
- def canned_contents(path)
45
- "Contents of #{path}"
46
- end
47
-
48
- def add_symlink(target_path, symlink_path)
49
- FileUtils.ln_s data_path(target_path), data_path(symlink_path)
50
- end
51
-
52
- before(:each) do
53
- write_file 'file'
54
- make_directory 'dir'
55
- write_file 'dir/file_in_dir'
56
- make_directory 'unwritable_dir'
57
- write_file 'unwritable_dir/file'
58
- add_symlink 'file', 'symlink'
59
- end
60
-
61
- describe '#accessible?' do
62
-
63
- context '(within tree)' do
64
- specify do
65
- expect(disk_file_system.accessible?('file')).to be_truthy
66
- end
67
- end
68
-
69
- context '(outside tree)' do
70
- specify do
71
- expect(disk_file_system.accessible?('../outside')).to be_falsey
72
- end
73
- end
74
-
75
- end
76
-
77
- describe '#exists?' do
78
-
79
- context '(exists)' do
80
- specify do
81
- expect(disk_file_system.exists?('file')).to be_truthy
82
- end
83
- end
84
-
85
- context '(does not exist)' do
86
- specify do
87
- expect(disk_file_system.exists?('missing')).to be_falsey
88
- end
89
- end
90
-
91
- end
92
-
93
- describe '#directory?' do
94
-
95
- context '(directory)' do
96
- specify do
97
- expect(disk_file_system.directory?('file')).to be_falsey
98
- end
99
- end
100
-
101
- context '(file)' do
102
- specify do
103
- expect(disk_file_system.directory?('dir')).to be_truthy
104
- end
105
- end
106
-
107
- end
108
-
109
- describe '#delete' do
110
-
111
- context '(success)' do
112
- specify do
113
- disk_file_system.delete('file')
114
- expect(exists?('file')).to be_falsey
115
- end
116
- end
117
-
118
- context '(error)' do
119
- specify do
120
- expect {
121
- disk_file_system.delete(missing_path)
122
- }.to raise_error *missing_file_error
123
- end
124
- end
125
-
126
- end
127
-
128
- describe '#read' do
129
-
130
- context '(success)' do
131
- let(:path) {'file'}
132
- specify do
133
- disk_file_system.read(path) do |file|
134
- expect(file).to be_a(IO)
135
- expect(file.read).to eq canned_contents(path)
136
- end
137
- end
138
- end
139
-
140
- context '(error)' do
141
- specify do
142
- expect {
143
- disk_file_system.read(missing_path) {}
144
- }.to raise_error *missing_file_error
145
- end
146
- end
147
-
148
- end
149
-
150
- describe '#write' do
151
-
152
- let(:contents) {'file contents'}
153
- let(:stream) {Ftpd::Stream.new(StringIO.new(contents), nil)}
154
-
155
- context '(success)' do
156
- let(:path) {'file_path'}
157
- specify do
158
- disk_file_system.write(path, stream)
159
- expect(read_file(path)).to eq contents
160
- end
161
- end
162
-
163
- context '(error)' do
164
- specify do
165
- expect {
166
- disk_file_system.write('dir', stream)
167
- }.to raise_error *is_a_directory_error
168
- end
169
- end
170
-
171
- end
172
-
173
- describe '#append' do
174
-
175
- let(:contents) {'file contents'}
176
- let(:stream) {Ftpd::Stream.new(StringIO.new(contents), nil)}
177
-
178
- context '(destination missing)' do
179
- let(:path) {'file_path'}
180
- specify do
181
- disk_file_system.append(path, stream)
182
- expect(read_file(path)).to eq contents
183
- end
184
- end
185
-
186
- context '(destination exists)' do
187
- let(:path) {'file'}
188
- specify do
189
- disk_file_system.append(path, stream)
190
- expect(read_file(path)).to eq canned_contents(path) + contents
191
- end
192
- end
193
-
194
- context '(error)' do
195
- specify do
196
- expect {
197
- disk_file_system.append('dir', stream)
198
- }.to raise_error *is_a_directory_error
199
- end
200
- end
201
-
202
- end
203
-
204
- describe '#mkdir' do
205
-
206
- context '(success)' do
207
- let(:path) {'another_subdir'}
208
- specify do
209
- disk_file_system.mkdir(path)
210
- expect(directory?(path)).to be_truthy
211
- end
212
- end
213
-
214
- context '(error)' do
215
- specify do
216
- expect {
217
- disk_file_system.mkdir('file')
218
- }.to raise_error PermanentFileSystemError, /^File exists/
219
- end
220
- end
221
-
222
- end
223
-
224
- describe '#rename' do
225
-
226
- let(:from_path) {'file'}
227
- let(:to_path) {'renamed_file'}
228
-
229
- context '(success)' do
230
- specify do
231
- disk_file_system.rename(from_path, to_path)
232
- expect(exists?(from_path)).to be_falsey
233
- expect(exists?(to_path)).to be_truthy
234
- end
235
- end
236
-
237
- context '(error)' do
238
- specify do
239
- expect {
240
- disk_file_system.rename(missing_path, to_path)
241
- }.to raise_error *missing_file_error
242
- end
243
- end
244
-
245
- end
246
-
247
- describe '#file_info' do
248
-
249
- let(:identifier) {"#{stat.dev}.#{stat.ino}"}
250
- let(:owner) {Etc.getpwuid(stat.uid).name}
251
- let(:group) {Etc.getgrgid(stat.gid).name}
252
- let(:stat) {File.stat(data_path(path))}
253
- subject {disk_file_system.file_info(path)}
254
-
255
- shared_examples 'file info' do
256
- its(:ftype) {should == stat.ftype}
257
- its(:group) {should == group}
258
- its(:mode) {should == stat.mode}
259
- its(:mtime) {should == stat.mtime}
260
- its(:nlink) {should == stat.nlink}
261
- its(:owner) {should == owner}
262
- its(:size) {should == stat.size}
263
- its(:path) {should == path}
264
- its(:identifier) {should == identifier}
265
- end
266
-
267
- context '(file)' do
268
- let(:path) {'file'}
269
- it_behaves_like 'file info'
270
- end
271
-
272
- context '(symlink)' do
273
- let(:path) {'symlink'}
274
- it_behaves_like 'file info'
275
- end
276
-
277
- end
278
-
279
- describe '#dir' do
280
-
281
- subject(:dir) do
282
- disk_file_system.dir(path)
283
- end
284
-
285
- context '(no such file)' do
286
- let(:path) {'missing'}
287
- it {should be_empty}
288
- end
289
-
290
- context '(file)' do
291
- let(:path) {'file'}
292
- it {should include '/file'}
293
- end
294
-
295
- context '(directory)' do
296
- let(:path) {'dir'}
297
- it {should include '/dir'}
298
- it {should_not include '/dir/file_in_dir'}
299
- end
300
-
301
- context '(directory + wildcard)' do
302
- let(:path) {'dir/*'}
303
- it {should_not include '/dir'}
304
- it {should include '/dir/file_in_dir'}
305
- end
306
-
307
- context '(wildcard)' do
308
- let(:path) {'*'}
309
- it {should include '/unwritable_dir'}
310
- it {should include '/file'}
311
- it {should include '/dir'}
312
- end
313
-
314
- context '(no such directory)' do
315
- let(:path) {'foo/*'}
316
- it {should be_empty}
317
- end
318
-
319
- end
320
-
321
- end
322
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('spec_helper', File.dirname(__FILE__))
4
-
5
- module Ftpd
6
- describe ExceptionTranslator do
7
-
8
- class FooError < StandardError ; end
9
- class BarError < StandardError ; end
10
-
11
- subject(:translator) {ExceptionTranslator.new}
12
- let(:message) {'An error happened'}
13
-
14
- context '(registered exception)' do
15
- before(:each) do
16
- translator.register_exception FooError
17
- end
18
- it 'should translate the exception' do
19
- expect {
20
- subject.translate_exceptions do
21
- raise FooError, message
22
- end
23
- }.to raise_error PermanentFileSystemError, message
24
- end
25
- end
26
-
27
- context '(unregistered exception)' do
28
- it 'should pass the exception' do
29
- expect {
30
- subject.translate_exceptions do
31
- raise BarError, message
32
- end
33
- }.to raise_error BarError, message
34
- end
35
- end
36
-
37
- end
38
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('spec_helper', File.dirname(__FILE__))
4
-
5
- module Ftpd
6
- describe FileInfo do
7
-
8
- subject {FileInfo.new(opts)}
9
-
10
- def self.it_has_attribute(attribute)
11
- describe "##{attribute}" do
12
- let(:value) {"#{attribute} value"}
13
- let(:opts) {{attribute => value}}
14
- its(attribute) {should == value}
15
- end
16
- end
17
-
18
- it_has_attribute :ftype
19
- it_has_attribute :group
20
- it_has_attribute :identifier
21
- it_has_attribute :mode
22
- it_has_attribute :mtime
23
- it_has_attribute :nlink
24
- it_has_attribute :owner
25
- it_has_attribute :path
26
- it_has_attribute :size
27
-
28
- describe '#file?' do
29
-
30
- let(:opts) {{:ftype => ftype}}
31
-
32
- context '(file)' do
33
- let(:ftype) {'file'}
34
- its(:file?) {should be_truthy}
35
- end
36
-
37
- context '(directory)' do
38
- let(:ftype) {'directory'}
39
- its(:file?) {should be_falsey}
40
- end
41
-
42
- end
43
-
44
- describe '#directory?' do
45
-
46
- let(:opts) {{:ftype => ftype}}
47
-
48
- context '(file)' do
49
- let(:ftype) {'file'}
50
- its(:directory?) {should be_falsey}
51
- end
52
-
53
- context '(directory)' do
54
- let(:ftype) {'directory'}
55
- its(:directory?) {should be_truthy}
56
- end
57
-
58
- end
59
-
60
- end
61
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('spec_helper', File.dirname(__FILE__))
4
-
5
- module Ftpd
6
- describe FtpServerError do
7
-
8
- it "won't instantiate with an invalid error code" do
9
- expect { described_class.new("Nooooooooo", 665) }.to(
10
- raise_error(ArgumentError, "Invalid response code")
11
- )
12
- end
13
-
14
- end
15
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
4
-
5
- module Ftpd
6
- module ListFormat
7
- describe Eplf do
8
-
9
- context '(file)' do
10
-
11
- let(:file_info) do
12
- FileInfo.new(:ftype => 'file',
13
- :mode => 0100644,
14
- :mtime => Time.utc(2013, 3, 3, 8, 38, 0),
15
- :path => 'foo',
16
- :size => 1234)
17
- end
18
- subject(:formatter) {Eplf.new(file_info)}
19
-
20
- it 'should produce EPLF format' do
21
- expect(formatter.to_s).to eq "+r,s1234,m1362299880\tfoo"
22
- end
23
-
24
- end
25
-
26
- context '(directory)' do
27
-
28
- let(:file_info) do
29
- FileInfo.new(:ftype => 'directory',
30
- :mode => 0100644,
31
- :mtime => Time.utc(2013, 3, 3, 8, 38, 0),
32
- :path => 'foo',
33
- :size => 1024)
34
- end
35
- subject(:formatter) {Eplf.new(file_info)}
36
-
37
- it 'should produce EPLF format' do
38
- expect(formatter.to_s).to eq "+/,m1362299880\tfoo"
39
- end
40
-
41
- end
42
-
43
- context '(with identifier)' do
44
-
45
- let(:file_info) do
46
- FileInfo.new(:ftype => 'file',
47
- :mode => 0100644,
48
- :mtime => Time.utc(2013, 3, 3, 8, 38, 0),
49
- :path => 'foo',
50
- :identifier => '1234.5678',
51
- :size => 1234)
52
- end
53
- subject(:formatter) {Eplf.new(file_info)}
54
-
55
- it 'should produce EPLF format' do
56
- expect(formatter.to_s).to eq "+r,s1234,m1362299880,i1234.5678\tfoo"
57
- end
58
-
59
- end
60
-
61
- end
62
- end
63
- end