ftpd 0.0.0.pre1

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.

Files changed (62) hide show
  1. data/Gemfile +9 -0
  2. data/Gemfile.lock +43 -0
  3. data/LICENSE.md +9 -0
  4. data/README.md +57 -0
  5. data/Rakefile +8 -0
  6. data/VERSION +1 -0
  7. data/features/command_errors.feature +33 -0
  8. data/features/delete.feature +34 -0
  9. data/features/directory_navigation.feature +34 -0
  10. data/features/file_structure.feature +40 -0
  11. data/features/get.feature +62 -0
  12. data/features/list.feature +77 -0
  13. data/features/login.feature +54 -0
  14. data/features/mode.feature +40 -0
  15. data/features/name_list.feature +77 -0
  16. data/features/noop.feature +14 -0
  17. data/features/port.feature +25 -0
  18. data/features/put.feature +65 -0
  19. data/features/quit.feature +20 -0
  20. data/features/step_definitions/client_and_server_files.rb +24 -0
  21. data/features/step_definitions/client_files.rb +9 -0
  22. data/features/step_definitions/command.rb +5 -0
  23. data/features/step_definitions/connect.rb +15 -0
  24. data/features/step_definitions/delete.rb +15 -0
  25. data/features/step_definitions/directories.rb +22 -0
  26. data/features/step_definitions/error.rb +87 -0
  27. data/features/step_definitions/file_structure.rb +16 -0
  28. data/features/step_definitions/get.rb +16 -0
  29. data/features/step_definitions/invalid_commands.rb +11 -0
  30. data/features/step_definitions/line_endings.rb +7 -0
  31. data/features/step_definitions/list.rb +46 -0
  32. data/features/step_definitions/login.rb +69 -0
  33. data/features/step_definitions/mode.rb +15 -0
  34. data/features/step_definitions/noop.rb +13 -0
  35. data/features/step_definitions/passive.rb +3 -0
  36. data/features/step_definitions/port.rb +5 -0
  37. data/features/step_definitions/put.rb +16 -0
  38. data/features/step_definitions/quit.rb +15 -0
  39. data/features/step_definitions/server.rb +7 -0
  40. data/features/step_definitions/server_files.rb +18 -0
  41. data/features/step_definitions/type.rb +15 -0
  42. data/features/support/env.rb +4 -0
  43. data/features/support/file_templates/ascii_unix +4 -0
  44. data/features/support/file_templates/ascii_windows +4 -0
  45. data/features/support/file_templates/binary +0 -0
  46. data/features/support/test_client.rb +89 -0
  47. data/features/support/test_file_templates.rb +33 -0
  48. data/features/support/test_server.rb +52 -0
  49. data/features/syntax_errors.feature +15 -0
  50. data/features/type.feature +53 -0
  51. data/ftpd.gemspec +112 -0
  52. data/insecure-test-cert.pem +29 -0
  53. data/lib/ftpd.rb +6 -0
  54. data/lib/ftpd/FakeFtpServer.rb +736 -0
  55. data/lib/ftpd/FakeServer.rb +57 -0
  56. data/lib/ftpd/FakeTlsServer.rb +52 -0
  57. data/lib/ftpd/ObjectUtil.rb +66 -0
  58. data/lib/ftpd/TempDir.rb +54 -0
  59. data/lib/ftpd/q.rb +92 -0
  60. data/rake_tasks/cucumber.rake +7 -0
  61. data/rake_tasks/jeweler.rake +25 -0
  62. metadata +164 -0
@@ -0,0 +1,40 @@
1
+ Feature: Mode
2
+
3
+ As a client
4
+ I want to set the file transfer mode
5
+ So that can optimize the transfer
6
+
7
+ Scenario: Stream
8
+ Given a successful login
9
+ And the server has file "ascii_unix"
10
+ When the client successfully sets mode "S"
11
+ And the client successfully gets text "ascii_unix"
12
+ Then the remote file "ascii_unix" should match the local file
13
+
14
+ Scenario: Block
15
+ Given a successful login
16
+ And the server has file "ascii_unix"
17
+ When the client sets mode "B"
18
+ Then the server returns a mode not implemented error
19
+
20
+ Scenario: Compressed
21
+ Given a successful login
22
+ And the server has file "ascii_unix"
23
+ When the client sets mode "C"
24
+ Then the server returns a mode not implemented error
25
+
26
+ Scenario: Invalid
27
+ Given a successful login
28
+ And the server has file "ascii_unix"
29
+ When the client sets mode "*"
30
+ Then the server returns an invalid mode error
31
+
32
+ Scenario: Not logged in
33
+ Given a successful connection
34
+ When the client sets mode "S"
35
+ Then the server returns a not logged in error
36
+
37
+ Scenario: Missing parameter
38
+ Given a successful login
39
+ When the client sets mode with no parameter
40
+ Then the server returns a syntax error
@@ -0,0 +1,77 @@
1
+ Feature: Name List
2
+
3
+ As a client
4
+ I want to list file names
5
+ So that I can see what file to transfer
6
+
7
+ Scenario: List implicit
8
+ Given a successful login
9
+ And the server has file "foo"
10
+ And the server has file "bar"
11
+ When the client name lists the directory
12
+ Then the file list should be in short form
13
+ And the file list should contain "foo"
14
+ And the file list should contain "bar"
15
+
16
+ Scenario: List root
17
+ Given a successful login
18
+ And the server has file "foo"
19
+ And the server has file "bar"
20
+ When the client name lists the directory "/"
21
+ Then the file list should be in short form
22
+ And the file list should contain "foo"
23
+ And the file list should contain "bar"
24
+
25
+ Scenario: List subdir
26
+ Given a successful login
27
+ And the server has file "subdir/foo"
28
+ When the client name lists the directory "subdir"
29
+ Then the file list should be in short form
30
+ And the file list should contain "foo"
31
+
32
+ Scenario: List glob
33
+ Given a successful login
34
+ And the server has file "foo"
35
+ And the server has file "bar"
36
+ When the client name lists the directory "f*"
37
+ Then the file list should be in short form
38
+ And the file list should contain "foo"
39
+ And the file list should not contain "bar"
40
+
41
+ Scenario: Passive
42
+ Given a successful login
43
+ And the server has file "foo"
44
+ And the server has file "bar"
45
+ And the client is in passive mode
46
+ When the client name lists the directory
47
+ Then the file list should be in short form
48
+ And the file list should contain "foo"
49
+ And the file list should contain "bar"
50
+
51
+ Scenario: TLS
52
+ pending "TLS not supported in active mode (see README)"
53
+
54
+ Scenario: TLS, Passive
55
+ Given a successful login with TLS
56
+ And the server has file "foo"
57
+ And the server has file "bar"
58
+ And the client is in passive mode
59
+ When the client name lists the directory
60
+ Then the file list should be in short form
61
+ And the file list should contain "foo"
62
+ And the file list should contain "bar"
63
+
64
+ Scenario: Path outside tree
65
+ Given a successful login
66
+ When the client name lists the directory ".."
67
+ Then the server returns an access denied error
68
+
69
+ Scenario: Missing file
70
+ Given a successful login
71
+ When the client name lists the directory "missing/file"
72
+ Then the server returns a no such file error
73
+
74
+ Scenario: Not logged in
75
+ Given a successful connection
76
+ When the client name lists the directory
77
+ Then the server returns a not logged in error
@@ -0,0 +1,14 @@
1
+ Feature: No Operation
2
+
3
+ As a client
4
+ I want to keep the connection alive
5
+ So that I don't have to log in so often
6
+
7
+ Scenario: NOP
8
+ Given a successful connection
9
+ Then the client successfully does nothing
10
+
11
+ Scenario: With a parameter
12
+ Given a successful connection
13
+ When the client does nothing with a parameter
14
+ Then the server returns a syntax error
@@ -0,0 +1,25 @@
1
+ Feature: Port
2
+
3
+ As a programmer
4
+ I want good error messages
5
+ So that I can correct problems
6
+
7
+ Scenario: Not logged in
8
+ Given a successful connection
9
+ When the client sends PORT "1,2,3,4,5,6"
10
+ Then the server returns a not logged in error
11
+
12
+ Scenario: Incorrect number of bytes
13
+ Given a successful login
14
+ When the client sends PORT "1,2,3,4,5"
15
+ Then the server returns a syntax error
16
+
17
+ Scenario: Ill formatted byte
18
+ Given a successful login
19
+ When the client sends PORT "1,2,3,4,5,0006"
20
+ Then the server returns a syntax error
21
+
22
+ Scenario: Byte out of range
23
+ Given a successful login
24
+ When the client sends PORT "1,2,3,4,5,256"
25
+ Then the server returns a syntax error
@@ -0,0 +1,65 @@
1
+ Feature: Put
2
+
3
+ As a client
4
+ I want to put a file
5
+ So that someone else can have it
6
+
7
+ Scenario: ASCII file with *nix line endings
8
+ Given a successful login
9
+ And the client has file "ascii_unix"
10
+ When the client successfully puts text "ascii_unix"
11
+ Then the remote file "ascii_unix" should match the local file
12
+ And the remote file "ascii_unix" should have unix line endings
13
+
14
+ Scenario: ASCII file with windows line endings
15
+ Given a successful login
16
+ And the client has file "ascii_windows"
17
+ When the client successfully puts text "ascii_windows"
18
+ Then the remote file "ascii_windows" should match the local file
19
+ And the remote file "ascii_windows" should have unix line endings
20
+
21
+ Scenario: Binary file
22
+ Given a successful login
23
+ And the client has file "binary"
24
+ When the client successfully puts binary "binary"
25
+ Then the remote file "binary" should exactly match the local file
26
+
27
+ Scenario: Passive
28
+ Given a successful login
29
+ And the client has file "ascii_unix"
30
+ And the client is in passive mode
31
+ When the client successfully puts text "ascii_unix"
32
+ Then the remote file "ascii_unix" should match the local file
33
+
34
+ Scenario: TLS
35
+ pending "TLS not supported in active mode (see README)"
36
+
37
+ Scenario: TLS, Passive
38
+ Given a successful login with TLS
39
+ And the client has file "ascii_unix"
40
+ And the client is in passive mode
41
+ When the client successfully puts text "ascii_unix"
42
+ Then the remote file "ascii_unix" should match the local file
43
+
44
+ Scenario: Path outside tree
45
+ Given a successful login
46
+ And the client has file "foo"
47
+ When the client puts text "../foo"
48
+ Then the server returns an access denied error
49
+
50
+ Scenario: Missing directory
51
+ Given a successful login
52
+ And the client has file "bar"
53
+ When the client puts text "foo/bar"
54
+ Then the server returns a no such file error
55
+
56
+ Scenario: Not logged in
57
+ Given a successful connection
58
+ And the client has file "foo"
59
+ When the client puts text "foo"
60
+ Then the server returns a not logged in error
61
+
62
+ Scenario: Missing path
63
+ Given a successful login
64
+ When the client puts with no path
65
+ Then the server returns a syntax error
@@ -0,0 +1,20 @@
1
+ Feature: Quit
2
+
3
+ As a client
4
+ In order to free up resources
5
+ I want to close the connection
6
+
7
+ Scenario: Logged in
8
+ Given a successful login
9
+ When the client successfully quits
10
+ Then the client should not be logged in
11
+
12
+ Scenario: With a parameter
13
+ Given a successful connection
14
+ When the client quits with a parameter
15
+ Then the server returns a syntax error
16
+
17
+ Scenario: Not logged in
18
+ Given a successful connection
19
+ When the client quits
20
+ Then the server returns a not logged in error
@@ -0,0 +1,24 @@
1
+ def unix_line_endings(exactly, s)
2
+ return s if exactly
3
+ s.gsub(/\r\n/, "\n")
4
+ end
5
+
6
+ Then /^the remote file "(.*?)" should( exactly)? match the local file$/ do
7
+ |remote_path, exactly|
8
+ local_path = File.basename(remote_path)
9
+ remote_contents = @server.file_contents(remote_path)
10
+ local_contents = @client.file_contents(local_path)
11
+ remote_contents = unix_line_endings(exactly, remote_contents)
12
+ local_contents = unix_line_endings(exactly, local_contents)
13
+ remote_contents.should == local_contents
14
+ end
15
+
16
+ Then /^the local file "(.*?)" should( exactly)? match the remote file$/ do
17
+ |local_path, exactly|
18
+ remote_path = local_path
19
+ remote_contents = @server.file_contents(remote_path)
20
+ local_contents = @client.file_contents(local_path)
21
+ remote_contents = unix_line_endings(exactly, remote_contents)
22
+ local_contents = unix_line_endings(exactly, local_contents)
23
+ local_contents.should == remote_contents
24
+ end
@@ -0,0 +1,9 @@
1
+ Given /^the client has file "(.*?)"$/ do |local_path|
2
+ @client.add_file local_path
3
+ end
4
+
5
+ Then /^the local file "(.*?)" should have (unix|windows) line endings$/ do
6
+ |local_path, line_ending_type|
7
+ line_ending_type(@client.file_contents(local_path)).should ==
8
+ line_ending_type.to_sym
9
+ end
@@ -0,0 +1,5 @@
1
+ When /^the client sends command "(.*?)"$/ do |command|
2
+ capture_error do
3
+ @client.raw command
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require 'double_bag_ftps'
2
+ require 'net/ftp'
3
+
4
+ When /^the client connects( with TLS)?$/ do |with_tls|
5
+ @client = TestClient.new(:tls => with_tls)
6
+ @client.connect(@server.host, @server.port)
7
+ end
8
+
9
+ Then /^the connection is closed$/ do
10
+ @client.should be_closed
11
+ end
12
+
13
+ Then /^the connection is open$/ do
14
+ @client.should be_open
15
+ end
@@ -0,0 +1,15 @@
1
+ When /^the client deletes "(.*?)"$/ do |path|
2
+ capture_error do
3
+ step %Q(the client successfully deletes "#{path}")
4
+ end
5
+ end
6
+
7
+ When /^the client successfully deletes "(.*?)"$/ do |path|
8
+ @client.delete path
9
+ end
10
+
11
+ When /^the client deletes with no path$/ do
12
+ capture_error do
13
+ @client.raw 'DELE'
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ When /^the client cd's to "(.*?)"$/ do |path|
2
+ capture_error do
3
+ step %Q(the client successfully cd's to "#{path}")
4
+ end
5
+ end
6
+
7
+ # As of Ruby 1.9.3-p125, Net::FTP#chdir('..') will send a CDUP.
8
+ # However, that could conceivably change: The use of CDUP not
9
+ # required by the FTP protocol. Therefore we use this step to
10
+ # ensure that CDUP is sent and therefore tested.
11
+
12
+ When /^the client successfully cd's up$/ do
13
+ @client.raw 'CDUP'
14
+ end
15
+
16
+ When /^the client successfully cd's to "(.*?)"$/ do |path|
17
+ @client.chdir path
18
+ end
19
+
20
+ Then /^the current directory should be "(.*?)"$/ do |path|
21
+ @client.pwd.should == path
22
+ end
@@ -0,0 +1,87 @@
1
+ def capture_error
2
+ yield
3
+ @error = nil
4
+ rescue Net::FTPError => e
5
+ @error = e.message
6
+ end
7
+
8
+ Then /^the server returns no error$/ do
9
+ @error.should be_nil
10
+ end
11
+
12
+ Then /^the server returns a "(.*?)" error$/ do |error_message|
13
+ @error.should include error_message
14
+ end
15
+
16
+ Then /^the server returns a no such file error$/ do
17
+ step 'the server returns a "550 No such file or directory" error'
18
+ end
19
+
20
+ Then /^the server returns a login incorrect error$/ do
21
+ step 'the server returns a "530 Login incorrect" error'
22
+
23
+ end
24
+
25
+ Then /^the server returns a not logged in error$/ do
26
+ step 'the server returns a "530 Not logged in" error'
27
+ end
28
+
29
+ Then /^the server returns an access denied error$/ do
30
+ step 'the server returns a "550 Access denied" error'
31
+ end
32
+
33
+ Then /^the server returns a path required error$/ do
34
+ step 'the server returns a "501 Path required" error'
35
+ end
36
+
37
+ Then /^the server returns a not found error$/ do
38
+ step 'the server returns a "450 No such file or directory" error'
39
+ end
40
+
41
+ Then /^the server returns a syntax error$/ do
42
+ step 'the server returns a "501 Syntax error" error'
43
+ end
44
+
45
+ Then /^the server returns a mode not implemented error$/ do
46
+ step 'the server returns a "504 Mode not implemented" error'
47
+ end
48
+
49
+ Then /^the server returns an invalid mode error$/ do
50
+ step 'the server returns a "504 Invalid mode code" error'
51
+ end
52
+
53
+ Then /^the server returns a file structure not implemented error$/ do
54
+ step 'the server returns a "504 Structure not implemented" error'
55
+ end
56
+
57
+ Then /^the server returns an invalid file structure error$/ do
58
+ step 'the server returns a "504 Invalid structure code" error'
59
+ end
60
+
61
+ Then /^the server returns a bad sequence error$/ do
62
+ step 'the server returns a "503 Bad sequence of commands" error'
63
+ end
64
+
65
+ Then /^the server returns a type not implemented error$/ do
66
+ step 'the server returns a "504 Type not implemented" error'
67
+ end
68
+
69
+ Then /^the server returns an invalid type error$/ do
70
+ step 'the server returns a "504 Invalid type code" error'
71
+ end
72
+
73
+ Then /^the server returns a format not implemented error$/ do
74
+ step 'the server returns a "504 Format not implemented" error'
75
+ end
76
+
77
+ Then /^the server returns an invalid format error$/ do
78
+ step 'the server returns a "504 Invalid format code" error'
79
+ end
80
+
81
+ Then /^the server returns a command unrecognized error$/ do
82
+ step 'the server returns a "500 Syntax error, command unrecognized" error'
83
+ end
84
+
85
+ Then /^the server returns an unimplemented command error$/ do
86
+ step 'the server returns a "502 Command not implemented" error'
87
+ end
@@ -0,0 +1,16 @@
1
+ When /^the client successfully sets file structure "(.*?)"$/ do
2
+ |file_structure|
3
+ @client.raw 'STRU', file_structure
4
+ end
5
+
6
+ When /^the client sets file structure "(.*?)"$/ do |file_structure|
7
+ capture_error do
8
+ step %Q'the client successfully sets file structure "#{file_structure}"'
9
+ end
10
+ end
11
+
12
+ When /^the client sets file structure with no parameter$/ do
13
+ capture_error do
14
+ @client.raw 'STRU'
15
+ end
16
+ end