Bonjour,
Le voici, en intégralité. Les seuls changements sont les remplacement par xxxxxxxxx des infos sensibles.
Petite explication sur le fonctionnement :
Ce script sert à télécharger de très gros fichiers (de 1,5 à 8 Go) par blocs de 10 Mo via des requêtes HTTP "RANGE" émises par une applet Java. Pour chaque téléchargement elle émet :
- 1 requête avec le paramètre 't' pour vérifier la présence du fichier et récupérer sa taille
- 1 requête avec le paramètre 'i' pour initialiser le téléchargement et récupérer le n° de session
- autant que requêtes "RANGE" que le blocs de 10Mo dans le fichier
- 1 requête avec le paramètre 'x' pour terminer le téléchargement et clôturer la session
le paramètres "f" contient toujours le chemin du fichier à télécharger,
le paramètre "s" contient le numéro de session alloué par la commande "i"
La BDD contient 2 tables :
- zp_dl contient la liste des IP entrain de télécharger
- zp_stats contient la liste des fichiers téléchargés avec l'heure de dernier accès et le volume déjà téléchargé.
<?php
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
{ $LNG = StrToUpper(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],0,2));
if ($LNG != 'FR')
$LNG = 'EN';
}
else
$LNG = 'EN';
//Interdit appel depuis un navigateur autre que le downloadeur ou sans nom de fichier
if (!isset($_GET['f']) || !isset($_SERVER['HTTP_USER_AGENT']) || ($_SERVER['HTTP_USER_AGENT'] != 'xxxxxxxx'))
{ header("HTTP/1.1 403 Forbidden");
$Titre = 'Erreur';
$InHead = ' <style>.erreur {font-size:16px; text-align:center; color:red; font-weight:bold}</style>'."\n";
require 'menu.php';
echo '<p class="TitrePage">'.(($LNG='FR') ? 'Erreur !' : 'Error!').'</p>';
echo '<p class="erreur">'.(($LNG='FR') ? 'Page invalide !' : 'Invalid page!').'</p>'."\n";
echo "</body>\n</html>\n";
exit;
}
$fich = 'fichiers/'.stripslashes($_GET['f']);
if (!file_exists($fich))
{ header("HTTP/1.1 404 Not Found");
exit;
}
//Demande de taille du fichier
$taille = filesize($fich);
if (isset($_GET['t']))
{ echo $taille;
exit;
}
//Connexion à la BDD indispensable pour la suite
$sql_host = "xxxxxxxx";
$sql_base = "xxxxxxxx";
$sql_user = "xxxxxxxx";
$sql_pwd = "xxxxxxxx";
if ((mysql_connect($sql_host, $sql_user, $sql_pwd) == false) || (mysql_select_db($sql_base) == false))
{ //La base de donné n'est pas joignable
header("HTTP/1.1 500 Internal Server Error");
exit;
}
$Attente = 30*60; //30 minutes avant annulation d'un téléchargement avorté sans prévenir
$Temps = time(); //temps au moment de la demande
$ip = addslashes($_SERVER['REMOTE_ADDR']);
//Demande d'ID de session (inscription de début de téléchargement)
if (isset($_GET['i']))
{ //inscrit le fichier en téléchargement
$fichprot = mysql_real_escape_string($fich);
mysql_query("INSERT zp_stats SET fichier='$fichprot', ip='$ip', debut=FROM_UNIXTIME($Temps), fin=0, taille=0");
$id_stat = mysql_insert_id();
//Inscrit l'IP téléchargeant
mysql_query("INSERT zp_dl VALUES('$ip', FROM_UNIXTIME($Temps), $id_stat) ON DUPLICATE KEY UPDATE debut=FROM_UNIXTIME($Temps)");
echo $id_stat;
exit;
}
//Signale fin de téléchargement
if (isset($_GET['x']))
{ mysql_query("DELETE FROM zp_dl WHERE ip='$ip'");
echo '1';
exit;
}
//Vérifie si demande valide
$res = mysql_query("SELECT UNIX_TIMESTAMP(debut),session FROM zp_dl WHERE ip='$ip'");
if ((mysql_num_rows($res) == 0) || !isset($_GET['s']))
{ header("HTTP/1.1 417 Expectation failed");
exit;
}
else
{ //L'IP est dans la table -> elle télécharge déjà (mais a pu abandonner)
$enreg = mysql_fetch_row($res);
$Delai = $Attente + $enreg[0] - time(); //Délai restant à attendre
$id_stat = $enreg[1];
if (($id_stat != $_GET['s']) && ($Delai > 0))
{ header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Status: 503 Service Temporarily Unavailable');
header('Retry-After: '.$Delai);
exit;
}
}
//Pour le téléchargement, n'accepte que des demandes portant sur des tailles de moins de 20 Mo.
if (!isset($_SERVER['HTTP_RANGE']))
{ header("HTTP/1.1 405 Method Not Allowed");
exit;
}
//=== Téléchargement autorisé
$datefich = date('r', filemtime($fich));
$nomfich = (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE") == false) ? basename($fich) : urlencode(basename($fich));
$TailleFich = filesize($fich);
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $plage);
$premier = intval($plage[1]);
$dernier = intval($plage[2]);
if ($dernier+1 == $TailleFich)
{ //Indque téléchargement fini pour cet utilisateur et dans les stats
mysql_query("UPDATE zp_stats SET fin=FROM_UNIXTIME($Temps), taille=-1 WHERE id=$id_stat");
mysql_query("DELETE FROM zp_dl WHERE ip='$ip'");
}
else
{ //Met à jour la date de dernier accès
mysql_query("UPDATE zp_dl SET debut=FROM_UNIXTIME($Temps) WHERE ip='$ip'");
//Met à jour le volume téléchargé
$finmega = round($dernier/1024/1024);
mysql_query("UPDATE zp_stats SET fin=FROM_UNIXTIME($Temps), taille=$finmega WHERE id=$id_stat");
}
mysql_close(); //Libère immédiatement BDD
//Empêche Apache de compresser la sortie
ini_set('zlib.output_compression', 0);
header('Content-Transfer-Encoding: binary'); //Transfert en binaire (fichier)
header('Content-Disposition: attachment; filename="'.$nomfich.'"; modification-date="'.$datefich.'";');
header('Content-Length: '.$taille);
header('Content-Type: application/force-download');
header('Accept-Ranges: bytes');
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes '.$premier.'-'.$dernier.'/'.$taille);
$TailleBloc = min($dernier+1-$premier, $TailleFich-$premier, 40*1024*1024); //Taille maxi en octets acceptée
$handle = fopen($fich, 'rb');
fseek($handle, $premier);
echo fread($handle, $TailleBloc);
fclose($handle);
exit; //Pour être sûr qu'aucun octet ne suit
?>