Limitar la velocidad de las descargas con PHP

Limitar la velocidad de las descargas con PHP.

Es algo común que si tenemos un sitio web de alguna temática especifica,  ofrezcamos algún tipo de descarga en nuestra web, manuales, archivos, scripts, etc…

Como norma general y por comodidad los solemos alojar en nuestro propio sitio o en algún hosting gratuito.

Pero debes saber que con esta practica corres un grave riesgo, y es que si la descarga tiene una gran aceptación y se empieza a descargar de forma masiva, lo normal es que el hosting gratuito te mande a paseo, o si es en nuestro propio sitio se consuman demasiados recursos y tu web este cada dos por tres caída.

Si tienes una gran web lo lógico es un server exclusivo.

Pero si no es tu caso y para no tener estos problemas tenemos un script php con el cual podemos modificar los parámetros en tiempo y ejecución, de forma que sea posible limitar la velocidad de las descargas.

Lo vemos…

Limitar la velocidad de las descargas con PHP 1

 

Limitar la velocidad de las descargas con PHP

< ?php
function enviar_archivo($archivo, $speed = 100) {
// Vemos si existe el fichero ?
    if (!is_file($archivo)) {
        die("<b>404 Archivo no encontrado");
    }
// Info del archivo
    $archivo_nombre = basename($archivo);
    $archivo_extension = strtolower(substr(strrchr($archivo_nombre,"."),1));
// Asignamos Content-Type a cada tipo de archivo, puedes añadir
    switch($archivo_extension) {
        case "exe":
            $ctype="application/octet-stream";
            break;
        case "zip":
            $ctype="application/zip";
            break;
        case "lit":
            $ctype="application/lit";
            break;
        case "pdf":
            $ctype="application/pdf";
            break;
        case "mp3":
            $ctype="audio/mpeg3";
            break;
        case "htm":
        case "html":
            $ctype="text/html";
            break;
        case "txt":
            $ctype="text/plain";
            break;
// Bloqueamos archivos .php, .inc, etc...
        case "php":
        case "inc":
            die("<b>Archivo no permitido ". $archivo_extension ."</b>");
            break;
        default:
            $ctype="application/force-download";
    }
// Headers
    header("Cache-Control:");
    header("Cache-Control: public");
    header("Content-Type: $ctype");
// Estetica, si tenemos guiones bajos( _ ) modificamos por legible
// Ejemplo: "script_bash.zip" se transforma en "script bash.zip"
    $archivo_nombre_limpio = str_replace("_", " ", $archivo_nombre);
// Forzar descarga en vez de abrir archivo
    $header='Content-Disposition: attachment; filename='.$archivo_nombre_limpio;
    header($header);
    header("Accept-Ranges: bytes");
    $tamano = filesize($archivo);



// Si el navegador nos solicita el http_range (si tienes problemas anula esta seccion)
    if(isset($_SERVER['HTTP_RANGE'])) {
// enviamos el resume
        list($a, $rango)=explode("=",$_SERVER['HTTP_RANGE']);
        str_replace($rango, "-", $rango);
        $tamano2=$tamano-1;
        $nueva_longitud=$tamano2-$rango;
        header("HTTP/1.1 206 Partial Content");
        header("Content-Length: $nueva_longitud");
        header("Content-Range: bytes $rango$tamano2/$tamano");
    } else {
// enviar completo
        $tamano2=$tamano-1;
        header("Content-Range: bytes 0-$tamano2/$tamano");
        header("Content-Length: ".$tamano2);
    }
// Abrir el archivo
    $puntero_al_fichero = fopen("$archivo","rb");
// localizar el inicio de lo que queremos enviar
    fseek($puntero_al_fichero,$posicion_inicio);
// Comenzamos a enviar, leemos el tamaño del archivo y enviamos
    while(!feof($puntero_al_fichero)) {
// Ajusta para no caer en timeout
        set_time_limit(0);
// Datos en el buffer
        print(fread($puntero_al_fichero,1024*$speed));
// Se lanza el contenido del buffer
        flush();
// Configura el retraso
        sleep(1);
    }
// Proceso completado, archivo descargado correctamente
    fclose($puntero_al_fichero);
    exit;
}
// Ejemplo de uso de la funcion
enviar_archivo("fichero.pdf",100);
?>

 

Espero te resulte de utilidad.

Agregar comentario