ftpd 0.0.0.pre2 → 0.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ftpd might be problematic. Click here for more details.
- data/VERSION +1 -1
- data/examples/example.rb +4 -4
- data/features/concurrent_sessions.feature +11 -0
- data/features/delete.feature +0 -2
- data/features/step_definitions/client.rb +14 -0
- data/features/step_definitions/connect.rb +5 -11
- data/features/step_definitions/login.rb +9 -4
- data/features/step_definitions/noop.rb +7 -5
- data/features/support/test_client.rb +3 -4
- data/features/support/test_server.rb +3 -4
- data/features/syntax_errors.feature +1 -1
- data/ftpd.gemspec +4 -2
- data/lib/ftpd/ftp_server.rb +2 -2
- data/lib/ftpd/server.rb +11 -5
- data/lib/ftpd/temp_dir.rb +10 -50
- data/lib/ftpd/tls_server.rb +1 -1
- metadata +102 -56
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.1.pre
|
data/examples/example.rb
CHANGED
@@ -9,9 +9,9 @@ require 'ftpd'
|
|
9
9
|
class Example
|
10
10
|
|
11
11
|
def initialize
|
12
|
-
@data_dir =
|
12
|
+
@data_dir = TempDir.make
|
13
13
|
create_files
|
14
|
-
@server = Ftpd::FtpServer.new(@data_dir
|
14
|
+
@server = Ftpd::FtpServer.new(@data_dir)
|
15
15
|
set_credentials
|
16
16
|
display_connection_info
|
17
17
|
create_connection_script
|
@@ -31,7 +31,7 @@ class Example
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def create_file(path, contents)
|
34
|
-
full_path = File.expand_path(path, @data_dir
|
34
|
+
full_path = File.expand_path(path, @data_dir)
|
35
35
|
FileUtils.mkdir_p File.dirname(full_path)
|
36
36
|
File.open(full_path, 'w') do |file|
|
37
37
|
file.write contents
|
@@ -48,7 +48,7 @@ class Example
|
|
48
48
|
puts "Port: #{@server.port}"
|
49
49
|
puts "User: #{@server.user}"
|
50
50
|
puts "Pass: #{@server.password}"
|
51
|
-
puts "Directory: #{@data_dir
|
51
|
+
puts "Directory: #{@data_dir}"
|
52
52
|
puts "URI: ftp://#{HOST}:#{@server.port}"
|
53
53
|
end
|
54
54
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Mode
|
2
|
+
|
3
|
+
As a client
|
4
|
+
I want to start a session when there is another session
|
5
|
+
So that my session doesn't have to wait on the other
|
6
|
+
|
7
|
+
Scenario: Stream
|
8
|
+
Given a successful login
|
9
|
+
And the server has file "ascii_unix"
|
10
|
+
And the second client connects and logs in
|
11
|
+
Then the second client successfully does nothing
|
data/features/delete.feature
CHANGED
@@ -9,8 +9,6 @@ Feature: Delete
|
|
9
9
|
And the server has file "foo"
|
10
10
|
When the client successfully deletes "foo"
|
11
11
|
Then the server should not have file "foo"
|
12
|
-
And the client lists the directory
|
13
|
-
And the file list should not contain "foo"
|
14
12
|
|
15
13
|
Scenario: Missing path
|
16
14
|
Given a successful login
|
@@ -0,0 +1,14 @@
|
|
1
|
+
def client_variable_name(client_name)
|
2
|
+
var = '@' + [
|
3
|
+
client_name,
|
4
|
+
'client',
|
5
|
+
].compact.map(&:strip).join('_')
|
6
|
+
end
|
7
|
+
|
8
|
+
def set_client(client_name, client)
|
9
|
+
instance_variable_set client_variable_name(client_name), client
|
10
|
+
end
|
11
|
+
|
12
|
+
def client(client_name = nil)
|
13
|
+
instance_variable_get(client_variable_name(client_name))
|
14
|
+
end
|
@@ -1,19 +1,13 @@
|
|
1
1
|
require 'double_bag_ftps'
|
2
2
|
require 'net/ftp'
|
3
3
|
|
4
|
-
When /^the client connects( with TLS)?$/ do
|
5
|
-
|
6
|
-
|
4
|
+
When /^the( \w+)? client connects( with TLS)?$/ do
|
5
|
+
|client_name, with_tls|
|
6
|
+
client = TestClient.new(:tls => with_tls)
|
7
|
+
client.connect(@server.host, @server.port)
|
8
|
+
set_client client_name, client
|
7
9
|
end
|
8
10
|
|
9
11
|
After do
|
10
12
|
@client.close if @client
|
11
13
|
end
|
12
|
-
|
13
|
-
Then /^the connection is closed$/ do
|
14
|
-
@client.should be_closed
|
15
|
-
end
|
16
|
-
|
17
|
-
Then /^the connection is open$/ do
|
18
|
-
@client.should be_open
|
19
|
-
end
|
@@ -3,9 +3,9 @@ def logged_in?
|
|
3
3
|
@error.nil?
|
4
4
|
end
|
5
5
|
|
6
|
-
def login(user, password)
|
6
|
+
def login(user, password, client_name = nil)
|
7
7
|
capture_error do
|
8
|
-
|
8
|
+
client.login user, password
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -19,14 +19,19 @@ Given /^a successful login( with TLS)?$/ do |with_tls|
|
|
19
19
|
step 'the client logs in'
|
20
20
|
end
|
21
21
|
|
22
|
+
Given /^the( \w+)? client connects and logs in$/ do |client_name|
|
23
|
+
step "the#{client_name} client connects"
|
24
|
+
step "the#{client_name} client logs in"
|
25
|
+
end
|
26
|
+
|
22
27
|
Given /^a failed login$/ do
|
23
28
|
step 'the server is started'
|
24
29
|
step 'the client connects'
|
25
30
|
step 'the client logs in with a bad password'
|
26
31
|
end
|
27
32
|
|
28
|
-
When /^the client logs in$/ do
|
29
|
-
login @server.user, @server.password
|
33
|
+
When /^the( \w+)? client logs in$/ do |client_name|
|
34
|
+
login @server.user, @server.password, client_name
|
30
35
|
end
|
31
36
|
|
32
37
|
When /^the client logs in with a bad password$/ do
|
@@ -1,13 +1,15 @@
|
|
1
|
-
When /^the client successfully does nothing( with a parameter)?$/ do
|
1
|
+
When /^the( \w+)? client successfully does nothing( with a parameter)?$/ do
|
2
|
+
|client_name, with_param|
|
2
3
|
if with_param
|
3
|
-
|
4
|
+
client(client_name).raw 'NOOP', 'foo'
|
4
5
|
else
|
5
|
-
|
6
|
+
client(client_name).noop
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
|
-
When /^the client does nothing( with a parameter)?$/ do
|
10
|
+
When /^the( \w+)? client does nothing( with a parameter)?$/ do
|
11
|
+
|client_name, with_param|
|
10
12
|
capture_error do
|
11
|
-
step "the client successfully does nothing#{with_param}"
|
13
|
+
step "the#{client_name} client successfully does nothing#{with_param}"
|
12
14
|
end
|
13
15
|
end
|
@@ -7,14 +7,13 @@ class TestClient
|
|
7
7
|
include FileUtils
|
8
8
|
|
9
9
|
def initialize(opts = {})
|
10
|
-
@temp_dir =
|
10
|
+
@temp_dir = TempDir.make
|
11
11
|
@ftp = make_ftp(opts)
|
12
12
|
@templates = TestFileTemplates.new
|
13
13
|
end
|
14
14
|
|
15
15
|
def close
|
16
16
|
@ftp.close
|
17
|
-
@temp_dir.rm
|
18
17
|
end
|
19
18
|
|
20
19
|
def_delegators :@ftp,
|
@@ -32,7 +31,7 @@ class TestClient
|
|
32
31
|
:quit
|
33
32
|
|
34
33
|
def raw(*command)
|
35
|
-
@ftp.sendcmd
|
34
|
+
@ftp.sendcmd command.compact.join(' ')
|
36
35
|
end
|
37
36
|
|
38
37
|
def get(mode, remote_path)
|
@@ -66,7 +65,7 @@ class TestClient
|
|
66
65
|
end
|
67
66
|
|
68
67
|
def temp_path(path)
|
69
|
-
File.expand_path(path, @temp_dir
|
68
|
+
File.expand_path(path, @temp_dir)
|
70
69
|
end
|
71
70
|
|
72
71
|
def make_ftp(opts)
|
@@ -7,14 +7,13 @@ class TestServer
|
|
7
7
|
include FileUtils
|
8
8
|
|
9
9
|
def initialize
|
10
|
-
@temp_dir =
|
11
|
-
@server = Ftpd::FtpServer.new(@temp_dir
|
10
|
+
@temp_dir = TempDir.make
|
11
|
+
@server = Ftpd::FtpServer.new(@temp_dir)
|
12
12
|
@templates = TestFileTemplates.new
|
13
13
|
end
|
14
14
|
|
15
15
|
def close
|
16
16
|
@server.close
|
17
|
-
@temp_dir.rm
|
18
17
|
end
|
19
18
|
|
20
19
|
def host
|
@@ -46,7 +45,7 @@ class TestServer
|
|
46
45
|
private
|
47
46
|
|
48
47
|
def temp_path(path)
|
49
|
-
File.expand_path(path, @temp_dir
|
48
|
+
File.expand_path(path, @temp_dir)
|
50
49
|
end
|
51
50
|
|
52
51
|
end
|
data/ftpd.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "ftpd"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.1.pre"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Wayne Conrad"]
|
12
|
-
s.date = "2013-02-
|
12
|
+
s.date = "2013-02-11"
|
13
13
|
s.description = "ftpd is a pure Ruby FTP server library. It supports implicit and explicit TLS, suitlble for use by a program such as a test fixture or FTP daemon."
|
14
14
|
s.email = "wconrad@yagni.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"examples/example.rb",
|
27
27
|
"features/command_errors.feature",
|
28
|
+
"features/concurrent_sessions.feature",
|
28
29
|
"features/delete.feature",
|
29
30
|
"features/directory_navigation.feature",
|
30
31
|
"features/file_structure.feature",
|
@@ -37,6 +38,7 @@ Gem::Specification.new do |s|
|
|
37
38
|
"features/port.feature",
|
38
39
|
"features/put.feature",
|
39
40
|
"features/quit.feature",
|
41
|
+
"features/step_definitions/client.rb",
|
40
42
|
"features/step_definitions/client_and_server_files.rb",
|
41
43
|
"features/step_definitions/client_files.rb",
|
42
44
|
"features/step_definitions/command.rb",
|
data/lib/ftpd/ftp_server.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'openssl'
|
5
5
|
require 'pathname'
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require 'ftpd/tls_server'
|
7
|
+
require 'ftpd/temp_dir'
|
8
8
|
|
9
9
|
module Ftpd
|
10
10
|
class FtpServer < TlsServer
|
data/lib/ftpd/server.rb
CHANGED
@@ -39,11 +39,7 @@ module Ftpd
|
|
39
39
|
sleep(0.2)
|
40
40
|
retry
|
41
41
|
end
|
42
|
-
|
43
|
-
session(socket)
|
44
|
-
ensure
|
45
|
-
socket.close
|
46
|
-
end
|
42
|
+
start_session_thread socket
|
47
43
|
rescue IOError
|
48
44
|
break
|
49
45
|
end
|
@@ -51,6 +47,16 @@ module Ftpd
|
|
51
47
|
end
|
52
48
|
end
|
53
49
|
|
50
|
+
def start_session_thread(socket)
|
51
|
+
Thread.new do
|
52
|
+
begin
|
53
|
+
session(socket)
|
54
|
+
ensure
|
55
|
+
socket.close
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
54
60
|
def accept
|
55
61
|
@server_socket.accept
|
56
62
|
end
|
data/lib/ftpd/temp_dir.rb
CHANGED
@@ -1,56 +1,16 @@
|
|
1
|
-
require '
|
1
|
+
require 'fileutils'
|
2
|
+
require 'tmpdir'
|
2
3
|
|
3
|
-
module
|
4
|
-
class TempDir
|
4
|
+
module TempDir
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
temp_dir = TempDir.new(basename)
|
12
|
-
begin
|
13
|
-
yield(temp_dir)
|
14
|
-
ensure
|
15
|
-
temp_dir.rm unless temp_dir.kept
|
16
|
-
end
|
6
|
+
def make
|
7
|
+
Dir.mktmpdir.tap do |path|
|
8
|
+
at_exit do
|
9
|
+
FileUtils.rm_rf path
|
10
|
+
Dir.rmdir path if File.exists?(path)
|
17
11
|
end
|
18
|
-
|
19
12
|
end
|
20
|
-
|
21
|
-
attr_reader :kept
|
22
|
-
|
23
|
-
def initialize(basename = nil)
|
24
|
-
@path = unique_path(basename)
|
25
|
-
@kept = false
|
26
|
-
ObjectSpace.define_finalizer(self, TempDir.cleanup(path))
|
27
|
-
Dir.mkdir(@path)
|
28
|
-
end
|
29
|
-
|
30
|
-
def keep
|
31
|
-
@kept = true
|
32
|
-
ObjectSpace.undefine_finalizer(self)
|
33
|
-
end
|
34
|
-
|
35
|
-
def rm
|
36
|
-
keep
|
37
|
-
system("rm -rf #{path.inspect}")
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def unique_path(basename)
|
43
|
-
tempfile = Tempfile.new(File.basename(basename || $0 || ''))
|
44
|
-
path = tempfile.path
|
45
|
-
tempfile.close!
|
46
|
-
path
|
47
|
-
end
|
48
|
-
|
49
|
-
def TempDir.cleanup(path)
|
50
|
-
proc { |id|
|
51
|
-
system("/bin/rm -rf #{path.inspect}")
|
52
|
-
}
|
53
|
-
end
|
54
|
-
|
55
13
|
end
|
14
|
+
module_function :make
|
15
|
+
|
56
16
|
end
|
data/lib/ftpd/tls_server.rb
CHANGED
metadata
CHANGED
@@ -1,80 +1,113 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ftpd
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: -468842399
|
5
5
|
prerelease: 6
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
- pre
|
11
|
+
version: 0.0.1.pre
|
6
12
|
platform: ruby
|
7
|
-
authors:
|
13
|
+
authors:
|
8
14
|
- Wayne Conrad
|
9
15
|
autorequire:
|
10
16
|
bindir: bin
|
11
17
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
18
|
+
|
19
|
+
date: 2013-02-11 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
15
22
|
name: cucumber
|
16
|
-
|
23
|
+
prerelease: false
|
24
|
+
type: :development
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
26
|
none: false
|
18
|
-
requirements:
|
27
|
+
requirements:
|
19
28
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 29
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 2
|
34
|
+
- 1
|
21
35
|
version: 1.2.1
|
22
|
-
|
23
|
-
|
24
|
-
version_requirements: *70369190
|
25
|
-
- !ruby/object:Gem::Dependency
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
26
38
|
name: double-bag-ftps
|
27
|
-
|
39
|
+
prerelease: false
|
40
|
+
type: :development
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
42
|
none: false
|
29
|
-
requirements:
|
43
|
+
requirements:
|
30
44
|
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 27
|
47
|
+
segments:
|
48
|
+
- 0
|
49
|
+
- 1
|
50
|
+
- 0
|
32
51
|
version: 0.1.0
|
33
|
-
|
34
|
-
|
35
|
-
version_requirements: *70366630
|
36
|
-
- !ruby/object:Gem::Dependency
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
37
54
|
name: jeweler
|
38
|
-
|
55
|
+
prerelease: false
|
56
|
+
type: :development
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
58
|
none: false
|
40
|
-
requirements:
|
59
|
+
requirements:
|
41
60
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 63
|
63
|
+
segments:
|
64
|
+
- 1
|
65
|
+
- 8
|
66
|
+
- 4
|
43
67
|
version: 1.8.4
|
44
|
-
|
45
|
-
|
46
|
-
version_requirements: *70397920
|
47
|
-
- !ruby/object:Gem::Dependency
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
48
70
|
name: rake
|
49
|
-
|
71
|
+
prerelease: false
|
72
|
+
type: :development
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
74
|
none: false
|
51
|
-
requirements:
|
75
|
+
requirements:
|
52
76
|
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 73
|
79
|
+
segments:
|
80
|
+
- 10
|
81
|
+
- 0
|
82
|
+
- 3
|
54
83
|
version: 10.0.3
|
55
|
-
|
56
|
-
|
57
|
-
version_requirements: *70395740
|
58
|
-
- !ruby/object:Gem::Dependency
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
59
86
|
name: rspec
|
60
|
-
|
87
|
+
prerelease: false
|
88
|
+
type: :development
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
61
90
|
none: false
|
62
|
-
requirements:
|
91
|
+
requirements:
|
63
92
|
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 13
|
95
|
+
segments:
|
96
|
+
- 2
|
97
|
+
- 0
|
98
|
+
- 1
|
65
99
|
version: 2.0.1
|
66
|
-
|
67
|
-
|
68
|
-
version_requirements: *70395170
|
69
|
-
description: ftpd is a pure Ruby FTP server library. It supports implicit and explicit
|
70
|
-
TLS, suitlble for use by a program such as a test fixture or FTP daemon.
|
100
|
+
version_requirements: *id005
|
101
|
+
description: ftpd is a pure Ruby FTP server library. It supports implicit and explicit TLS, suitlble for use by a program such as a test fixture or FTP daemon.
|
71
102
|
email: wconrad@yagni.com
|
72
103
|
executables: []
|
104
|
+
|
73
105
|
extensions: []
|
74
|
-
|
106
|
+
|
107
|
+
extra_rdoc_files:
|
75
108
|
- LICENSE.md
|
76
109
|
- README.md
|
77
|
-
files:
|
110
|
+
files:
|
78
111
|
- Gemfile
|
79
112
|
- Gemfile.lock
|
80
113
|
- LICENSE.md
|
@@ -83,6 +116,7 @@ files:
|
|
83
116
|
- VERSION
|
84
117
|
- examples/example.rb
|
85
118
|
- features/command_errors.feature
|
119
|
+
- features/concurrent_sessions.feature
|
86
120
|
- features/delete.feature
|
87
121
|
- features/directory_navigation.feature
|
88
122
|
- features/file_structure.feature
|
@@ -95,6 +129,7 @@ files:
|
|
95
129
|
- features/port.feature
|
96
130
|
- features/put.feature
|
97
131
|
- features/quit.feature
|
132
|
+
- features/step_definitions/client.rb
|
98
133
|
- features/step_definitions/client_and_server_files.rb
|
99
134
|
- features/step_definitions/client_files.rb
|
100
135
|
- features/step_definitions/command.rb
|
@@ -136,28 +171,39 @@ files:
|
|
136
171
|
- rake_tasks/cucumber.rake
|
137
172
|
- rake_tasks/jeweler.rake
|
138
173
|
homepage: http://github.com/wconrad/ftpd
|
139
|
-
licenses:
|
174
|
+
licenses:
|
140
175
|
- MIT
|
141
176
|
post_install_message:
|
142
177
|
rdoc_options: []
|
143
|
-
|
178
|
+
|
179
|
+
require_paths:
|
144
180
|
- lib
|
145
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
182
|
none: false
|
147
|
-
requirements:
|
148
|
-
- -
|
149
|
-
- !ruby/object:Gem::Version
|
150
|
-
|
151
|
-
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
hash: 3
|
187
|
+
segments:
|
188
|
+
- 0
|
189
|
+
version: "0"
|
190
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
191
|
none: false
|
153
|
-
requirements:
|
154
|
-
- -
|
155
|
-
- !ruby/object:Gem::Version
|
192
|
+
requirements:
|
193
|
+
- - ">"
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
hash: 25
|
196
|
+
segments:
|
197
|
+
- 1
|
198
|
+
- 3
|
199
|
+
- 1
|
156
200
|
version: 1.3.1
|
157
201
|
requirements: []
|
202
|
+
|
158
203
|
rubyforge_project:
|
159
204
|
rubygems_version: 1.8.17
|
160
205
|
signing_key:
|
161
206
|
specification_version: 3
|
162
207
|
summary: Pure Ruby FTP server library
|
163
208
|
test_files: []
|
209
|
+
|