listing & zip Dir on the Fly
Hello,
Sometime I need to access my music from work.
To do this I have made a quick php script to print my private collection hosted on my own server and added a script to create archive file (.zip) on the fly.
J’ai développé une petite page php pour gerer ma musique sur mon server perso. Ce script me permet de créer un fichier zip a la volée pour chaque album que je veux prendre chez moi.
Prequesities:
you need the package zipArchives for php5
On Fedora:
yum install php-pecl-zip
On Debian
apt-get install php5-zip
Let me explain: if you go to http://www.crapules.com/test.zip this will create a test.zip file on the fly with all the content of http://www.crapules.com/test directory.
To do this you need to change your .htaccess file like this.
Le principe est simple. Lorsque un utilisateur utilise une URL avec une extension .zip dans certain répertoire, le script créer un fichier archive contenant l’intégralité du repertoire. Par exemple http://www.crapules.com/test.zip, créera un zip avec l’intégralité de http://www.crapules.com/test.
La première étape est de créer un fichier .htaccess dans ledit répertoire comme suit:
RewriteEngine On
Options +FollowSymlinks
RewriteCond %{REQUEST_URI} .zip$ [NC]
RewriteRule ^(.*).zip$ download.php?download=$1 [L]
This change will redirect all the link like
http://www.crapules.com/test.zip
in
http://www.crapules.com/download.php?download=test
Now you need to create a download.php in the same directory:
On crée un fichier download.php dans le même répertoire:
<?php
# download.php
# This script is an adaptation from the balupton's script from b2evolution.net.
# Thanks to him
function myDownloadFile ( $file_path, $content_type = NULL, $buffer_size = 20000 )
{ // Credits go out to; pechkin at zeos dot net - http://au3.php.net/manual/en/function.header.php#65667
// Modified into function by balupton
// A shitload of upgrade to this done by balupton
// Modified by Pateretou to delete file after downloading
if ( empty($content_type) )
$content_type = 'application/force-download';
// Define variables
$fpath = $file_path;
$fname = basename($file_path);
$fsize = filesize($fpath);
$bufsize = $buffer_size;
if ( isset($_SERVER['HTTP_RANGE']) )
{ // Partial download
if( preg_match("/^bytes=(\\d+)-(\\d*)$/", $_SERVER['HTTP_RANGE'], $matches) )
{ // Parsing Range header
$from = $matches[1];
$to = $matches[2];
if( empty($to) )
{
$to = $fsize - 1; // -1 because end byte is included
}
$content_size = $to - $from + 1;
header("HTTP/1.1 206 Partial Content");
header('Pragma: public');
header('Cache-control: must-revalidate, post-check=0, pre-check=0');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header("Content-Range: $from-$to/$fsize");
header("Content-Length: $content_size");
header("Content-Type: $content_type");
if ( $content_type == 'application/force-download' )
header("Content-Disposition: attachment; filename=$fname");
header("Content-Transfer-Encoding: binary");
if(file_exists($fpath) && $fh = fopen($fpath, "rb"))
{
fseek($fh, $from);
$cur_pos = ftell($fh);
while($cur_pos !== FALSE && ftell($fh) + $bufsize < $to+1)
{
$buffer = fread($fh, $bufsize);
print $buffer;
$cur_pos = ftell($fh);
}
$buffer = fread($fh, $to+1 - $cur_pos);
print $buffer;
fclose($fh);
unlink($fpath);
}
else
{
header("HTTP/1.1 500 Internal Server Error");
exit;
}
}
else // Usual download
{
// die ( $fpath.':::'.$fsize);
header("HTTP/1.1 200 OK");
header('Pragma: public');
header('Cache-control: must-revalidate, post-check=0, pre-check=0');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header("Content-Length: $fsize");
header("Content-Type: $content_type");
if ( $content_type == 'application/force-download' )
header("Content-Disposition: attachment; filename=$fname");
header("Content-Transfer-Encoding: binary");
if( file_exists($fpath) )
{
readfile($fpath);
unlink($fpath);
}
else
{
header("HTTP/1.1 404 Not Found");
}
}
}
/*
* Recurse function to create a zip file
*/
function myCreateArchive( $dir , & $zip, $extdir = '' )
{
if ( is_dir($dir) )
if ( $rs = opendir($dir) )
{
while ( ($file = readdir($rs)) !== false )
{
if( $file != '.' && $file != '..' )
{
if( is_dir( $dir . $file ) )
{
$zip->addFile($dir.$file,$extdir.$file);
myCreateArchive($dir.$file.'/' , $zip, $extdir.$file.'/');
}
else
{
$zip->addFile($dir."/".$file,$extdir.$file);
}
}
}
closedir($rs);
}
return true;
}
# Prepare variables
if ( !isset($_GET['download']) )
exit('no download');
$download = $_GET['download'];
$this_dir_path = dirname(__FILE__);
$this_dir_path = realpath($this_dir_path);
$parent_dir_path = $this_dir_path.'/../';
$parent_dir_path = realpath($parent_dir_path);
$dir_path = $this_dir_path.'/'.$download;
$dir_path = realpath($dir_path);
if ( $this_dir_path && $parent_dir_path && $dir_path )
{ /* Ok, variables are set we can continue*/ }
else {
exit('something went wrong...');
}
if ( substr($dir_path, 0, strlen($parent_dir_path)) === $parent_dir_path )
{ /* good */ }
else
exit('stop hacking '."[$dir_path][$parent_dir_path]");
$file_path = $this_dir_path.'/'.$download.'.zip';
# Remove old file
if ( is_file($file_path) )
unlink($file_path);
# Create Zip
$zip = new ZipArchive();
if ( $zip->open($file_path, ZIPARCHIVE::CREATE) !== TRUE )
exit("cannot open <$filename>\n");
# Add file to Zip
myCreateArchive($dir_path, $zip);
$zip->close();
# Download
echo "file_path:$file_path<br>\n";
myDownloadFile($file_path, 'archive/zip');
die;
You can try you script with the following url:
http://youwebsite.com/download.php?download=test to download the content of your “test” directory for example.
If it’s work, you can test your .htaccess file with the url
http://youwebsite.com/test.zip
Now you can do a cute index page like this:
<html>
<header>
<link rel="stylesheet" type="text/css" href="/theme.css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Crapules</title>
</header>
<body>
<div id="gsHeader">
<span class="gsHeader">
<a href="http://www.crapules.com" border="0"><img src="/images/crapules.jpg" alt="Crapules.com logo"/></a>
<br/>
<br/>
</span>
</div>
<div id="gsNavBar" class="gcBorder1">
<div class="gbBreadCrumb">
<div class="block-core-BreadCrumb">
<span class="BreadCrumb-1">
Crapules.com Listing Access
</span>
</div>
</div>
</div>
<br>
<b><font color="red">Please be patient if you try to DL a ZIP file. It's took take more than 40 secondes </font></b>
<br><br>
<?
$myDirectory = opendir(".");
while($entryName = readdir($myDirectory)) {
$dirArray[] = $entryName;
}
closedir($myDirectory);
$indexCount = count($dirArray);
// sort case unsensitive
usort($dirArray, "strcasecmp" );
// print
print("<TABLE border=1 cellpadding=5 cellspacing=0 class=whitelinks>\n");
print("<TR><TH>Filename</TH><th>Download</th><th>Filetype</th><th>Filesize</th></TR>\n");
for($index=0; $index < $indexCount; $index++) {
$extension = array_pop(explode(".", $dirArray[$index]));
if (substr("$dirArray[$index]", 0, 1) != "."){ // don't list hidden files
if ($extension != "php") {
print("<TR><TD><a href=\"$dirArray[$index]\">$dirArray[$index]</a></td>");
print("<td><a href=\"$dirArray[$index].zip\">DL .zip</a></td>");
print("<td>");
print(filetype($dirArray[$index]));
print("</td>");
print("<td>");
print(filesize($dirArray[$index]));
print("</td>");
print("</TR>\n");
}
}
}
print("</TABLE>\n");
?>
<div id="gsFooter">Logo designed by <a href="http://www.k-leidoscope.com">[A]ura</a>. ©2004-2008 <a href="http://www.crapules.com">Crapules.com</a>. All Rights Reserved.</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-3653212-1";
urchinTracker();
</script>
</body>
</html>
Leave a Reply