Problem using X-Accel-Redirect in nginx under ssl

Hi everybody.

I have a problem using X-Accel-Redirect under ssl in nginx for serving
static image-files that I want to protect from unauthorized downloads.
The problem is that the images downloading is extremely slow, and a
timeout occurs before the
whole image is being downloaded to the browser.

I read that the way protect certain static files (like images) from
being
exposed to the public (so for example, only logged-in users will be
permitted to download
the images) in nginx is to use X-Accel-Redirect response header in
combination
with ‘internal’ location configuration. (http://wiki.codemongers.com/
NginxXSendfile)

I want urls like https://mydomain.com/item-images/some_image.jpg
to be mapped to the ImagesController#download_image action in which
the user authorization
to download the file will be checked.

That’s what I did:

###In config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.connect ‘item_images/:image_path’,
:controller => ‘images’,
:action => ‘download_image’,
:image_path => /.+/
.
.
.
end

In app/controllers/images_controller.rb

class ImagesController < ApplicationController

def download_image

# Some checking in here - suppose the user is authorized to

download the file
# I want nginx to serve the file.

# I know - params[:image_path] should be sanitized...
response.headers["X-Accel-Redirect"] = "/item-images/

#{params[:image_path]}"
render :nothing => true
end

end

In nginx.conf

server {
# port to listen on. Can also be set to an IP:PORT
listen 443;

ssl                  on;
ssl_certificate      /path-to/ssl.crt/ssl_cert.crt;
ssl_certificate_key  /path-to/ssl.key/ssl_cert_key.key;

ssl_session_timeout  5m;

keepalive_timeout    70;

# Set the max size for file uploads to 50Mb
client_max_body_size 150M;

# sets the domain[s] that this vhost server requests for
server_name mydomain.com anotherdomain.com;

# doc root
root html;

# vhost specific access log
access_log  /usr/local/nginx/logs/nginx.vhost.access.log  main;

# this rewrites all the requests to the maintenance.html
# page if it exists in the doc root. This is for capistrano's
# disable web task
if (-f $document_root/system/maintenance.html) {
  rewrite  ^(.*)$  /system/maintenance.html last;
  break;
}

THIS IS THE INTERNAL LOCATION REFERED TO BY X-Accel-Redirect

location /item-images/ {
# The protected images directory is /var/www/rails/item-images
root /var/www/rails/;
internal;
}

location / {
.
.
.
# Proxing to mongrel the ‘usuall’ way (http://brainspl.at/articles/
2007/01/03/new-nginx-conf-with-optimizations)
}
}

As mentioned this works So slowly, that a timeout occurs.
However if I do not use ssl, or if I just put the images under public
directory
it seems to be ok (also under ssl).

I use rhel4 + nginx 0.5.30 .

Thanks for your kind help

Nadav

Hi everybody.
I wote my question again, with better line-breaks…

I have a problem using X-Accel-Redirect under ssl in nginx for
serving
static image-files that I want to protect from unauthorized
downloads.
The problem is that the images downloading is extremely slow, and a
timeout occurs before the whole image is being downloaded to the
browser.

I read that the way protect certain static files
(like images) from being exposed to the public
(so for example, only logged-in users will be permitted to download
the images) in nginx is to use X-Accel-Redirect response header in
combination with ‘internal’ location configuration.
(http://wiki.codemongers.com/NginxXSendfile)

I want urls like https://mydomain.com/item_images/some_image.jpg
to be mapped to the ImagesController#download_image action in which
the user authorization to download the file will be checked.

That’s what I did:

###In config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.connect ‘item_images/:image_path’,
:controller => ‘images’,
:action => ‘download_image’,
:image_path => /.+/
.
.
.
end

In app/controllers/images_controller.rb

class ImagesController < ApplicationController

def download_image

# Some checking in here - suppose the user is
# authorized to download the file
# I want nginx to serve the file.


# I know - params[:image_path] should be sanitized...
response.headers["X-Accel-Redirect"] = "/item-images/

#{params[:image_path]}"
render :nothing => true
end

end

In nginx.conf

server {
# port to listen on. Can also be set to an IP:PORT
listen 443;

ssl                  on;
ssl_certificate      /path-to/ssl.crt/ssl_cert.crt;
ssl_certificate_key  /path-to/ssl.key/ssl_cert_key.key;


ssl_session_timeout  5m;


keepalive_timeout    70;


# Set the max size for file uploads to 50Mb
client_max_body_size 150M;


# sets the domain[s] that this vhost server requests for
server_name mydomain.com anotherdomain.com;


# doc root
root html;


# vhost specific access log
access_log  /usr/local/nginx/logs/nginx.vhost.access.log  main;


# this rewrites all the requests to the maintenance.html
# page if it exists in the doc root. This is for capistrano's
# disable web task
if (-f $document_root/system/maintenance.html) {
  rewrite  ^(.*)$  /system/maintenance.html last;
  break;
}

THIS IS THE INTERNAL LOCATION REFERED TO BY X-Accel-Redirect

location /item-images/ {
# The protected images directory is /var/www/rails/item-images
root /var/www/rails/;
internal;
}

location / {
.
.
.
# Proxing to mongrel the ‘usuall’ way
# (http://brainspl.at/articles/2007/01/03/new-nginx-conf-with-
optimizations)
}

}

As mentioned this works So slowly, that a timeout occurs.
However if I do not use ssl, or if I just put the images under public
directory
it seems to be ok (also under ssl).

I use rhel4 + nginx 0.5.30 .

Thanks for your kind help

Nadav