maricris-sn
9/18/2015 - 4:30 AM

uploading a file in ruby is hard. ftp is hard.

uploading a file in ruby is hard. ftp is hard.

# fireway configured with: http://major.io/2007/07/01/active-ftp-connections-through-iptables/

require 'net/ftp'
require 'stringio'

# allows us to upload files by content instead of writing to disk first
class Net::FTP
  def puttextcontent(content, remotefile, &block)
    f = StringIO.new(content)
    begin
      storlines("STOR " + remotefile, f, &block)
    ensure
      f.close
    end
  end
end
  
def upload_data_buffer(data_buffer)
    ftp = Net::FTP.new
    remotefile = "data-#{Time.now.strftime("%F")}.txt"
    upload_status = false
    begin
      ftp.debug_mode = true
      ftp.passive = true
      ftp.connect(ftp_host)
      STDERR.puts "FTP connection established"
      ftp.login(ftp_user, ftp_pass)
      STDERR.puts "FTP login access granted"
      ftp.chdir(ftp_dir)
      list = ftp.list
      STDERR.puts "FTP changed folder to: #{ftp_dir} -> #{list.inspect}\n"
      ret = ftp.puttextcontent(data_buffer.read, remotefile)
      STDERR.puts "FTP databuffer: #{ret.inspect} -> #{remotefile} -> #{ftp.last_response}"
      upload_status = true
    rescue => e
      STDERR.puts("FTP Error: #{self.id}: #{e.message}\n#{e.backtrace.join("\n")} -> #{e.inspect}")
      Rails.logger.error("FTP Error: #{self.id}: #{e.message}\n#{e.backtrace.join("\n")}")
    ensure
      ftp.close
    end
    STDERR.puts "FTP upload status: #{upload_status}"
    upload_status
end

upload_data_buffer(StringIO.new("this is my fun test file data"))
connect: ftp.example.com, 21
get: 220 Service ready for new user.
put: USER ftp@user.example.com
get: 331 User name okay, need password for ftp@user.example.com.
put: PASS ***************
get: 230 User logged in, proceed.
put: TYPE I
get: 200 Command TYPE okay.
put: CWD /test/revenue-example
get: 250 Directory changed to /test/revenue-example
put: TYPE A
get: 200 Command TYPE okay.
put: PASV
get: 227 Entering Passive Mode (69,194,129,30,211,144)
put: LIST
get: 150 File status okay; about to open data connection.
get: 226 Closing data connection.
put: TYPE I
get: 200 Command TYPE okay.
put: TYPE A
get: 200 Command TYPE okay.
put: PASV
get: 227 Entering Passive Mode (69,194,129,30,211,146)
put: STOR data-2014-04-02.txt
get: 150 File status okay; about to open data connection.
get: 551 /test/revenue-example/data-2014-04-02.txt: Error on output file.
put: TYPE I
get: 200 Command TYPE okay.
ruby stack trace:

/usr/local/lib/ruby/2.1.0/net/ftp.rb:327:in `getresp'
/usr/local/lib/ruby/2.1.0/net/ftp.rb:339:in `voidresp'
/usr/local/lib/ruby/2.1.0/net/ftp.rb:584:in `block (2 levels) in storlines'
/usr/local/lib/ruby/2.1.0/net/ftp.rb:199:in `with_binary'
/usr/local/lib/ruby/2.1.0/net/ftp.rb:572:in `block in storlines'
/usr/local/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
/usr/local/lib/ruby/2.1.0/net/ftp.rb:571:in `storlines'