Esto iría en PHP, pero ya que está aquí respondo. Este es un código que ideé hace unos años. Es un archivo php que solo permite descargar si se pasan una serie de parámetros por $_POST tales como el nombre de archivo, la extensión y tal. Como la página nunca carga (dado que no es una página) no se ven los datos del _POST, simplemente la descarga:
Código PHP:
<?php
//Convierte el archivo en pedazos.
function readfile_chunked($filename,$retbytes=true) {
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$cnt =0;
// $handle = fopen($filename, 'rb');
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
//Según la extensión es un archivo u otro
if (isset($_POST['ext'])){ //Si hay datos en _POST
switch($_POST['ext']){
case "pdf": $ctype="application/pdf"; break;
//case "exe": $ctype="application/octet-stream"; break;
// case "zip": $ctype="application/zip"; break;
// case "doc": $ctype="application/msword"; break;
// case "xls": $ctype="application/vnd.ms-excel"; break;
// case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
// case "gif": $ctype="image/gif"; break;
// case "png": $ctype="image/png"; break;
// case "jpe": case "jpeg": case "jpg": $ctype="image/jpg"; break;
// case ".db": case "db": case "php": exit('No se permite la descarga de archivos de ese tipo'); break;
default: $ctype="application/force-download"; //Tu solo quieres este así que te puse el resto como notas.
}
//Begin writing headers
header("Pragma: no-cache"); //No se guarda en caché
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); //Fecha pasada, en el caso de que se guarde en algún sitio, se borraría enseguida
header("Content-Description: File Transfer");
header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
//Use the switch-generated Content-Type
header('Content-Type: '.$ctype);
//Force the download
print $_POST['res'];
$header = 'Content-Disposition: attachment; filename="'.$_POST['filename'].'"';
header($header);//Aquí tienes que $_POST['filename'] contiene el nombre de archivo a descargar, no la ruta. La ruta se extrae de una base de datos según una ID.
//También puedes probar a buscar un sistema de claves temporales para que no se pueda reutilizar más tarde
//y para mayor seguridad las claves evitan que alguien use algún script nocivo.
header("Content-Transfer-Encoding: binary");
$link = mysql_connect ("tu mysql server", "mysql user", "mysqlpass");//cambia las cosas aquí
mysql_select_db("mysql db"); // cambia las cosas aquí.
//Las consultas a las bases de datos van aquí:
//Ya acabaron. en $url has de guardar la ruta. Tiene que ser una ruta relativa o si no desde la raíz de tu web, nunca desde el http://.
$len = @filesize($url);
header("Content-Length: $len");
set_time_limit(0);
readfile_chunked($url) or die("File not found.");//Esto manda un error si no existe el archivo.
mysql_close ($link); // cierra la conexión
}else{ // Si no hay datos en _Post
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.tupagina.com"); //Aquí el nombre de tu página.
}
?>