investtools-ftpd 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +5 -0
  3. data/.yardopts +7 -0
  4. data/Changelog.md +310 -0
  5. data/Gemfile +15 -0
  6. data/Gemfile.lock +93 -0
  7. data/LICENSE.md +9 -0
  8. data/README.md +371 -0
  9. data/Rakefile +14 -0
  10. data/VERSION +1 -0
  11. data/doc/benchmarks.md +82 -0
  12. data/doc/references.md +66 -0
  13. data/doc/rfc-compliance.md +292 -0
  14. data/examples/example.rb +275 -0
  15. data/examples/example_spec.rb +93 -0
  16. data/examples/hello_world.rb +32 -0
  17. data/features/example/eplf.feature +14 -0
  18. data/features/example/example.feature +18 -0
  19. data/features/example/read_only.feature +63 -0
  20. data/features/example/step_definitions/example_server.rb +11 -0
  21. data/features/ftp_server/abort.feature +13 -0
  22. data/features/ftp_server/allo.feature +33 -0
  23. data/features/ftp_server/append.feature +94 -0
  24. data/features/ftp_server/cdup.feature +36 -0
  25. data/features/ftp_server/command_errors.feature +13 -0
  26. data/features/ftp_server/concurrent_sessions.feature +14 -0
  27. data/features/ftp_server/delay_after_failed_login.feature +23 -0
  28. data/features/ftp_server/delete.feature +60 -0
  29. data/features/ftp_server/directory_navigation.feature +59 -0
  30. data/features/ftp_server/disconnect_after_failed_logins.feature +25 -0
  31. data/features/ftp_server/eprt.feature +55 -0
  32. data/features/ftp_server/epsv.feature +36 -0
  33. data/features/ftp_server/features.feature +38 -0
  34. data/features/ftp_server/file_structure.feature +43 -0
  35. data/features/ftp_server/get.feature +80 -0
  36. data/features/ftp_server/get_ipv6.feature +43 -0
  37. data/features/ftp_server/get_tls.feature +23 -0
  38. data/features/ftp_server/help.feature +21 -0
  39. data/features/ftp_server/implicit_tls.feature +23 -0
  40. data/features/ftp_server/invertability.feature +15 -0
  41. data/features/ftp_server/list.feature +94 -0
  42. data/features/ftp_server/list_tls.feature +29 -0
  43. data/features/ftp_server/logging.feature +11 -0
  44. data/features/ftp_server/login_auth_level_account.feature +51 -0
  45. data/features/ftp_server/login_auth_level_password.feature +59 -0
  46. data/features/ftp_server/login_auth_level_user.feature +31 -0
  47. data/features/ftp_server/max_connections.feature +39 -0
  48. data/features/ftp_server/mdtm.feature +53 -0
  49. data/features/ftp_server/mkdir.feature +70 -0
  50. data/features/ftp_server/mode.feature +43 -0
  51. data/features/ftp_server/name_list.feature +77 -0
  52. data/features/ftp_server/name_list_tls.feature +30 -0
  53. data/features/ftp_server/noop.feature +17 -0
  54. data/features/ftp_server/options.feature +17 -0
  55. data/features/ftp_server/pasv.feature +23 -0
  56. data/features/ftp_server/port.feature +49 -0
  57. data/features/ftp_server/put.feature +79 -0
  58. data/features/ftp_server/put_tls.feature +23 -0
  59. data/features/ftp_server/put_unique.feature +56 -0
  60. data/features/ftp_server/quit.feature +23 -0
  61. data/features/ftp_server/reinitialize.feature +13 -0
  62. data/features/ftp_server/rename.feature +97 -0
  63. data/features/ftp_server/rmdir.feature +71 -0
  64. data/features/ftp_server/site.feature +13 -0
  65. data/features/ftp_server/size.feature +69 -0
  66. data/features/ftp_server/status.feature +18 -0
  67. data/features/ftp_server/step_definitions/logging.rb +8 -0
  68. data/features/ftp_server/step_definitions/test_server.rb +65 -0
  69. data/features/ftp_server/structure_mount.feature +13 -0
  70. data/features/ftp_server/syntax_errors.feature +18 -0
  71. data/features/ftp_server/syst.feature +18 -0
  72. data/features/ftp_server/timeout.feature +26 -0
  73. data/features/ftp_server/type.feature +59 -0
  74. data/features/step_definitions/append.rb +15 -0
  75. data/features/step_definitions/client.rb +24 -0
  76. data/features/step_definitions/client_and_server_files.rb +24 -0
  77. data/features/step_definitions/client_files.rb +14 -0
  78. data/features/step_definitions/command.rb +5 -0
  79. data/features/step_definitions/connect.rb +37 -0
  80. data/features/step_definitions/delete.rb +15 -0
  81. data/features/step_definitions/directory_navigation.rb +26 -0
  82. data/features/step_definitions/error_replies.rb +115 -0
  83. data/features/step_definitions/features.rb +21 -0
  84. data/features/step_definitions/file_structure.rb +16 -0
  85. data/features/step_definitions/generic_send.rb +9 -0
  86. data/features/step_definitions/get.rb +16 -0
  87. data/features/step_definitions/help.rb +18 -0
  88. data/features/step_definitions/invalid_commands.rb +11 -0
  89. data/features/step_definitions/line_endings.rb +7 -0
  90. data/features/step_definitions/list.rb +73 -0
  91. data/features/step_definitions/login.rb +82 -0
  92. data/features/step_definitions/mkdir.rb +9 -0
  93. data/features/step_definitions/mode.rb +15 -0
  94. data/features/step_definitions/mtime.rb +23 -0
  95. data/features/step_definitions/noop.rb +15 -0
  96. data/features/step_definitions/options.rb +9 -0
  97. data/features/step_definitions/passive.rb +3 -0
  98. data/features/step_definitions/pending.rb +3 -0
  99. data/features/step_definitions/port.rb +5 -0
  100. data/features/step_definitions/put.rb +29 -0
  101. data/features/step_definitions/quit.rb +15 -0
  102. data/features/step_definitions/rename.rb +11 -0
  103. data/features/step_definitions/rmdir.rb +9 -0
  104. data/features/step_definitions/server_files.rb +61 -0
  105. data/features/step_definitions/server_title.rb +12 -0
  106. data/features/step_definitions/size.rb +20 -0
  107. data/features/step_definitions/status.rb +9 -0
  108. data/features/step_definitions/success_replies.rb +7 -0
  109. data/features/step_definitions/system.rb +7 -0
  110. data/features/step_definitions/timing.rb +19 -0
  111. data/features/step_definitions/type.rb +15 -0
  112. data/features/support/env.rb +4 -0
  113. data/features/support/example_server.rb +67 -0
  114. data/features/support/file_templates/ascii_unix +4 -0
  115. data/features/support/file_templates/ascii_windows +4 -0
  116. data/features/support/file_templates/binary +0 -0
  117. data/features/support/test_client.rb +250 -0
  118. data/features/support/test_file_templates.rb +33 -0
  119. data/features/support/test_server.rb +293 -0
  120. data/features/support/test_server_files.rb +57 -0
  121. data/ftpd.gemspec +283 -0
  122. data/insecure-test-cert.pem +29 -0
  123. data/investtools-ftpd.gemspec +284 -0
  124. data/lib/ftpd.rb +86 -0
  125. data/lib/ftpd/auth_levels.rb +9 -0
  126. data/lib/ftpd/cmd_abor.rb +13 -0
  127. data/lib/ftpd/cmd_allo.rb +20 -0
  128. data/lib/ftpd/cmd_appe.rb +24 -0
  129. data/lib/ftpd/cmd_auth.rb +21 -0
  130. data/lib/ftpd/cmd_cdup.rb +16 -0
  131. data/lib/ftpd/cmd_cwd.rb +20 -0
  132. data/lib/ftpd/cmd_dele.rb +21 -0
  133. data/lib/ftpd/cmd_eprt.rb +23 -0
  134. data/lib/ftpd/cmd_epsv.rb +30 -0
  135. data/lib/ftpd/cmd_feat.rb +44 -0
  136. data/lib/ftpd/cmd_help.rb +29 -0
  137. data/lib/ftpd/cmd_list.rb +33 -0
  138. data/lib/ftpd/cmd_login.rb +60 -0
  139. data/lib/ftpd/cmd_mdtm.rb +27 -0
  140. data/lib/ftpd/cmd_mkd.rb +23 -0
  141. data/lib/ftpd/cmd_mode.rb +27 -0
  142. data/lib/ftpd/cmd_nlst.rb +27 -0
  143. data/lib/ftpd/cmd_noop.rb +14 -0
  144. data/lib/ftpd/cmd_opts.rb +14 -0
  145. data/lib/ftpd/cmd_pasv.rb +28 -0
  146. data/lib/ftpd/cmd_pbsz.rb +23 -0
  147. data/lib/ftpd/cmd_port.rb +28 -0
  148. data/lib/ftpd/cmd_prot.rb +34 -0
  149. data/lib/ftpd/cmd_pwd.rb +15 -0
  150. data/lib/ftpd/cmd_quit.rb +18 -0
  151. data/lib/ftpd/cmd_rein.rb +13 -0
  152. data/lib/ftpd/cmd_rename.rb +32 -0
  153. data/lib/ftpd/cmd_rest.rb +13 -0
  154. data/lib/ftpd/cmd_retr.rb +24 -0
  155. data/lib/ftpd/cmd_rmd.rb +22 -0
  156. data/lib/ftpd/cmd_site.rb +13 -0
  157. data/lib/ftpd/cmd_size.rb +29 -0
  158. data/lib/ftpd/cmd_smnt.rb +13 -0
  159. data/lib/ftpd/cmd_stat.rb +15 -0
  160. data/lib/ftpd/cmd_stor.rb +25 -0
  161. data/lib/ftpd/cmd_stou.rb +25 -0
  162. data/lib/ftpd/cmd_stru.rb +27 -0
  163. data/lib/ftpd/cmd_syst.rb +16 -0
  164. data/lib/ftpd/cmd_type.rb +28 -0
  165. data/lib/ftpd/command_handler.rb +90 -0
  166. data/lib/ftpd/command_handler_factory.rb +51 -0
  167. data/lib/ftpd/command_handlers.rb +60 -0
  168. data/lib/ftpd/command_loop.rb +80 -0
  169. data/lib/ftpd/command_sequence_checker.rb +58 -0
  170. data/lib/ftpd/config.rb +13 -0
  171. data/lib/ftpd/connection_throttle.rb +56 -0
  172. data/lib/ftpd/connection_tracker.rb +82 -0
  173. data/lib/ftpd/data_connection_helper.rb +123 -0
  174. data/lib/ftpd/disk_file_system.rb +434 -0
  175. data/lib/ftpd/error.rb +21 -0
  176. data/lib/ftpd/exception_translator.rb +32 -0
  177. data/lib/ftpd/exceptions.rb +62 -0
  178. data/lib/ftpd/file_info.rb +115 -0
  179. data/lib/ftpd/file_system_helper.rb +67 -0
  180. data/lib/ftpd/ftp_server.rb +214 -0
  181. data/lib/ftpd/gets_peer_address.rb +41 -0
  182. data/lib/ftpd/insecure_certificate.rb +16 -0
  183. data/lib/ftpd/list_format/eplf.rb +74 -0
  184. data/lib/ftpd/list_format/ls.rb +154 -0
  185. data/lib/ftpd/list_path.rb +28 -0
  186. data/lib/ftpd/null_logger.rb +22 -0
  187. data/lib/ftpd/protocols.rb +60 -0
  188. data/lib/ftpd/read_only_disk_file_system.rb +22 -0
  189. data/lib/ftpd/server.rb +139 -0
  190. data/lib/ftpd/session.rb +220 -0
  191. data/lib/ftpd/session_config.rb +111 -0
  192. data/lib/ftpd/stream.rb +80 -0
  193. data/lib/ftpd/telnet.rb +114 -0
  194. data/lib/ftpd/temp_dir.rb +22 -0
  195. data/lib/ftpd/tls_server.rb +111 -0
  196. data/lib/ftpd/translate_exceptions.rb +68 -0
  197. data/rake_tasks/cucumber.rake +9 -0
  198. data/rake_tasks/default.rake +1 -0
  199. data/rake_tasks/jeweler.rake +52 -0
  200. data/rake_tasks/spec.rake +3 -0
  201. data/rake_tasks/test.rake +2 -0
  202. data/rake_tasks/yard.rake +3 -0
  203. data/spec/command_sequence_checker_spec.rb +83 -0
  204. data/spec/connection_throttle_spec.rb +99 -0
  205. data/spec/connection_tracker_spec.rb +97 -0
  206. data/spec/disk_file_system_spec.rb +320 -0
  207. data/spec/exception_translator_spec.rb +36 -0
  208. data/spec/file_info_spec.rb +59 -0
  209. data/spec/ftp_server_error_spec.rb +13 -0
  210. data/spec/list_format/eplf_spec.rb +61 -0
  211. data/spec/list_format/ls_spec.rb +270 -0
  212. data/spec/list_path_spec.rb +21 -0
  213. data/spec/null_logger_spec.rb +24 -0
  214. data/spec/protocols_spec.rb +139 -0
  215. data/spec/server_spec.rb +81 -0
  216. data/spec/spec_helper.rb +15 -0
  217. data/spec/telnet_spec.rb +75 -0
  218. data/spec/translate_exceptions_spec.rb +40 -0
  219. metadata +404 -0
@@ -0,0 +1,59 @@
1
+ Feature: Representation Type
2
+
3
+ As a client
4
+ I want to set the representation type
5
+ So that I can interoperate with foreign operating systems
6
+
7
+ Background:
8
+ Given the test server is started
9
+
10
+ Scenario: ASCII/default
11
+ Given a successful login
12
+ Then the client successfully sets type "A"
13
+
14
+ Scenario: ASCII/Non-print
15
+ Given a successful login
16
+ Then the client successfully sets type "A N"
17
+
18
+ Scenario: ASCII/Telnet
19
+ Given a successful login
20
+ When the client successfully sets type "A T"
21
+
22
+ Scenario: Type IMAGE
23
+ Given a successful login
24
+ Then the client successfully sets type "I"
25
+
26
+ Scenario: Type EBCDIC
27
+ Given a successful login
28
+ When the client sets type "E"
29
+ Then the server returns a type not implemented error
30
+
31
+ Scenario: Type Local
32
+ Given a successful login
33
+ When the client sets type "L 7"
34
+ Then the server returns a type not implemented error
35
+
36
+ Scenario: Invalid Type
37
+ Given a successful login
38
+ When the client sets type "*"
39
+ Then the server returns an invalid type error
40
+
41
+ Scenario: Format Carriage Control
42
+ Given a successful login
43
+ When the client sets type "A C"
44
+ Then the server returns a type not implemented error
45
+
46
+ Scenario: Invalid Format
47
+ Given a successful login
48
+ When the client sets type "A *"
49
+ Then the server returns an invalid type error
50
+
51
+ Scenario: Not logged in
52
+ Given a successful connection
53
+ When the client sets type "S"
54
+ Then the server returns a not logged in error
55
+
56
+ Scenario: Missing parameter
57
+ Given a successful login
58
+ When the client sets type with no parameter
59
+ Then the server returns a syntax error
@@ -0,0 +1,15 @@
1
+ When /^the client appends (.*)$/ do |args|
2
+ capture_error do
3
+ step "the client successfully appends #{args}"
4
+ end
5
+ end
6
+
7
+ When /^the client successfully appends text "(.*?)" onto "(.*?)"$/ do
8
+ |local_path, remote_path|
9
+ client.append_text local_path, remote_path
10
+ end
11
+
12
+ When /^the client successfully appends binary "(.*?)" onto "(.*?)"$/ do
13
+ |local_path, remote_path|
14
+ client.append_binary local_path, remote_path
15
+ end
@@ -0,0 +1,24 @@
1
+ require 'singleton'
2
+
3
+ class Clients
4
+
5
+ include Singleton
6
+
7
+ def initialize
8
+ @clients = {}
9
+ end
10
+
11
+ def [](client_name)
12
+ @clients[client_name] ||= TestClient.new
13
+ end
14
+
15
+ def close
16
+ @clients.values.each(&:close)
17
+ end
18
+
19
+ end
20
+
21
+ def client(client_name = nil)
22
+ client_name ||= 'client'
23
+ Clients.instance[client_name]
24
+ end
@@ -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
+ expect(remote_contents).to eq 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
+ expect(local_contents).to eq remote_contents
24
+ end
@@ -0,0 +1,14 @@
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
+ expect(line_ending_type(client.file_contents(local_path))).to eq \
8
+ line_ending_type.to_sym
9
+ end
10
+
11
+ Then /^the local file "(.*?)" should match its template$/ do |local_path|
12
+ expect(client.template(local_path)).to eq \
13
+ client.file_contents(local_path)
14
+ 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,37 @@
1
+ require 'double_bag_ftps'
2
+ require 'net/ftp'
3
+
4
+ When /^the( \w+)? client connects(?: with (\w+) TLS)?$/ do
5
+ |client_name, tls_mode|
6
+ tls_mode ||= 'off'
7
+ client(client_name).tls_mode = tls_mode.to_sym
8
+ client(client_name).start
9
+ client(client_name).connect(server.host, server.port)
10
+ end
11
+
12
+ When /^the (\d+)rd client tries to connect$/ do |client_name|
13
+ client(client_name).start
14
+ capture_error do
15
+ client(client_name).connect(server.host, server.port)
16
+ end
17
+ end
18
+
19
+ When /^the (\S+) client connects from (\S+)$/ do
20
+ |client_name, source_ip|
21
+ client(client_name).connect_from(source_ip, server.host, server.port)
22
+ end
23
+
24
+ When /^the (\S+) client tries to connect from (\S+)$/ do
25
+ |client_name, source_ip|
26
+ capture_error do
27
+ step "the #{client_name} client connects from #{source_ip}"
28
+ end
29
+ end
30
+
31
+ Then /^the client should be connected$/ do
32
+ expect(client).to be_connected
33
+ end
34
+
35
+ Then /^the client should not be connected$/ do
36
+ expect(client).to_not be_connected
37
+ 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,26 @@
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
+ expect(client.pwd).to eq path
22
+ end
23
+
24
+ Then /^the XPWD directory should be "(.*?)"$/ do |path|
25
+ expect(client.xpwd).to eq path
26
+ end
@@ -0,0 +1,115 @@
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
+ expect(@error).to be_nil
10
+ end
11
+
12
+ Then /^the server returns a "(.*?)" error$/ do |error_message|
13
+ expect(@error || '').to include error_message
14
+ end
15
+
16
+ Then /^the server returns a too many connections error$/ do
17
+ step 'the server returns a "421 Too many connections" error'
18
+ end
19
+
20
+ Then /^the server returns a server unavailable error$/ do
21
+ step 'the server returns a "421 server unavailable" error'
22
+ end
23
+
24
+ Then /^the server returns a not a directory error$/ do
25
+ step 'the server returns a "550 Not a directory" error'
26
+ end
27
+
28
+ Then /^the server returns a login incorrect error$/ do
29
+ step 'the server returns a "530 Login incorrect" error'
30
+ end
31
+
32
+ Then /^the server returns a not logged in error$/ do
33
+ step 'the server returns a "530 Not logged in" error'
34
+ end
35
+
36
+ Then /^the server returns an access denied error$/ do
37
+ step 'the server returns a "550 Access denied" error'
38
+ end
39
+
40
+ Then /^the server returns a path required error$/ do
41
+ step 'the server returns a "501 Path required" error'
42
+ end
43
+
44
+ Then /^the server returns a not found error$/ do
45
+ step 'the server returns a "550 No such file or directory" error'
46
+ end
47
+
48
+ Then /^the server returns a syntax error$/ do
49
+ step 'the server returns a "501 Syntax error" error'
50
+ end
51
+
52
+ Then /^the server returns a bad option error$/ do
53
+ step 'the server returns a "501 Unsupported option" error'
54
+ end
55
+
56
+ Then /^the server returns a mode not implemented error$/ do
57
+ step 'the server returns a "504 Mode not implemented" error'
58
+ end
59
+
60
+ Then /^the server returns an invalid mode error$/ do
61
+ step 'the server returns a "504 Invalid mode code" error'
62
+ end
63
+
64
+ Then /^the server returns a file structure not implemented error$/ do
65
+ step 'the server returns a "504 Structure not implemented" error'
66
+ end
67
+
68
+ Then /^the server returns an invalid file structure error$/ do
69
+ step 'the server returns a "504 Invalid structure code" error'
70
+ end
71
+
72
+ Then /^the server returns a bad sequence error$/ do
73
+ step 'the server returns a "503 Bad sequence of commands" error'
74
+ end
75
+
76
+ Then /^the server returns a type not implemented error$/ do
77
+ step 'the server returns a "504 Type not implemented" error'
78
+ end
79
+
80
+ Then /^the server returns an invalid type error$/ do
81
+ step 'the server returns a "504 Invalid type code" error'
82
+ end
83
+
84
+ Then /^the server returns a format not implemented error$/ do
85
+ step 'the server returns a "504 Format not implemented" error'
86
+ end
87
+
88
+ Then /^the server returns an unimplemented parameter error$/ do
89
+ step('the server returns a "504 Command not '\
90
+ 'implemented for that parameter" error')
91
+ end
92
+
93
+ Then /^the server returns a command unrecognized error$/ do
94
+ step 'the server returns a "500 Syntax error, command unrecognized" error'
95
+ end
96
+
97
+ Then /^the server returns an unimplemented command error$/ do
98
+ step 'the server returns a "502 Command not implemented" error'
99
+ end
100
+
101
+ Then /^the server returns an action not taken error$/ do
102
+ step 'the server returns a "550 Unable to do it" error'
103
+ end
104
+
105
+ Then /^the server returns an already exists error$/ do
106
+ step 'the server returns a "550 Already exists" error'
107
+ end
108
+
109
+ Then /^the server returns a network protocol not supported error$/ do
110
+ step 'the server returns a "522 Network protocol" error'
111
+ end
112
+
113
+ Then /^the server sends a not allowed after epsv all error$/ do
114
+ step 'the server returns a "501 Not allowed after EPSV ALL" error'
115
+ end
@@ -0,0 +1,21 @@
1
+ When /^the client successfully requests features$/ do
2
+ @feature_reply = client.raw "FEAT"
3
+ end
4
+
5
+ def feature_regexp(feature)
6
+ /^ #{feature}$/
7
+ end
8
+
9
+ Then /^the response should include feature "(.*?)"$/ do |feature|
10
+ expect(@feature_reply).to match feature_regexp(feature)
11
+ end
12
+
13
+ Then /^the response should not include feature "(.*?)"$/ do |feature|
14
+ expect(@feature_reply).to_not match feature_regexp(feature)
15
+ end
16
+
17
+ Then /^the response should( not)? include TLS features$/ do |neg|
18
+ step %Q'the response should#{neg} include feature "AUTH TLS"'
19
+ step %Q'the response should#{neg} include feature "PBSZ"'
20
+ step %Q'the response should#{neg} include feature "PROT"'
21
+ 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
@@ -0,0 +1,9 @@
1
+ When /^the client successfully sends "(.*?)"$/ do |command|
2
+ @reply = client.raw command
3
+ end
4
+
5
+ When /^the client sends "(.*?)"$/ do |command|
6
+ capture_error do
7
+ step %Q'the client successfully sends "#{command}"'
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ When /^the client successfully gets (text|binary) "(.*?)"$/ \
2
+ do |mode, remote_path|
3
+ client.get mode, remote_path
4
+ end
5
+
6
+ When /^the client gets (\S+) "(.*?)"$/ do |mode, path|
7
+ capture_error do
8
+ step %Q(the client successfully gets #{mode} "#{path}")
9
+ end
10
+ end
11
+
12
+ When /^the client gets with no path$/ do
13
+ capture_error do
14
+ client.raw 'RETR'
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ When /^the client successfully asks for help(?: for "(.*?)")?$/ do
2
+ |command|
3
+ @help_reply = client.help(command)
4
+ end
5
+
6
+ Then /^the server should return a list of commands$/ do
7
+ commands = @help_reply.scan(/\b([A-Z][A-Z]+)\b/).flatten
8
+ expect(commands).to include 'NOOP'
9
+ expect(commands).to include 'USER'
10
+ end
11
+
12
+ Then /^the server should return help for "(.*?)"$/ do |command|
13
+ expect(@help_reply).to match /Command #{command} is recognized/
14
+ end
15
+
16
+ Then /^the server should return no help for "(.*?)"$/ do |command|
17
+ expect(@help_reply).to match /Command #{command} is not recognized/
18
+ end
@@ -0,0 +1,11 @@
1
+ When /^the client sends an empty command$/ do
2
+ capture_error do
3
+ client.raw ''
4
+ end
5
+ end
6
+
7
+ When /^the client sends a non-word command$/ do
8
+ capture_error do
9
+ client.raw '*'
10
+ end
11
+ end