ftpd 0.10.0 → 0.11.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c547a0bf777999094a612c387fb63d40a2cbc7f
4
- data.tar.gz: 021d0b2bdad238406fdc19d00c9b8036ec85a749
3
+ metadata.gz: 131edbd4d2cff04d60c36f8fb0ae07adea821823
4
+ data.tar.gz: 9b43256518b4844af2a76306ce48943999ddde08
5
5
  SHA512:
6
- metadata.gz: 5b7560963a406e9098cbbff5ba71741c642c93ce7f6296218eb28e69027c99837b07891abf922111e84601792871c3296211f66b8865711520b7a0bdc8ac3663
7
- data.tar.gz: 5797b248427a0d497de07918094c35db4a921ae016e016ae63f48fef901c8ba4a38064b0314e62037c00dd695f879bf6b0e880441f9701d7ad884328838f5331
6
+ metadata.gz: becd885798f77294b84ef32815c018b2ac0dc15f467a72ae338b06e507f0dc91a464e56f405c5612897e3ec8bd24322ab98220d4c60815be70b5db75f8626274
7
+ data.tar.gz: 30b34af9047acf54b926e9f55803004003ba95bd269a120749a55cbfd329682eb42d579be6823634abd34679fc837641181ac0d65d629a6888c5775b73693d3e
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
- - 2.0.0
4
+ - 2.0
5
+ - 2.1
@@ -2,6 +2,18 @@ This is the change log for the main branch of ftpd, which supports
2
2
  Ruby 1.9 and greater. For ruby 1.8.7, please use the latest version
3
3
  before 0.8.0.
4
4
 
5
+ ### 0.11.0
6
+
7
+ Bug fixes
8
+
9
+ * Fix Bad file descriptor exception on stop (issue #20)
10
+ * CWD returns 250, not 257 (issue #18)
11
+
12
+ #Enhancements
13
+
14
+ * MDTM command (issue #19)
15
+ * SIZE command (issue #19)
16
+
5
17
  ### 0.10.0
6
18
 
7
19
  Bug fixes
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ftpd [![Code Climate](https://codeclimate.com/github/wconrad/ftpd.png)](https://codeclimate.com/github/wconrad/ftpd) [![Build Status](https://travis-ci.org/wconrad/ftpd.png)](https://travis-ci.org/wconrad/ftpd)
2
2
 
3
3
  ftpd is a pure Ruby FTP server library. It supports implicit and
4
- explicit TLS, passive and active mode, and is unconditionally
4
+ explicit TLS, IPV6, passive and active mode, and is unconditionally
5
5
  compliant per [RFC-1123][1]. It can be used as part of a test fixture
6
6
  or embedded in a program.
7
7
 
@@ -330,8 +330,10 @@ Among those who have improved ftpd are:
330
330
 
331
331
  * Alfonso Cora
332
332
  * Bjoern B. Dorra
333
+ * Joshua Rutherford
333
334
  * Larry. W. Cashdollar
334
335
  * Michael de Silva
336
+ * cransom
335
337
 
336
338
  Thank you!
337
339
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.0
1
+ 0.11.0
@@ -252,7 +252,7 @@ LANG command No ---
252
252
  UNICODE No ---
253
253
  </pre>
254
254
 
255
- RFC-3659 - Extensions to FTP
255
+ ## RFC-3659 - Extensions to FTP
256
256
 
257
257
  Four new commands are added: "SIZE", "MDTM", "MLST", and "MLSD". The existing command "REST" is modified.
258
258
 
@@ -262,13 +262,13 @@ Four new commands are added: "SIZE", "MDTM", "MLST", and "MLSD". The existing co
262
262
  * [link](http://tools.ietf.org/rfc/rfc3659.txt)
263
263
 
264
264
  <pre>
265
- MDTM command No --- Get file's last modification time
265
+ MDTM command Yes --- Get file's last modification time
266
266
  MLSD command No --- Get directory list in a standardized form.
267
267
  MLST command No --- Get file information in a standardized form.
268
- SIZE command No --- Get file size.
268
+ SIZE command Yes --- Get file size.
269
269
  TVSF mechanism No --- Unix-like file system naming conventions
270
270
  Min. MLST facts No ---
271
- GMT timestamps No ---
271
+ GMT timestamps Yes ---
272
272
  </pre>
273
273
 
274
274
  ##RFC-4217 - Securing FTP with TLS
@@ -23,7 +23,7 @@ require 'tmpdir'
23
23
  module Fetcher
24
24
 
25
25
  # This is the code under test, a simple fetcher that logs into an
26
- # FTP site, changes to a directlry, and gets a list of files.
26
+ # FTP site, changes to a directory, and gets a list of files.
27
27
 
28
28
  class FTPFetcher
29
29
 
@@ -58,7 +58,7 @@ end
58
58
  describe Fetcher::FTPFetcher do
59
59
 
60
60
  # This `Driver` tells Ftpd how to authenticate and how to interact
61
- # with the file systme. In this example, the file system is
61
+ # with the file system. In this example, the file system is
62
62
  # read-only and contains a single file.
63
63
 
64
64
  class Driver
@@ -24,3 +24,15 @@ Feature: Features
24
24
  And the client connects
25
25
  When the client sends "FEAT FOO"
26
26
  Then the server returns a syntax error
27
+
28
+ Scenario: IPV6 Extensions
29
+ Given the test server is started
30
+ When the client successfully requests features
31
+ Then the response should include feature "EPRT"
32
+ And the response should include feature "EPSV"
33
+
34
+ Scenario: RFC 3659 Extensions
35
+ Given the test server is started
36
+ When the client successfully requests features
37
+ Then the response should include feature "SIZE"
38
+ Then the response should include feature "MDTM"
@@ -0,0 +1,53 @@
1
+ Feature: MDTM
2
+
3
+ As a client
4
+ I want to get a file's modification time
5
+ So that I can detect when it changes
6
+
7
+ Background:
8
+ Given the test server is started
9
+
10
+ Scenario: File in current directory
11
+ Given a successful login
12
+ And the server has file "ascii_unix"
13
+ And the file "ascii_unix" has mtime "2014-01-02 13:14:15.123456"
14
+ When the client successfully gets mtime of "ascii_unix"
15
+ Then the reported mtime should be "20140102131415"
16
+
17
+ Scenario: File in subdirectory
18
+ Given a successful login
19
+ And the server has file "foo/ascii_unix"
20
+ Then the client successfully gets mtime of "foo/ascii_unix"
21
+
22
+ Scenario: Non-root working directory
23
+ Given a successful login
24
+ And the server has file "foo/ascii_unix"
25
+ And the client successfully cd's to "foo"
26
+ Then the client successfully gets mtime of "ascii_unix"
27
+
28
+ Scenario: Access denied
29
+ Given a successful login
30
+ When the client gets mtime of "forbidden"
31
+ Then the server returns an access denied error
32
+
33
+ Scenario: Missing file
34
+ Given a successful login
35
+ When the client gets mtime of "foo"
36
+ Then the server returns a not found error
37
+
38
+ Scenario: Not logged in
39
+ Given a successful connection
40
+ When the client gets mtime of "foo"
41
+ Then the server returns a not logged in error
42
+
43
+ Scenario: Missing path
44
+ Given a successful login
45
+ When the client gets mtime with no path
46
+ Then the server returns a syntax error
47
+
48
+ Scenario: List not enabled
49
+ Given the test server lacks list
50
+ And a successful login
51
+ And the server has file "foo"
52
+ When the client gets mtime of "foo"
53
+ Then the server returns an unimplemented command error
@@ -0,0 +1,69 @@
1
+ Feature: Size
2
+
3
+ As a client
4
+ I want to know the size of a file
5
+ So that I can tell how long it will take to get it
6
+
7
+ Background:
8
+ Given the test server is started
9
+
10
+ Scenario: ASCII file with *nix line endings
11
+ Given a successful login
12
+ And the server has file "ascii_unix"
13
+ When the client successfully gets size of text "ascii_unix"
14
+ Then the reported size should be "83"
15
+
16
+ Scenario: ASCII file with windows line endings
17
+ Given a successful login
18
+ And the server has file "ascii_windows"
19
+ When the client successfully gets size of text "ascii_windows"
20
+ Then the reported size should be "83"
21
+
22
+ Scenario: Binary file
23
+ Given a successful login
24
+ And the server has file "binary"
25
+ When the client successfully gets size of binary "binary"
26
+ Then the reported size should be "256"
27
+
28
+ Scenario: File in subdirectory
29
+ Given a successful login
30
+ And the server has file "foo/ascii_unix"
31
+ Then the client successfully gets size of text "foo/ascii_unix"
32
+
33
+ Scenario: Non-root working directory
34
+ Given a successful login
35
+ And the server has file "foo/ascii_unix"
36
+ And the client successfully cd's to "foo"
37
+ Then the client successfully gets size of text "ascii_unix"
38
+
39
+ Scenario: Access denied
40
+ Given a successful login
41
+ When the client gets size of text "forbidden"
42
+ Then the server returns an access denied error
43
+
44
+ Scenario: Missing file
45
+ Given a successful login
46
+ When the client gets size of text "foo"
47
+ Then the server returns a not found error
48
+
49
+ Scenario: Not logged in
50
+ Given a successful connection
51
+ When the client gets size of text "foo"
52
+ Then the server returns a not logged in error
53
+
54
+ Scenario: Missing path
55
+ Given a successful login
56
+ When the client gets size with no path
57
+ Then the server returns a syntax error
58
+
59
+ Scenario: File system error
60
+ Given a successful login
61
+ When the client gets size of text "unable"
62
+ Then the server returns an action not taken error
63
+
64
+ Scenario: Read not enabled
65
+ Given the test server lacks read
66
+ And a successful login
67
+ And the server has file "foo"
68
+ When the client gets size of text "foo"
69
+ Then the server returns an unimplemented command error
@@ -0,0 +1,23 @@
1
+ require 'date'
2
+
3
+ When /^the client successfully gets mtime of "(.*?)"$/ \
4
+ do |remote_path|
5
+ @mtime = client.get_mtime remote_path
6
+ end
7
+
8
+ When /^the client gets mtime of "(.*?)"$/ do |path|
9
+ capture_error do
10
+ step %Q(the client successfully gets mtime of "#{path}")
11
+ end
12
+ end
13
+
14
+ When /^the client gets mtime with no path$/ do
15
+ capture_error do
16
+ client.raw 'MDTM'
17
+ end
18
+ end
19
+
20
+ Then(/^the reported mtime should be "(.*?)"$/) do |mtime|
21
+ expected_time = DateTime.parse(mtime).to_time.utc
22
+ @mtime.should eq expected_time
23
+ end
@@ -1,3 +1,5 @@
1
+ require 'date'
2
+
1
3
  Given /^the server has directory "(.*?)"$/ do |remote_path|
2
4
  server.add_directory remote_path
3
5
  end
@@ -6,6 +8,11 @@ Given /^the server has file "(.*?)"$/ do |remote_path|
6
8
  server.add_file remote_path
7
9
  end
8
10
 
11
+ Given(/^the file "(.*?)" has mtime "(.*?)"$/) do |remote_path, mtime|
12
+ mtime = DateTime.parse(mtime).to_time.utc
13
+ server.set_mtime remote_path, mtime
14
+ end
15
+
9
16
  Then /^the server should( not)? have file "(.*?)"$/ do |neg, path|
10
17
  matcher = if neg
11
18
  :be_false
@@ -0,0 +1,20 @@
1
+ When /^the client successfully gets size of (text|binary) "(.*?)"$/ \
2
+ do |mode, remote_path|
3
+ @size = client.get_size mode, remote_path
4
+ end
5
+
6
+ When /^the client gets size of (\S+) "(.*?)"$/ do |mode, path|
7
+ capture_error do
8
+ step %Q(the client successfully gets size of #{mode} "#{path}")
9
+ end
10
+ end
11
+
12
+ When /^the client gets size with no path$/ do
13
+ capture_error do
14
+ client.raw 'SIZE'
15
+ end
16
+ end
17
+
18
+ Then(/^the reported size should be "(.*?)"$/) do |size|
19
+ @size.should eq size.to_i
20
+ end
@@ -71,6 +71,18 @@ class TestClient
71
71
  @ftp.send method, local_path(remote_path), remote_path
72
72
  end
73
73
 
74
+ def get_size(mode, remote_path)
75
+ raise unless ['binary', 'text'].include?(mode)
76
+ @ftp.binary = mode == 'binary'
77
+ override_with_binary do
78
+ @ftp.size(remote_path)
79
+ end
80
+ end
81
+
82
+ def get_mtime(remote_path)
83
+ @ftp.mtime(remote_path)
84
+ end
85
+
74
86
  def add_file(path)
75
87
  full_path = temp_path(path)
76
88
  mkdir_p File.dirname(full_path)
@@ -141,16 +153,19 @@ class TestClient
141
153
  end
142
154
 
143
155
  def make_ftp
144
- case @tls_mode
145
- when :off
146
- make_non_tls_ftp
147
- when :implicit
148
- make_tls_ftp(:implicit)
149
- when :explicit
150
- make_tls_ftp(:explicit)
151
- else
152
- raise "Unknown TLS mode: #{@tls_mode}"
153
- end
156
+ ftp =
157
+ case @tls_mode
158
+ when :off
159
+ make_non_tls_ftp
160
+ when :implicit
161
+ make_tls_ftp(:implicit)
162
+ when :explicit
163
+ make_tls_ftp(:explicit)
164
+ else
165
+ raise "Unknown TLS mode: #{@tls_mode}"
166
+ end
167
+ allow_size_in_ascii_mode ftp
168
+ ftp
154
169
  end
155
170
 
156
171
  def make_tls_ftp(ftps_mode)
@@ -167,6 +182,40 @@ class TestClient
167
182
  Net::FTP.new
168
183
  end
169
184
 
185
+ # Ruby FTP client forces binary mode when doing a SIZE command. Our
186
+ # tests want to check that the server's SIZE command works correctly
187
+ # in ASCII mode as well, so we'll monkey-patch the FTP client.
188
+
189
+ def allow_size_in_ascii_mode(ftp)
190
+
191
+ class << ftp
192
+
193
+ attr_accessor :override_with_binary
194
+
195
+ alias :orig_with_binary :with_binary
196
+
197
+ def with_binary(*args, &block)
198
+ if @override_with_binary
199
+ block.call
200
+ else
201
+ return orig_with_binary(*args, &block)
202
+ end
203
+ end
204
+
205
+ end
206
+
207
+ end
208
+
209
+ def override_with_binary
210
+ orig = @ftp.override_with_binary
211
+ begin
212
+ @ftp.override_with_binary = true
213
+ yield
214
+ ensure
215
+ @ftp.override_with_binary = orig
216
+ end
217
+ end
218
+
170
219
  # Ruby 2.0's Ftp class is expecting a TCPSocket, not a Socket. The
171
220
  # trouble comes with Ftp#close, which closes sockets by first doing
172
221
  # a shutdown, setting the read timeout, and doing a read. Plain
@@ -8,6 +8,11 @@ module TestServerFiles
8
8
  end
9
9
  end
10
10
 
11
+ def set_mtime(path, mtime)
12
+ full_path = temp_path(path)
13
+ File.utime(File.atime(full_path), mtime, full_path)
14
+ end
15
+
11
16
  def add_directory(path)
12
17
  full_path = temp_path(path)
13
18
  mkdir_p full_path
@@ -2,16 +2,17 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: ftpd 0.10.0 ruby lib
5
+ # stub: ftpd 0.11.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "ftpd"
9
- s.version = "0.10.0"
9
+ s.version = "0.11.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
12
13
  s.authors = ["Wayne Conrad"]
13
- s.date = "2013-10-26"
14
- s.description = "ftpd is a pure Ruby FTP server library. It supports implicit and explicit TLS, passive and active mode, and is unconditionally compliant per [RFC-1123][1]. It can be used as part of a test fixture or embedded in a program."
14
+ s.date = "2014-03-16"
15
+ s.description = "ftpd is a pure Ruby FTP server library. It supports implicit and explicit TLS, IPV6, passive and active mode, and is unconditionally compliant per [RFC-1123][1]. It can be used as part of a test fixture or embedded in a program."
15
16
  s.email = "wconrad@yagni.com"
16
17
  s.extra_rdoc_files = [
17
18
  "LICENSE.md",
@@ -64,6 +65,7 @@ Gem::Specification.new do |s|
64
65
  "features/ftp_server/login_auth_level_password.feature",
65
66
  "features/ftp_server/login_auth_level_user.feature",
66
67
  "features/ftp_server/max_connections.feature",
68
+ "features/ftp_server/mdtm.feature",
67
69
  "features/ftp_server/mkdir.feature",
68
70
  "features/ftp_server/mode.feature",
69
71
  "features/ftp_server/name_list.feature",
@@ -80,6 +82,7 @@ Gem::Specification.new do |s|
80
82
  "features/ftp_server/rename.feature",
81
83
  "features/ftp_server/rmdir.feature",
82
84
  "features/ftp_server/site.feature",
85
+ "features/ftp_server/size.feature",
83
86
  "features/ftp_server/status.feature",
84
87
  "features/ftp_server/step_definitions/logging.rb",
85
88
  "features/ftp_server/step_definitions/test_server.rb",
@@ -108,6 +111,7 @@ Gem::Specification.new do |s|
108
111
  "features/step_definitions/login.rb",
109
112
  "features/step_definitions/mkdir.rb",
110
113
  "features/step_definitions/mode.rb",
114
+ "features/step_definitions/mtime.rb",
111
115
  "features/step_definitions/noop.rb",
112
116
  "features/step_definitions/options.rb",
113
117
  "features/step_definitions/passive.rb",
@@ -119,6 +123,7 @@ Gem::Specification.new do |s|
119
123
  "features/step_definitions/rmdir.rb",
120
124
  "features/step_definitions/server_files.rb",
121
125
  "features/step_definitions/server_title.rb",
126
+ "features/step_definitions/size.rb",
122
127
  "features/step_definitions/status.rb",
123
128
  "features/step_definitions/success_replies.rb",
124
129
  "features/step_definitions/system.rb",
@@ -186,8 +191,7 @@ Gem::Specification.new do |s|
186
191
  ]
187
192
  s.homepage = "http://github.com/wconrad/ftpd"
188
193
  s.licenses = ["MIT"]
189
- s.require_paths = ["lib"]
190
- s.rubygems_version = "2.1.3"
194
+ s.rubygems_version = "2.2.1"
191
195
  s.summary = "Pure Ruby FTP server library"
192
196
 
193
197
  if s.respond_to? :specification_version then
@@ -25,6 +25,7 @@ module Ftpd
25
25
  def initialize
26
26
  @interface = '127.0.0.1'
27
27
  @port = 0
28
+ @stopping = false
28
29
  end
29
30
 
30
31
  # The port the server is bound to. Must not be called until after
@@ -48,6 +49,7 @@ module Ftpd
48
49
  # stops the thread.
49
50
 
50
51
  def stop
52
+ @stopping = true
51
53
  @server_socket.close
52
54
  end
53
55
 
@@ -68,6 +70,10 @@ module Ftpd
68
70
  IO.select([@server_socket])
69
71
  sleep(0.2)
70
72
  retry
73
+ rescue Errno::EBADF
74
+ raise unless @stopping
75
+ @stopping = false
76
+ break
71
77
  end
72
78
  start_session socket
73
79
  rescue IOError
@@ -277,7 +277,7 @@ module Ftpd
277
277
  ensure_exists path
278
278
  ensure_directory path
279
279
  @name_prefix = path
280
- pwd
280
+ pwd 250
281
281
  end
282
282
  alias cmd_xcwd :cmd_cwd
283
283
 
@@ -368,7 +368,7 @@ module Ftpd
368
368
 
369
369
  def cmd_pwd(argument)
370
370
  ensure_logged_in
371
- pwd
371
+ pwd 257
372
372
  end
373
373
  alias cmd_xpwd :cmd_pwd
374
374
 
@@ -528,6 +528,36 @@ module Ftpd
528
528
  end
529
529
  end
530
530
 
531
+ def cmd_mdtm(path)
532
+ ensure_logged_in
533
+ ensure_file_system_supports :dir
534
+ ensure_file_system_supports :file_info
535
+ syntax_error unless path
536
+ path = File.expand_path(path, @name_prefix)
537
+ ensure_accessible(path)
538
+ ensure_exists(path)
539
+ info = @file_system.file_info(path)
540
+ mtime = info.mtime.utc
541
+ # We would like to report fractional seconds, too. Sadly, the
542
+ # spec declares that we may not report more precision than is
543
+ # actually there, and there is no spec or API to tell us how
544
+ # many fractional digits are significant.
545
+ mtime = mtime.strftime("%Y%m%d%H%M%S")
546
+ reply "213 #{mtime}"
547
+ end
548
+
549
+ def cmd_size(path)
550
+ ensure_logged_in
551
+ ensure_file_system_supports :read
552
+ syntax_error unless path
553
+ path = File.expand_path(path, @name_prefix)
554
+ ensure_accessible(path)
555
+ ensure_exists(path)
556
+ contents = @file_system.read(path)
557
+ contents = (@data_type == 'A') ? unix_to_nvt_ascii(contents) : contents
558
+ reply "213 #{contents.bytesize}"
559
+ end
560
+
531
561
  unimplemented :abor
532
562
  unimplemented :rein
533
563
  unimplemented :rest
@@ -538,6 +568,7 @@ module Ftpd
538
568
  [
539
569
  (TLS_EXTENSIONS if tls_enabled?),
540
570
  IPV6_EXTENSIONS,
571
+ RFC_3659_EXTENSIONS,
541
572
  ].flatten.compact
542
573
  end
543
574
 
@@ -552,14 +583,19 @@ module Ftpd
552
583
  'EPSV',
553
584
  ]
554
585
 
586
+ RFC_3659_EXTENSIONS = [
587
+ 'MDTM',
588
+ 'SIZE',
589
+ ]
590
+
555
591
  def supported_commands
556
592
  private_methods.map do |method|
557
593
  method.to_s[/^cmd_(\w+)$/, 1]
558
594
  end.compact.map(&:upcase)
559
595
  end
560
596
 
561
- def pwd
562
- reply %Q(257 "#{@name_prefix}" is current directory)
597
+ def pwd(status_code)
598
+ reply %Q(#{status_code} "#{@name_prefix}" is current directory)
563
599
  end
564
600
 
565
601
  TRANSMISSION_MODES = {
@@ -8,3 +8,7 @@ require 'thread'
8
8
  require 'timecop'
9
9
  require 'tmpdir'
10
10
 
11
+ glob = File.expand_path('helpers/*.rb', File.dirname(__FILE__))
12
+ Dir[glob].sort.each do |helper_path|
13
+ require helper_path
14
+ end
metadata CHANGED
@@ -1,143 +1,143 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ftpd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wayne Conrad
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-26 00:00:00.000000000 Z
11
+ date: 2014-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: memoizer
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.0.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.0.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: cucumber
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: double-bag-ftps
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: jeweler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: redcarpet
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: timecop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: yard
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - '>='
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - '>='
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  description: ftpd is a pure Ruby FTP server library. It supports implicit and explicit
140
- TLS, passive and active mode, and is unconditionally compliant per [RFC-1123][1]. It
140
+ TLS, IPV6, passive and active mode, and is unconditionally compliant per [RFC-1123][1]. It
141
141
  can be used as part of a test fixture or embedded in a program.
142
142
  email: wconrad@yagni.com
143
143
  executables: []
@@ -146,8 +146,8 @@ extra_rdoc_files:
146
146
  - LICENSE.md
147
147
  - README.md
148
148
  files:
149
- - .travis.yml
150
- - .yardopts
149
+ - ".travis.yml"
150
+ - ".yardopts"
151
151
  - Changelog.md
152
152
  - Gemfile
153
153
  - Gemfile.lock
@@ -192,6 +192,7 @@ files:
192
192
  - features/ftp_server/login_auth_level_password.feature
193
193
  - features/ftp_server/login_auth_level_user.feature
194
194
  - features/ftp_server/max_connections.feature
195
+ - features/ftp_server/mdtm.feature
195
196
  - features/ftp_server/mkdir.feature
196
197
  - features/ftp_server/mode.feature
197
198
  - features/ftp_server/name_list.feature
@@ -208,6 +209,7 @@ files:
208
209
  - features/ftp_server/rename.feature
209
210
  - features/ftp_server/rmdir.feature
210
211
  - features/ftp_server/site.feature
212
+ - features/ftp_server/size.feature
211
213
  - features/ftp_server/status.feature
212
214
  - features/ftp_server/step_definitions/logging.rb
213
215
  - features/ftp_server/step_definitions/test_server.rb
@@ -236,6 +238,7 @@ files:
236
238
  - features/step_definitions/login.rb
237
239
  - features/step_definitions/mkdir.rb
238
240
  - features/step_definitions/mode.rb
241
+ - features/step_definitions/mtime.rb
239
242
  - features/step_definitions/noop.rb
240
243
  - features/step_definitions/options.rb
241
244
  - features/step_definitions/passive.rb
@@ -247,6 +250,7 @@ files:
247
250
  - features/step_definitions/rmdir.rb
248
251
  - features/step_definitions/server_files.rb
249
252
  - features/step_definitions/server_title.rb
253
+ - features/step_definitions/size.rb
250
254
  - features/step_definitions/status.rb
251
255
  - features/step_definitions/success_replies.rb
252
256
  - features/step_definitions/system.rb
@@ -321,17 +325,17 @@ require_paths:
321
325
  - lib
322
326
  required_ruby_version: !ruby/object:Gem::Requirement
323
327
  requirements:
324
- - - '>='
328
+ - - ">="
325
329
  - !ruby/object:Gem::Version
326
330
  version: '0'
327
331
  required_rubygems_version: !ruby/object:Gem::Requirement
328
332
  requirements:
329
- - - '>='
333
+ - - ">="
330
334
  - !ruby/object:Gem::Version
331
335
  version: '0'
332
336
  requirements: []
333
337
  rubyforge_project:
334
- rubygems_version: 2.1.3
338
+ rubygems_version: 2.2.1
335
339
  signing_key:
336
340
  specification_version: 4
337
341
  summary: Pure Ruby FTP server library