Обслуживание больших файлов через Nginx через Rails 2.3 Использование x-sendfile

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

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

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

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

Ответ 1

Основная идея: все, что делает ваш контроллер, это установить заголовок 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/файлах. Добавьте это в конец вашей конфигурации nginx внутри блока сервера:

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

Поместите статический файл в файл $RAILS_ROOT/, и он должен работать. Нет необходимости в плагинах или monkeypatching. Протестировано с Rails 2.3.2 и 2.3.14.