ftpd 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ftpd might be problematic. Click here for more details.

@@ -24,7 +24,7 @@ module Ftpd
24
24
  end
25
25
 
26
26
  def run
27
- reply "220 FakeFtpServer"
27
+ reply "220 ftpd"
28
28
  @state = :user
29
29
  catch :done do
30
30
  loop do
@@ -37,7 +37,7 @@ module Ftpd
37
37
  end
38
38
  method = 'cmd_' + command
39
39
  unless self.class.private_method_defined?(method)
40
- error "502 Command not implemented: #{command}"
40
+ unimplemented
41
41
  end
42
42
  send(method, argument)
43
43
  rescue CommandError => e
@@ -89,6 +89,17 @@ module Ftpd
89
89
  "user",
90
90
  ]
91
91
 
92
+ def cmd_allo(argument)
93
+ ensure_logged_in
94
+ syntax_error unless argument =~ /^\d+( R \d+)?$/
95
+ command_not_needed
96
+ end
97
+
98
+ def cmd_syst(argument)
99
+ syntax_error if argument
100
+ reply "215 UNIX Type: L8"
101
+ end
102
+
92
103
  def cmd_user(argument)
93
104
  syntax_error unless argument
94
105
  bad_sequence unless @state == :user
@@ -101,6 +112,10 @@ module Ftpd
101
112
  error "503 Bad sequence of commands"
102
113
  end
103
114
 
115
+ def unimplemented
116
+ error "502 Command not implemented"
117
+ end
118
+
104
119
  def cmd_pass(argument)
105
120
  syntax_error unless argument
106
121
  bad_sequence unless @state == :password
@@ -143,6 +158,7 @@ module Ftpd
143
158
  def cmd_stor(argument)
144
159
  close_data_server_socket_when_done do
145
160
  ensure_logged_in
161
+ ensure_write_supported
146
162
  path = argument
147
163
  syntax_error unless path
148
164
  path = File.expand_path(path, @name_prefix)
@@ -157,6 +173,7 @@ module Ftpd
157
173
  def cmd_retr(argument)
158
174
  close_data_server_socket_when_done do
159
175
  ensure_logged_in
176
+ ensure_read_supported
160
177
  path = argument
161
178
  syntax_error unless path
162
179
  path = File.expand_path(path, @name_prefix)
@@ -169,6 +186,7 @@ module Ftpd
169
186
 
170
187
  def cmd_dele(argument)
171
188
  ensure_logged_in
189
+ ensure_delete_supported
172
190
  path = argument
173
191
  error "501 Path required" unless path
174
192
  path = File.expand_path(path, @name_prefix)
@@ -179,38 +197,29 @@ module Ftpd
179
197
  end
180
198
 
181
199
  def cmd_list(argument)
182
- ls(argument, :list_long)
183
- end
184
-
185
- def cmd_nlst(argument)
186
- ls(argument, :list_short)
187
- end
188
-
189
- def ls(path, file_system_method)
190
200
  close_data_server_socket_when_done do
191
201
  ensure_logged_in
202
+ ensure_list_supported
203
+ path = argument
192
204
  path ||= '.'
193
205
  path = File.expand_path(path, @name_prefix)
194
- list = @file_system.send(file_system_method, path)
206
+ list = @file_system.list(path)
195
207
  transmit_file(list, 'A')
196
208
  end
197
209
  end
198
210
 
199
- def realpath(pathname)
200
- handle_system_error do
201
- basename = File.basename(pathname.to_s)
202
- if is_glob?(basename)
203
- pathname.dirname.realpath + basename
204
- else
205
- pathname.realpath
206
- end
211
+ def cmd_nlst(argument)
212
+ close_data_server_socket_when_done do
213
+ ensure_logged_in
214
+ ensure_name_list_supported
215
+ path = argument
216
+ path ||= '.'
217
+ path = File.expand_path(path, @name_prefix)
218
+ list = @file_system.name_list(path)
219
+ transmit_file(list, 'A')
207
220
  end
208
221
  end
209
222
 
210
- def is_glob?(filename)
211
- filename =~ /[.*]/
212
- end
213
-
214
223
  def cmd_type(argument)
215
224
  ensure_logged_in
216
225
  syntax_error unless argument =~ /^(\S)(?: (\S+))?$/
@@ -317,6 +326,36 @@ module Ftpd
317
326
  end
318
327
  end
319
328
 
329
+ def ensure_write_supported
330
+ unless @file_system.respond_to?(:write)
331
+ unimplemented
332
+ end
333
+ end
334
+
335
+ def ensure_read_supported
336
+ unless @file_system.respond_to?(:read)
337
+ unimplemented
338
+ end
339
+ end
340
+
341
+ def ensure_delete_supported
342
+ unless @file_system.respond_to?(:delete)
343
+ unimplemented
344
+ end
345
+ end
346
+
347
+ def ensure_list_supported
348
+ unless @file_system.respond_to?(:list)
349
+ unimplemented
350
+ end
351
+ end
352
+
353
+ def ensure_name_list_supported
354
+ unless @file_system.respond_to?(:name_list)
355
+ unimplemented
356
+ end
357
+ end
358
+
320
359
  def tls_enabled?
321
360
  @tls != :off
322
361
  end
@@ -413,18 +452,6 @@ module Ftpd
413
452
  @file_system = FileSystemErrorTranslator.new(file_system)
414
453
  end
415
454
 
416
- def child_path_of?(parent, child)
417
- child.cleanpath.to_s.index(parent.cleanpath.to_s) == 0
418
- end
419
-
420
- def handle_system_error
421
- begin
422
- yield
423
- rescue SystemCallError => e
424
- error "550 #{e}"
425
- end
426
- end
427
-
428
455
  def transmit_file(contents, data_type = @data_type)
429
456
  open_data_connection do |data_socket|
430
457
  contents = unix_to_nvt_ascii(contents) if data_type == 'A'
@@ -477,6 +504,10 @@ module Ftpd
477
504
  ].compact.join(' ')
478
505
  end
479
506
 
507
+ def command_not_needed
508
+ reply '202 Command not needed at this site'
509
+ end
510
+
480
511
  def encrypt_data?
481
512
  @data_channel_protection_level != :clear
482
513
  end
@@ -155,10 +155,10 @@ module Ftpd
155
155
 
156
156
  end
157
157
 
158
- describe '#list_short' do
158
+ describe '#name_list' do
159
159
 
160
160
  subject do
161
- disk_file_system.list_short(path)
161
+ disk_file_system.name_list(path)
162
162
  end
163
163
 
164
164
  shared_examples 'returns short list of root' do
@@ -195,10 +195,10 @@ module Ftpd
195
195
 
196
196
  end
197
197
 
198
- describe '#list_long' do
198
+ describe '#list' do
199
199
 
200
200
  subject do
201
- disk_file_system.list_long(path)
201
+ disk_file_system.list(path)
202
202
  end
203
203
 
204
204
  shared_examples 'returns long list of root' do
@@ -0,0 +1,43 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Ftpd
4
+ describe FileSystemErrorTranslator do
5
+
6
+ class MockFileSystem
7
+
8
+ def with_error
9
+ raise FileSystemError, 'An error occurred'
10
+ end
11
+
12
+ def without_error
13
+ 123
14
+ end
15
+
16
+ end
17
+
18
+ subject(:translator) do
19
+ FileSystemErrorTranslator.new(MockFileSystem.new)
20
+ end
21
+
22
+ context 'missing method' do
23
+ specify do
24
+ expect {
25
+ translator.no_such_method
26
+ }.to raise_error NoMethodError, /no_such_method/
27
+ end
28
+ end
29
+
30
+ context 'no exception' do
31
+ its(:without_error) {should == 123}
32
+ end
33
+
34
+ context 'exception' do
35
+ specify do
36
+ expect {
37
+ translator.with_error
38
+ }.to raise_error CommandError, '450 An error occurred'
39
+ end
40
+ end
41
+
42
+ end
43
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ftpd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-23 00:00:00.000000000 Z
12
+ date: 2013-02-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: memoizer
@@ -124,7 +124,7 @@ dependencies:
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  description: ftpd is a pure Ruby FTP server library. It supports implicit and explicit
127
- TLS, and is suitable for use by a program such as a test fixture or small FTP daemon.
127
+ TLS, and can be used as part of a test fixture or to embed in another program.
128
128
  email: wconrad@yagni.com
129
129
  executables: []
130
130
  extensions: []
@@ -132,6 +132,7 @@ extra_rdoc_files:
132
132
  - LICENSE.md
133
133
  - README.md
134
134
  files:
135
+ - Changelog.md
135
136
  - Gemfile
136
137
  - Gemfile.lock
137
138
  - LICENSE.md
@@ -142,6 +143,7 @@ files:
142
143
  - examples/hello_world.rb
143
144
  - features/example/example.feature
144
145
  - features/example/step_definitions/example_server.rb
146
+ - features/ftp_server/allo.feature
145
147
  - features/ftp_server/command_errors.feature
146
148
  - features/ftp_server/concurrent_sessions.feature
147
149
  - features/ftp_server/debug.feature
@@ -164,6 +166,7 @@ files:
164
166
  - features/ftp_server/step_definitions/debug.rb
165
167
  - features/ftp_server/step_definitions/test_server.rb
166
168
  - features/ftp_server/syntax_errors.feature
169
+ - features/ftp_server/syst.feature
167
170
  - features/ftp_server/type.feature
168
171
  - features/step_definitions/client.rb
169
172
  - features/step_definitions/client_and_server_files.rb
@@ -172,8 +175,9 @@ files:
172
175
  - features/step_definitions/connect.rb
173
176
  - features/step_definitions/delete.rb
174
177
  - features/step_definitions/directories.rb
175
- - features/step_definitions/error.rb
178
+ - features/step_definitions/error_replies.rb
176
179
  - features/step_definitions/file_structure.rb
180
+ - features/step_definitions/generic_send.rb
177
181
  - features/step_definitions/get.rb
178
182
  - features/step_definitions/invalid_commands.rb
179
183
  - features/step_definitions/line_endings.rb
@@ -187,6 +191,8 @@ files:
187
191
  - features/step_definitions/quit.rb
188
192
  - features/step_definitions/server_files.rb
189
193
  - features/step_definitions/stop_server.rb
194
+ - features/step_definitions/success_replies.rb
195
+ - features/step_definitions/system.rb
190
196
  - features/step_definitions/type.rb
191
197
  - features/support/env.rb
192
198
  - features/support/example_server.rb
@@ -221,6 +227,7 @@ files:
221
227
  - sandbox/em-server.rb
222
228
  - spec/disk_file_system_spec.rb
223
229
  - spec/exception_translator_spec.rb
230
+ - spec/file_system_error_translator_spec.rb
224
231
  - spec/spec_helper.rb
225
232
  - spec/translate_exceptions_spec.rb
226
233
  homepage: http://github.com/wconrad/ftpd
@@ -238,7 +245,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
245
  version: '0'
239
246
  segments:
240
247
  - 0
241
- hash: 564915969
248
+ hash: 198418525
242
249
  required_rubygems_version: !ruby/object:Gem::Requirement
243
250
  none: false
244
251
  requirements: