Подтвердить что ты не робот

Загрузка файлов 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, если это имеет значение. Кто-нибудь знает, что происходит?

4b9b3361

Ответ 1

После долгих исследований и ударов головой я закончил читать исходный код метода 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-сервер поддерживает пассивный режим.

Ответ 2

Мне кажется, что ftp.putbinaryfile просто хочет, чтобы путь и имя файла были первым параметром.