Created
July 22, 2011 19:14
-
-
Save bparker98/1100181 to your computer and use it in GitHub Desktop.
Patch to add :BindAddress, :ExternalAddress, and :Use220First to @options, and to fix an issue with the PORT command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From c0391fe1fbeee994daf4dd7263742e961a86c33e Mon Sep 17 00:00:00 2001 | |
From: Brandon Parker <[email protected]> | |
Date: Fri, 22 Jul 2011 13:09:26 -0600 | |
Subject: [PATCH] Added :BindAddress to @options to set the IP Address to bind the server to. Added :ExternalAddress to @options to be able to test PASV support with a firewall. Added :Use220First to @options to have the server return a 220 response instead of a 200 response upon connection to fix compatibility with some FTP clients. Fixed an issue with the PORT command that prevented Active connections from working properly. Changed socket.accept in start() to be non-blocking so the server can be shut down cleaner. | |
--- | |
lib/fake_ftp/server.rb | 51 ++++++++++++++++++++++++++++++++---------------- | |
1 files changed, 34 insertions(+), 17 deletions(-) | |
diff --git a/lib/fake_ftp/server.rb b/lib/fake_ftp/server.rb | |
index 29feafb..9b1ef13 100644 | |
--- a/lib/fake_ftp/server.rb | |
+++ b/lib/fake_ftp/server.rb | |
@@ -10,7 +10,8 @@ module FakeFtp | |
CMDS = %w[acct cwd cdup list nlst pass pasv port pwd quit stor retr type user] | |
LNBK = "\r\n" | |
- def initialize(control_port = 21, data_port = nil, options = {}) | |
+ def initialize(control_port = 21, data_port = nil, options = { :BindAddress => '127.0.0.1', :Use220First => false }) | |
+ | |
self.port = control_port | |
self.passive_port = data_port | |
raise(Errno::EADDRINUSE, "#{port}") if is_running? | |
@@ -19,6 +20,11 @@ module FakeFtp | |
@options = options | |
@files = [] | |
@mode = :active | |
+ @thread = nil | |
+ @client = nil | |
+ @server = nil | |
+ @started = false | |
+ @active_connection = nil | |
end | |
def files | |
@@ -35,17 +41,24 @@ module FakeFtp | |
def start | |
@started = true | |
- @server = ::TCPServer.new('127.0.0.1', port) | |
+ @server = ::TCPServer.new(@options[:BindAddress], port) | |
@thread = Thread.new do | |
- while @started | |
- @client = @server.accept | |
- respond_with('200 Can has FTP?') | |
- @connection = Thread.new(@client) do |socket| | |
- while @started && !socket.nil? && !socket.closed? | |
- respond_with parse(socket.gets) | |
+ while @started && [email protected]? && [email protected]? | |
+ begin | |
+ @client = @server.accept_nonblock | |
+ if @options[:Use220First] | |
+ respond_with('220 FakeFtp') | |
+ else | |
+ respond_with('200 Can has FTP?') | |
end | |
- @client.close | |
- @client = nil | |
+ @connection = Thread.new(@client) do |socket| | |
+ while @started && !socket.nil? && !socket.closed? | |
+ respond_with parse(socket.gets) | |
+ end | |
+ socket.close unless socket.closed? | |
+ socket = nil | |
+ end | |
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR | |
end | |
end | |
@server.close | |
@@ -53,17 +66,16 @@ module FakeFtp | |
end | |
if passive_port | |
- @data_server = ::TCPServer.new('127.0.0.1', passive_port) | |
+ @data_server = ::TCPServer.new(@options[:BindAddress], passive_port) | |
end | |
end | |
def stop | |
@started = false | |
- @client.close if @client | |
- @server.close if @server | |
- @server = nil | |
+ @thread.join() | |
+ @client.close if @client != nil and [email protected]? | |
+ @server.close if @server != nil and [email protected]? | |
@data_server.close if @data_server | |
- @data_server = nil | |
end | |
def is_running?(tcp_port = nil) | |
@@ -142,7 +154,11 @@ module FakeFtp | |
@mode = :passive | |
p1 = (passive_port / 256).to_i | |
p2 = passive_port % 256 | |
- "227 Entering Passive Mode (127,0,0,1,#{p1},#{p2})" | |
+ if @options.has_key? :ExternalAddress | |
+ "227 Entering Passive Mode (#{@options[:ExternalAddress].gsub(".", ",")},#{p1},#{p2})" | |
+ else | |
+ "227 Entering Passive Mode (#{@options[:BindAddress].gsub(".", ",")},#{p1},#{p2})" | |
+ end | |
else | |
'502 Aww hell no, use Active' | |
end | |
@@ -156,7 +172,8 @@ module FakeFtp | |
@active_connection = nil | |
end | |
@mode = :active | |
- @active_connection = ::TCPSocket.open('127.0.0.1', remote_port) | |
+ addr = "#{remote[0]}.#{remote[1]}.#{remote[2]}.#{remote[3]}" | |
+ @active_connection = ::TCPSocket.open(addr, remote_port) | |
'200 Okay' | |
end | |
-- | |
1.7.4.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment