ftpd 0.4.0 → 0.5.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.
- data/Changelog.md +33 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +5 -0
- data/README.md +29 -30
- data/VERSION +1 -1
- data/config/cucumber.yml +2 -0
- data/doc/benchmarks.md +92 -0
- data/doc/references.md +39 -12
- data/doc/rfc-compliance.md +6 -6
- data/examples/example.rb +21 -0
- data/features/ftp_server/command_errors.feature +0 -1
- data/features/ftp_server/logging.feature +11 -0
- data/features/ftp_server/port.feature +15 -0
- data/features/ftp_server/status.feature +19 -0
- data/features/ftp_server/step_definitions/logging.rb +8 -0
- data/features/ftp_server/step_definitions/test_server.rb +19 -2
- data/features/ftp_server/timeout.feature +26 -0
- data/features/step_definitions/error_replies.rb +5 -0
- data/features/step_definitions/status.rb +17 -0
- data/features/step_definitions/timeout.rb +11 -0
- data/features/support/test_client.rb +13 -1
- data/features/support/test_server.rb +23 -9
- data/ftpd.gemspec +18 -5
- data/lib/ftpd.rb +3 -0
- data/lib/ftpd/ftp_server.rb +52 -18
- data/lib/ftpd/null_logger.rb +22 -0
- data/lib/ftpd/server.rb +11 -2
- data/lib/ftpd/session.rb +71 -25
- data/lib/ftpd/telnet.rb +119 -0
- data/rake_tasks/cucumber.rake +0 -1
- data/spec/null_logger_spec.rb +24 -0
- data/spec/telnet_spec.rb +75 -0
- metadata +32 -6
- data/features/ftp_server/debug.feature +0 -17
- data/features/ftp_server/step_definitions/debug.rb +0 -8
data/Changelog.md
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
### 0.5.0
|
2
|
+
|
3
|
+
Bug fixes
|
4
|
+
|
5
|
+
* Replies are sent with the correct line ending ("\r\n" instead of
|
6
|
+
"\n")
|
7
|
+
* Do not hang on out-of-band commands.
|
8
|
+
* When data connection disconnects, send "426 Connection closed"
|
9
|
+
response instead of ending the session.
|
10
|
+
|
11
|
+
Enhancements
|
12
|
+
|
13
|
+
* Now unconditionally compliant
|
14
|
+
* Configurable session timeout (see {Ftpd::FtpServer#session_timeout}).
|
15
|
+
Defaults to 5 minutes.
|
16
|
+
* Disable Nagle algorithm on control connection to decrease latency.
|
17
|
+
This makes the tests run much faster.
|
18
|
+
* Support STAT (server status).
|
19
|
+
* Example has --timeout option for session idle timeout.
|
20
|
+
* Write log to Logger (see {Ftpd::FtpServer#log}).
|
21
|
+
* Disallow active-mode connections to privileged ports (configurable).
|
22
|
+
See RFC 2577 section 3.
|
23
|
+
* Added benchmarks.
|
24
|
+
* Support telnet sequences.
|
25
|
+
|
26
|
+
API Changes
|
27
|
+
|
28
|
+
* Added {Ftpd::FtpServer#server_name}
|
29
|
+
* Added {Ftpd::FtpServer#server_version}
|
30
|
+
* Removed #debug and #debug_path from Ftpd::FtpServer. They have been
|
31
|
+
replaced with #log
|
32
|
+
# Added {Ftpd::FtpServer#allow_low_data_ports}
|
33
|
+
|
1
34
|
### 0.4.0
|
2
35
|
|
3
36
|
Enhancements
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -14,6 +14,9 @@ GEM
|
|
14
14
|
gherkin (~> 2.11.0)
|
15
15
|
json (>= 1.4.6)
|
16
16
|
diff-lcs (1.2.1)
|
17
|
+
fuubar-cucumber (0.0.18)
|
18
|
+
cucumber (~> 1.2.0)
|
19
|
+
ruby-progressbar (~> 1.0.0)
|
17
20
|
gherkin (2.11.6)
|
18
21
|
json (>= 1.7.6)
|
19
22
|
git (1.2.5)
|
@@ -36,6 +39,7 @@ GEM
|
|
36
39
|
rspec-expectations (2.13.0)
|
37
40
|
diff-lcs (>= 1.1.3, < 2.0)
|
38
41
|
rspec-mocks (2.13.0)
|
42
|
+
ruby-progressbar (1.0.2)
|
39
43
|
timecop (0.5.9.2)
|
40
44
|
yard (0.8.5.2)
|
41
45
|
|
@@ -45,6 +49,7 @@ PLATFORMS
|
|
45
49
|
DEPENDENCIES
|
46
50
|
cucumber
|
47
51
|
double-bag-ftps!
|
52
|
+
fuubar-cucumber
|
48
53
|
jeweler
|
49
54
|
memoizer (~> 1.0.1)
|
50
55
|
rake
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# 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
|
5
|
-
|
4
|
+
explicit TLS, passive and active mode, and is unconditionally
|
5
|
+
complaint per RFC-1123. It an be used as part of a test fixture or
|
6
6
|
embedded in a program.
|
7
7
|
|
8
8
|
## A note about this README
|
@@ -10,7 +10,7 @@ embedded in a program.
|
|
10
10
|
This readme, and the other files, contains Yardoc markup, especially
|
11
11
|
for links to the API docs; those links don't display properly on
|
12
12
|
github. You'll find a properly rendered version
|
13
|
-
|
13
|
+
[on rubydoc.info](http://rubydoc.info/gems/ftpd)
|
14
14
|
|
15
15
|
## HELLO WORLD
|
16
16
|
|
@@ -83,14 +83,17 @@ file system.
|
|
83
83
|
Here are the methods a file system may expose:
|
84
84
|
|
85
85
|
* {Ftpd::DiskFileSystem::Accessors#accessible? accessible?}
|
86
|
-
* {Ftpd::DiskFileSystem::Accessors#exists? exists?}
|
87
86
|
* {Ftpd::DiskFileSystem::Accessors#directory? directory?}
|
88
|
-
* {Ftpd::DiskFileSystem::
|
89
|
-
* {Ftpd::DiskFileSystem::
|
90
|
-
* {Ftpd::DiskFileSystem::
|
91
|
-
* {Ftpd::DiskFileSystem::List#file_info file_info}
|
87
|
+
* {Ftpd::DiskFileSystem::Accessors#exists? exists?}
|
88
|
+
* {Ftpd::DiskFileSystem::Append#append append}
|
89
|
+
* {Ftpd::DiskFileSystem::Delete#delete delete}
|
92
90
|
* {Ftpd::DiskFileSystem::List#dir dir}
|
91
|
+
* {Ftpd::DiskFileSystem::List#file_info file_info}
|
92
|
+
* {Ftpd::DiskFileSystem::Mkdir#mkdir mkdir}
|
93
|
+
* {Ftpd::DiskFileSystem::Read#read read}
|
93
94
|
* {Ftpd::DiskFileSystem::Rename#rename rename}
|
95
|
+
* {Ftpd::DiskFileSystem::Rmdir#rmdir rmdir}
|
96
|
+
* {Ftpd::DiskFileSystem::Write#write write}
|
94
97
|
|
95
98
|
### DiskFileSystem
|
96
99
|
|
@@ -113,6 +116,7 @@ file system, then use {Ftpd::ReadOnlyDiskFileSystem} instead.
|
|
113
116
|
The DiskFileSystem is composed out of modules:
|
114
117
|
|
115
118
|
* {Ftpd::DiskFileSystem::Base Base} - You will need this
|
119
|
+
* {Ftpd::DiskFileSystem::Append Append} - File appending
|
116
120
|
* {Ftpd::DiskFileSystem::Delete Delete} - File deletion
|
117
121
|
* {Ftpd::DiskFileSystem::List List} - Directory listing
|
118
122
|
* {Ftpd::DiskFileSystem::Mkdir Mkdir} - Directory creation
|
@@ -148,7 +152,7 @@ By default, the LIST command uses Unix "ls -l" formatting:
|
|
148
152
|
-rw-r--r-- 1 user group 1234 Mar 3 08:38 foo
|
149
153
|
|
150
154
|
To switch to
|
151
|
-
|
155
|
+
[Easily Parsed LIST format (EPLF)](http://cr.yp.to/ftp/list/eplf.html)
|
152
156
|
format:
|
153
157
|
|
154
158
|
ftp_server.list_formatter = Ftpd::ListFormat::Eplf
|
@@ -181,27 +185,15 @@ Debug output can also be enabled by setting the environment variable
|
|
181
185
|
FTPD_DEBUG to a non-zero value. This is a convenient way to get debug
|
182
186
|
output without having to change any code.
|
183
187
|
|
184
|
-
##
|
185
|
-
|
186
|
-
Ftpd is not fully RFC compliant. It does most of RFC969, and enough
|
187
|
-
TLS to get by. {file:doc/rfc.md Here} is a list of RFCs, indicating
|
188
|
-
how much of each Ftpd complies with.
|
189
|
-
|
190
|
-
RFC does not meet the following
|
191
|
-
[RFC-1123](http://tools.ietf.org/rfc/rfc1123.txt) "MUST" requrements.
|
192
|
-
If FTPD met these requirements, but did not meet the "SHOULD"
|
193
|
-
requirements, it would be "conditionally compliant":
|
188
|
+
## STANDARDS COMPLIANCE
|
194
189
|
|
195
|
-
|
196
|
-
|
190
|
+
Ftpd is fully unconditionally compliant per [RFC-1123 Requirements for
|
191
|
+
Internet Hosts](http://tools.ietf.org/rfc/rfc1123.txt).
|
197
192
|
|
198
|
-
|
199
|
-
|
200
|
-
"SHOULD" requrements. If FTPD met both the "MUST" and the "SHOULD"
|
201
|
-
requirements, it would be "unconditionally compliant":
|
193
|
+
Ftpd implements enough of [RFC-4217 Securing FTP with
|
194
|
+
TLS](http://tools.ietf.org/rfc/rfc4217.txt) to get by.
|
202
195
|
|
203
|
-
|
204
|
-
* Configurable idle timeout
|
196
|
+
See [RFC Compliance](doc/rfc-compliance.md) for details
|
205
197
|
|
206
198
|
## RUBY COMPATABILITY
|
207
199
|
|
@@ -231,6 +223,12 @@ or just:
|
|
231
223
|
|
232
224
|
$ rake
|
233
225
|
|
226
|
+
To force features to write the server log to stdout:
|
227
|
+
|
228
|
+
$ FTPD_DEBUG=1 rake test:features
|
229
|
+
|
230
|
+
### Example
|
231
|
+
|
234
232
|
To run the stand-alone example:
|
235
233
|
|
236
234
|
$ examples/example.rb
|
@@ -256,6 +254,7 @@ and granted permission to donate it to the community.
|
|
256
254
|
|
257
255
|
## See also
|
258
256
|
|
259
|
-
*
|
260
|
-
*
|
261
|
-
*
|
257
|
+
* [Changelog](Changelog.md)
|
258
|
+
* [RFC compliance](doc/rfc-compliance.md)
|
259
|
+
* [References](doc/references.md)
|
260
|
+
* [Benchmarks](doc/benchmarks.md)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/config/cucumber.yml
ADDED
data/doc/benchmarks.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Benchmarks
|
2
|
+
|
3
|
+
Benchmarks using pyftpd's [benchmark
|
4
|
+
script](http://pyftpdlib.googlecode.com/svn/trunk/test/bench.py) and
|
5
|
+
[procedures](http://code.google.com/p/pyftpdlib/wiki/Benchmarks).
|
6
|
+
|
7
|
+
## Results
|
8
|
+
|
9
|
+
### ftpd 0.4.0
|
10
|
+
|
11
|
+
(starting with 13.6M of RSS memory being used)
|
12
|
+
STOR (client -> server) 845.55 MB/sec 13.6M RSS
|
13
|
+
RETR (server -> client) 1234.80 MB/sec 859.5M RSS
|
14
|
+
200 concurrent clients (connect, login) 0.14 secs 863.0M RSS
|
15
|
+
STOR (1 file with 200 idle clients) 848.56 MB/sec 863.0M RSS
|
16
|
+
RETR (1 file with 200 idle clients) 1227.46 MB/sec 866.4M RSS
|
17
|
+
200 concurrent clients (RETR 10.0M file) 5.36 secs 2.0G RSS
|
18
|
+
200 concurrent clients (STOR 10.0M file) 4.65 secs 2.0G RSS
|
19
|
+
200 concurrent clients (QUIT) 0.01 secs
|
20
|
+
|
21
|
+
### pyftpdlib 1.0.1
|
22
|
+
|
23
|
+
(starting with 8.9M of RSS memory being used)
|
24
|
+
STOR (client -> server) 81.73 MB/sec 8.9M RSS
|
25
|
+
RETR (server -> client) 1001.05 MB/sec 8.9M RSS
|
26
|
+
200 concurrent clients (connect, login) 2.58 secs 9.6M RSS
|
27
|
+
STOR (1 file with 200 idle clients) 108.46 MB/sec 9.6M RSS
|
28
|
+
RETR (1 file with 200 idle clients) 1134.18 MB/sec 9.6M RSS
|
29
|
+
200 concurrent clients (RETR 10.0M file) 2.32 secs 10.3M RSS
|
30
|
+
200 concurrent clients (STOR 10.0M file) 4.12 secs 10.4M RSS
|
31
|
+
200 concurrent clients (QUIT) 0.02 secs
|
32
|
+
|
33
|
+
### proftpd 1.3.4a-3
|
34
|
+
|
35
|
+
(starting with 2.3M of RSS memory being used)
|
36
|
+
STOR (client -> server) 93.06 MB/sec 6.6M RSS
|
37
|
+
RETR (server -> client) 1267.63 MB/sec 6.6M RSS
|
38
|
+
200 concurrent clients (connect, login) 14.21 secs 868.0M RSS
|
39
|
+
STOR (1 file with 200 idle clients) 76.04 MB/sec 872.3M RSS
|
40
|
+
RETR (1 file with 200 idle clients) 1289.75 MB/sec 872.3M RSS
|
41
|
+
200 concurrent clients (RETR 10.0M file) 2.04 secs 868.0M RSS
|
42
|
+
200 concurrent clients (STOR 10.0M file) 4.51 secs 868.2M RSS
|
43
|
+
200 concurrent clients (QUIT) 0.00 secs
|
44
|
+
|
45
|
+
### Discussion
|
46
|
+
|
47
|
+
ftpd's STOR results seen anomalous. I suspect that proftpd and
|
48
|
+
pyftpdlib aren't getting a fair shake here. proftpd and pyftpdlib are
|
49
|
+
serving my home directory, whereas ftpd is serving a temporary
|
50
|
+
directory, but I don't know what difference that could make.
|
51
|
+
|
52
|
+
Ftpd is a memory hog. During a STOR or RETR, it loads the entire
|
53
|
+
contents of a file into memory. This limits the number of concurrent
|
54
|
+
file transfers it can handle. The pyftpd team uses -n 300 (300
|
55
|
+
concurrent connections) when benchmarking, but Ftpd can't handle that
|
56
|
+
many at the moment.
|
57
|
+
|
58
|
+
Ftpd's fast time on the login test, compared to proftpd and pyftpdlib,
|
59
|
+
is a result of it not doing PAM authentication. It is an unfair
|
60
|
+
comparison and should be disregarded.
|
61
|
+
|
62
|
+
pyftpd's memory footprint is impressive.
|
63
|
+
|
64
|
+
ftpd is less performant with many concurrent connections than either
|
65
|
+
proftpd or pyftpdlib.
|
66
|
+
|
67
|
+
## Setup
|
68
|
+
|
69
|
+
### Machine
|
70
|
+
|
71
|
+
* Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz (4 cores)
|
72
|
+
* Python 2.7.3rc2 (default, Apr 22 2012, 22:35:38)
|
73
|
+
* ruby 2.0.0p0 (2013-02-24 revision 39474) [i686-linux]
|
74
|
+
* Linux 3.0.0-1-686-pae #1 SMP Sat Aug 27 16:41:03 UTC 2011 i686 GNU/Linux
|
75
|
+
|
76
|
+
### Benchmark command
|
77
|
+
|
78
|
+
$ python bench.py -u <USER> -p <PASS> -H localhost -p <PORT> -b all -n 200 -k <PID>
|
79
|
+
|
80
|
+
### Proftpd
|
81
|
+
|
82
|
+
/etc/proftpd/proftpd.conf:
|
83
|
+
|
84
|
+
MaxInstances 2000
|
85
|
+
|
86
|
+
### Ftpd
|
87
|
+
|
88
|
+
$ bundle exec examples/example.rb -p 2222 -U bench -P bench
|
89
|
+
|
90
|
+
### Pyftpd
|
91
|
+
|
92
|
+
pyftpdlib-1.0.0/demo$ sudo python unix_daemon.py 2>/dev/null
|
data/doc/references.md
CHANGED
@@ -9,15 +9,38 @@ Copyright (c) 2008 James Healy_
|
|
9
9
|
There are a range of RFCs that together specify the FTP protocol. In
|
10
10
|
chronological order, the more useful ones are:
|
11
11
|
|
12
|
-
*
|
13
|
-
|
14
|
-
|
15
|
-
*
|
16
|
-
|
17
|
-
|
18
|
-
*
|
19
|
-
|
20
|
-
|
12
|
+
* [RFC-854](http://tools.ietf.org/rfc/rfc854.txt) - Telnet Protocol
|
13
|
+
Specification
|
14
|
+
|
15
|
+
* [RFC-959](http://tools.ietf.org/rfc/rfc959.txt) - File Transfer
|
16
|
+
Protocol
|
17
|
+
|
18
|
+
* [RFC-1123](http://tools.ietf.org/rfc/rfc1123.txt) - Requirements for
|
19
|
+
Internet Hosts
|
20
|
+
|
21
|
+
* [RFC-1143](http://tools.ietf.org/rfc/rfc1143.txt) - The Q Method of
|
22
|
+
Implementing TELNET Option Negotation
|
23
|
+
|
24
|
+
* [RFC-2228](http://tools.ietf.org/rfc/rfc2228.txt) - FTP Security
|
25
|
+
Extensions
|
26
|
+
|
27
|
+
* [RFC-2389](http://tools.ietf.org/rfc/rfc2389.txt) - Feature
|
28
|
+
negotiation mechanism for the File Transfer Protocol
|
29
|
+
|
30
|
+
* [RFC-2428](http://tools.ietf.org/rfc/rfc2428.txt) - FTP Extensions
|
31
|
+
for IPv6 and NATs
|
32
|
+
|
33
|
+
* [RFC-2577](http://tools.ietf.org/rfc/rfc2577.txt) - FTP Security
|
34
|
+
Considerations
|
35
|
+
|
36
|
+
* [RFC-2640](http://tools.ietf.org/rfc/rfc2640.txt) -
|
37
|
+
Internationalization of the File Transfer Protocol
|
38
|
+
|
39
|
+
* [RFC-3659](http://tools.ietf.org/rfc/rfc3659.txt) - Extensions to
|
40
|
+
FTP
|
41
|
+
|
42
|
+
* [RFC-4217](http://tools.ietf.org/rfc/rfc4217.txt) -
|
43
|
+
Internationalization of the File Transfer Protocol
|
21
44
|
|
22
45
|
For an english summary that's somewhat more legible than the RFCs, and
|
23
46
|
provides some commentary on what features are actually useful or
|
@@ -29,11 +52,15 @@ For a history lesson, check out Appendix III of RCF959. It lists the
|
|
29
52
|
preceding (obsolete) RFC documents that relate to file transfers,
|
30
53
|
including the ye old RFC114 from 1971, "A File Transfer Protocol"
|
31
54
|
|
32
|
-
There is a
|
55
|
+
There is a [public test server](http://secureftp-test.com) which is
|
33
56
|
very handy for checking out clients, and seeing how at least one
|
34
57
|
server behaves.
|
35
58
|
|
59
|
+
## How to reliably close a socket (and not lose data)
|
60
|
+
|
61
|
+
[Why is my TCP not reliable](http://ia600609.us.archive.org/22/items/TheUltimateSo_lingerPageOrWhyIsMyTcpNotReliable/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable.html) by Bert Hubert
|
62
|
+
|
36
63
|
## LIST output format
|
37
64
|
|
38
|
-
*
|
39
|
-
*
|
65
|
+
* [GNU docs for ls](http://www.gnu.org/software/coreutils/manual/html_node/What-information-is-listed.html#What-information-is-listed)
|
66
|
+
* [Easily Parsed LIST format (EPLF)](http://cr.yp.to/ftp/list/eplf.html)
|
data/doc/rfc-compliance.md
CHANGED
@@ -50,7 +50,7 @@ Commands supported:
|
|
50
50
|
RNTO Yes 0.2.1 Rename file (to)
|
51
51
|
SITE No --- Site specific commands
|
52
52
|
SMNT No --- Structure Mount
|
53
|
-
STAT
|
53
|
+
STAT Yes 0.5.0 Server status
|
54
54
|
STOR Yes 0.1.0 Store file
|
55
55
|
STOU Yes 0.2.2 Store with unique name
|
56
56
|
STRU Yes 0.1.0 Set file structure
|
@@ -100,10 +100,10 @@ Server-FTP send only correct reply format |4.1.2.11 |x| | | | | C
|
|
100
100
|
Server-FTP use defined reply code if poss. |4.1.2.11 | |x| | | | C
|
101
101
|
New reply code following Section 4.2 |4.1.2.11 | | |x| | | E
|
102
102
|
Default data port same IP addr as ctl conn |4.1.2.12 |x| | | | | C
|
103
|
-
Server-FTP handle Telnet options |4.1.2.12 |x| | | | |
|
103
|
+
Server-FTP handle Telnet options |4.1.2.12 |x| | | | | C
|
104
104
|
Handle "Experimental" directory cmds |4.1.3.1 | |x| | | | C
|
105
|
-
Idle timeout in server-FTP |4.1.3.2 | |x| | | |
|
106
|
-
Configurable idle timeout |4.1.3.2 | |x| | | |
|
105
|
+
Idle timeout in server-FTP |4.1.3.2 | |x| | | | C
|
106
|
+
Configurable idle timeout |4.1.3.2 | |x| | | | C
|
107
107
|
Receiver checkpoint data at Restart Marker |4.1.3.4 | |x| | | |
|
108
108
|
Sender assume 110 replies are synchronous |4.1.3.4 | | | | |x|
|
109
109
|
| | | | | | |
|
@@ -157,7 +157,7 @@ Support commands: | | | | | | |
|
|
157
157
|
LIST |4.1.2.13 |x| | | | | C
|
158
158
|
NLST |4.1.2.13 |x| | | | | C
|
159
159
|
SITE |4.1.2.8 | | |x| | | E
|
160
|
-
STAT |4.1.2.13 |x| | | | |
|
160
|
+
STAT |4.1.2.13 |x| | | | | C
|
161
161
|
SYST |4.1.2.13 |x| | | | | C
|
162
162
|
HELP |4.1.2.13 |x| | | | | C
|
163
163
|
NOOP |4.1.2.13 |x| | | | | C
|
@@ -230,7 +230,7 @@ attempts and third-party "proxy FTP" transfers, which can be used in
|
|
230
230
|
|
231
231
|
<pre>
|
232
232
|
FTP bounce protection
|
233
|
-
Restrict PASV/PORT to non-priv. ports
|
233
|
+
Restrict PASV/PORT to non-priv. ports Yes 0.5.0
|
234
234
|
Disconnect after so many wrong auths. No ---
|
235
235
|
Delay on invalid password No ---
|
236
236
|
Per-source IP limit No ---
|
data/examples/example.rb
CHANGED
@@ -15,11 +15,13 @@ module Example
|
|
15
15
|
|
16
16
|
attr_reader :account
|
17
17
|
attr_reader :auth_level
|
18
|
+
attr_reader :debug
|
18
19
|
attr_reader :eplf
|
19
20
|
attr_reader :interface
|
20
21
|
attr_reader :password
|
21
22
|
attr_reader :port
|
22
23
|
attr_reader :read_only
|
24
|
+
attr_reader :session_timeout
|
23
25
|
attr_reader :tls
|
24
26
|
attr_reader :user
|
25
27
|
|
@@ -31,6 +33,8 @@ module Example
|
|
31
33
|
@user = ENV['LOGNAME']
|
32
34
|
@password = ''
|
33
35
|
@account = ''
|
36
|
+
@session_timeout = default_session_timeout
|
37
|
+
@log = nil
|
34
38
|
op = option_parser
|
35
39
|
op.parse!(argv)
|
36
40
|
rescue OptionParser::ParseError => e
|
@@ -76,9 +80,20 @@ module Example
|
|
76
80
|
'defaults to empty string') do |t|
|
77
81
|
@account = t
|
78
82
|
end
|
83
|
+
op.on('--timeout SEC', Integer, 'Session idle timeout',
|
84
|
+
"defaults to #{default_session_timeout}") do |t|
|
85
|
+
@session_timeout = t
|
86
|
+
end
|
87
|
+
op.on('-d', '--debug', 'Write server debug log to stdout') do |t|
|
88
|
+
@debug = t
|
89
|
+
end
|
79
90
|
end
|
80
91
|
end
|
81
92
|
|
93
|
+
def default_session_timeout
|
94
|
+
Ftpd::FtpServer::DEFAULT_SESSION_TIMEOUT
|
95
|
+
end
|
96
|
+
|
82
97
|
end
|
83
98
|
end
|
84
99
|
|
@@ -157,6 +172,8 @@ module Example
|
|
157
172
|
@server.list_formatter = Ftpd::ListFormat::Eplf
|
158
173
|
end
|
159
174
|
@server.auth_level = auth_level
|
175
|
+
@server.session_timeout = @args.session_timeout
|
176
|
+
@server.log = make_log
|
160
177
|
@server.start
|
161
178
|
display_connection_info
|
162
179
|
create_connection_script
|
@@ -231,6 +248,10 @@ module Example
|
|
231
248
|
@args.account
|
232
249
|
end
|
233
250
|
|
251
|
+
def make_log
|
252
|
+
@args.debug && Logger.new($stdout)
|
253
|
+
end
|
254
|
+
|
234
255
|
end
|
235
256
|
end
|
236
257
|
|