Forum: NGINX X-accel-redirect serving html download page instead of file.

Posted by wideawake (Guest)
on 2012-08-28 03:30
(Received via mailing list)
I have a script that uses x-accel-redirect on a nginx server to send 
large
files (150mb+). The script serves downloads fine as long as their is a 
space
in the name of the directory but not when the directory is a single 
word.
Anyone know why it would be doing so when the file exists and the path 
is
correct?

Layout: /Dir/file.exe /Dir2/file.exe /Another Dir/file.exe

If it's /Another Dir/file.exe it serves the file perfectly, however if 
its
/Dir/file.exe it serves the html of the download page. Anyone seen this
before?

nginx config:
server {
  access_log  logs/access_log;
  access_log  on;
  limit_conn  gulag 3;
  error_log  /var/log/nginx/vhost-error_log crit;
  listen    80 default;
  server_name  www.my.com my.com;
  root   /home/mysite/public_html;
  #root /usr/share/nginx/html;
  autoindex off;
  index  index.php index.html index.htm;



  #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.zip$
/download.php?model=$1&file=$2.zip last;
  #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.exe$
/download.php?model=$1&file=$2.exe last;
  #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.nbh$
/download.php?model=$1&file=$2.nbh last;
  #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.rar$
/download.php?model=$1&file=$2.rar last;

  error_page 503 /503.html;
  location = /503.html {
  root /home/mysite/public_html/errors;
  }


  error_page 504 /504.html;
  location = /504.html {
  root /home/mysite/public_html/errors;
  }


  # pass the PHP scripts to FastCGI server
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:8888;
       #fastcgi_pass    unix:/var/run/nginx-fcgi.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME
/home/mysite/public_html$fastcgi_script_name;
            include        /etc/nginx/fastcgi_params;

       fastcgi_intercept_errors off;
        }


 }

php code:
<?php
/*File Download Script*/
$fileserver_path = "./shipped/";  // change this to the directory your 
files
reside
$fileurlpath = "http://my.com/shipped/";
$req_file      = basename($_GET['file']);
$model       = $_GET['model'];
$thisfile       = basename(__FILE__);
$msg="";
$error=FALSE;

$path = $model."/".$req_file;


if (empty($req_file)) {
  $error=TRUE;
  $msg .= "Usage: $thisfile?model=&lt;model
name&gt;&amp;file=&lt;file_to_download&gt;<br />";
}

if (! isset($_GET["model"])) {
  $error=TRUE;
  $msg .= "No Model information present. Unable to continue.<br />";
} else {
  $fileserver_path .= $model."/";
  $fileurlpath .= $model."/";
  /* check if file exists */
  if (!file_exists($fileserver_path.$req_file)) {
    $error=TRUE;
    $msg .= "$req_file doesn't exist.";
  }
}

/* no web spamming */
if (!preg_match("/^[a-zA-Z0-9._-]+$/", $req_file, $matches)) {
  $error=TRUE;
  $msg .= "Spamming! I can't do that. Sorry.";
}

if(! ($error)) {
//Hotlink Code
if(eregi($_SERVER["HTTP_HOST"], str_replace("www.", "",
strtolower($_SERVER["HTTP_REFERER"]))))
{
  if (! isset($_GET['send_file'])) {

    Header("Refresh: 5;
url=http://my.com/$thisfile?model=$model&file=$req_fil...

  }
  else {

    header("Cache-Control: public");
    header('Content-Description: File Transfer');
    header("Content-type: application/octet-stream");
    //header('Content-Type: application/force-download');
    //header('Content-Length: ' . filesize($fileserver_path.$req_file));
    header('Content-Disposition: attachment; filename=' . $req_file);
    header("Content-Transfer-Encoding: binary");
    header("X-Accel-Redirect: /shipped/" . $path);

    exit;

  }
//More Hotlink Code
 } else {
  Header("Refresh: ;
url=http://my.com/$thisfile?model=$model&file=$req_fil...
 }
//End Hotlink
}
?>

Posted at Nginx Forum: 
http://forum.nginx.org/read.php?2,230161,230161#msg-230161
Posted by Justin Dorfman (Guest)
on 2012-08-28 03:56
(Received via mailing list)
Hey,

Try adding this to your nginx conf where applicable:

add_header Content-Disposition attachment;

Regards,

Justin Dorfman <http://www.twitter.com/jdorfman>

NetDNA <http://www.netdna.com>
The Science of Acceleration
Posted by wideawake (Guest)
on 2012-08-28 04:05
(Received via mailing list)
I tried adding what you suggested like so

location = /shipped {
  add_header Content-Disposition attachment;
  root /home/mysite/public_html/shipped;
  internal;
  }

and by just adding the line to the site config. Neither of which worked
unfortunately.

Posted at Nginx Forum: 
http://forum.nginx.org/read.php?2,230161,230163#msg-230163
Posted by Justin Dorfman (Guest)
on 2012-08-28 04:31
(Received via mailing list)
I checked my configs and add_header is after the root directive like so:

location = /shipped {
        root /home/mysite/public_html/shipped;
        internal;
        add_header Content-Disposition attachment;
        }

Not sure if order matters or if it should be above or below the internal
directive.  I know Maxim and Piotr S. will know ;)

Regards,

Justin Dorfman <http://www.twitter.com/jdorfman>

NetDNA <http://www.netdna.com>
The Science of Acceleration
Posted by wideawake (Guest)
on 2012-08-28 05:02
(Received via mailing list)
I noticed that if I use this in my config then shipped/Dir 1/file.exe
returns file not found in browser and shipped/dir/file.exe still returns
proper file extension (exe, etc) but contains the html content of the
download page.

location = /files {
root /home/mysite/public_html/shipped;
internal;
add_header Content-Disposition attachment;
}

header("X-Accel-Redirect: /files/" . $path);

While removing that and using "header("X-Accel-Redirect: /shipped/" .
$path);" the actual file location works for shipped/Dir 1/file.exe but 
not
for shipped/dir/file.exe.

I'm at a lose as to why it's not working properly.

Posted at Nginx Forum: 
http://forum.nginx.org/read.php?2,230161,230165#msg-230165
Posted by Maxim Dounin (Guest)
on 2012-09-03 20:31
(Received via mailing list)
Hello!

On Mon, Aug 27, 2012 at 09:29:47PM -0400, wideawake wrote:

> before?
I would suggest that the reason is that rewrites which are
commented out in the config you've posted:

>   #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.zip$
> /download.php?model=$1&file=$2.zip last;
>   #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.exe$
> /download.php?model=$1&file=$2.exe last;
>   #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.nbh$
> /download.php?model=$1&file=$2.nbh last;
>   #rewrite ^.*/([-\w\.]+)/([-\w\.]+)\.rar$
> /download.php?model=$1&file=$2.rar last;

aren't really commented out.  And any X-Accel-Redirect results in
rewrite match, and a download.php output being returned instead.
Obvious solution would be to actually comment them out (or, if
they are needed, to place them into a location which doesn't match
URIs returned in X-Accel-Redirect).

(Files/directories with space work as regular expressions above
doesn't match them.)

Maxim Dounin
Posted by poulphunter (Guest)
on 2012-12-04 15:08
(Received via mailing list)
I've correct this bug adding an expire header like :

location ^~ /protected-file/ {
    expires       30s;
    add_header Pragma public;
    add_header Cache-Control "public, must-revalidate, 
proxy-revalidate";
    gzip off;
    internal;
    alias /;
  }

And my PHP headers are :

header("X-Accel-Redirect: /protected-file".realpath($realpath));
header("X-Accel-Buffering: yes");
header('Content-Length: '.$size);
header("Content-Type: ");
header('Content-Disposition: attachment; filename="'.$filename.'"');

Nginx MIME types are /etc/nginx/mime.conf (from normal config)

Posted at Nginx Forum: 
http://forum.nginx.org/read.php?2,230161,233566#msg-233566
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.