Rails загрузить файл на FTP-сервер
Я на Rails 2.3.5 и Ruby 1.8.6 и пытаюсь выяснить, как позволить пользователю загружать файл на FTP-сервер на другом компьютере через мое приложение Rails. Также мое приложение Rails будет размещено на Heroku, что не облегчает запись файлов в локальную файловую систему.
index.html.erb
<% form_tag '/ftp/upload', :method => :post, :multipart => true do %>
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
<%= submit_tag 'Upload' %>
<% end %>
ftp_controller.rb
require 'net/ftp'
class FtpController < ApplicationController
def upload
file = params[:file]
ftp = Net::FTP.new('remote-ftp-server')
ftp.login(user = "***", passwd = "***")
ftp.putbinaryfile(file.read, File.basename(file.original_filename))
ftp.quit()
end
def index
end
end
В настоящее время я просто пытаюсь заставить приложение Rails работать на моем ноутбуке с Windows. С приведенным выше кодом, я получаю эту ошибку
Errno::ENOENT in FtpController#upload
No such file or directory -.... followed by a dump of the file contents
Я пытаюсь загрузить файл CSV, если это имеет какое-либо значение. Кто-нибудь знает, что происходит?
2 ответа
После долгих исследований и изучения проблем я закончил читать исходный код метода putbinaryfile, чтобы найти обходной путь для ограничения putbinaryfile. Вот рабочий код, замените эту строку
ftp.putbinaryfile(file.read, File.basename(file.original_filename))
с
ftp.storbinary("STOR " + file.original_filename, StringIO.new(file.read), Net::FTP::DEFAULT_BLOCKSIZE)
И если вам интересно, STOR - это необработанная команда FTP, да, до этого дошло. Я довольно удивлен, что этот сценарий не так легко обрабатывается стандартными библиотеками Ruby, и, конечно, не было очевидно, что нужно сделать.
И если ваше приложение на Heroku, добавьте эту строку
ftp.passive = true
Настройка брандмауэра Heroku не разрешает активный режим FTP, также убедитесь, что ваш FTP-сервер поддерживает пассивный режим.
Сдается мне, что ftp.putbinaryfile просто хочет путь и имя файла в качестве первого параметра.