ftpd 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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