Обслуживание больших файлов через Nginx через Rails 2.3. Использование x-sendfile - PullRequest
11 голосов
/ 05 июня 2009

Допустим, у меня есть приложение Rails 2.3.2, запущенное nginx и обслуживаемое mongrel, в котором мне нужно обслуживать большой статический файл через Rails (для контроля доступа к нему). Я хочу, чтобы приложение Rails делегировало передачу файла в nginx, чтобы избежать блокировки экземпляра mongrel.

Доступная информация кажется противоречивой и неполной. Этот пост показывает, как это сделать с Apache, и намекает, что это также можно сделать с помощью ngninx, но без примеров. Этот пост и этот пост показывают, как это сделать с помощью плагина, который, по-видимому, Rails 2.3 делает ненужным. Этот пост предполагает, что, возможно, в конце концов не поддерживается x-sendfile с nginx.

Я бы предпочел не возиться с плагинами для вещей, которые Rails теперь может делать сам по себе.

Кто-нибудь получил поведение, подобное x-sendfile, для работы без плагинов и Rails 2.3 / nginx / mongrel? Если нет, то какая документация лучше всего подходит для работы с плагином (и / или monkeypatch) и Rails 2.3 / nginx / mongrel?

1 Ответ

24 голосов
/ 05 июня 2009

Основная идея: все, что делает ваш контроллер, это устанавливает заголовок nginx x-accel-redirect . Как только ваш метод контроллера вернется (что будет очень быстро), nginx будет проверять заголовок вашего набора Rails-приложений. Если установлен x-accel-redirect, то nginx обслуживает статический файл.

Ваш контроллер будет выглядеть примерно так:

def show  
  @attachment = Attachment.find(params[:id])  
  # Do anything else you need for authentication, etc. 

  head(:x_accel_redirect => '/files/' + @attachment.filename,  
   :content_type => @attachment.content_type,  
   :content_disposition => "attachment; filename=\"#{@attachment.filename}\"")  
end  

Одно это не поможет. Вам также нужно сообщить nginx о файлах, расположенных в $ RAILS_ROOT / files. Добавьте это в конец вашей конфигурации nginx внутри блока сервера:

location /files {
  root /path/to/rails_app;  
  internal;  
}

Поместите статический файл в $ RAILS_ROOT / files, и он должен работать. Нет необходимости в подключаемых модулях или обезьяньих патчах. Протестировано с Rails 2.3.2 и 2.3.14.

...