Recent Topics

I've made a download script (to streamline releases)

Started by on Jul 22, 2007 – Contents updated: Jul 22, 2007

Jul 22, 2007 17:20    

I've made a download script that zips up a ... well it's easier to explain in a example.

So "domain.com/b2evo/skins/download/tictac.zip" will look for "domain.com/b2evo/skins/tictac/" and if it exists zip it up, and download it. There is protection in it to stop people accessing dirs/files higher than the initial parent directory. And it works even without the PHP Zip extension installed.

If you do not have .htaccess abilities then you will need to use "domain.com/b2evo/skins/download/download.php?download=tictac" instead.

So you can see that it stops the need to make official releases all the time, the user can just grab the latest and greatest directly from your website, so it's a "See it in action, and download the same code!".

Anyway, to install make the folder "download" where you want to offer these abilities, so for example the skins and plugins folders. Give the folder 777 permission. And add these two files into it:

download.php

PHP

<?php
 
function become_file_download $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
    
    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
                //(From HTTP protocol:
                // 'The last-byte-pos value gives the byte-offset of the last byte in the range; that is, the byte positions specified are inclusive')
            }
            
            $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+$cur_pos);
               print $buffer;
    
               fclose($fh);
           }
           else
           {
               header("HTTP/1.1 404 Not Found");
               exit;
           }
       }
       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);
        }
        else
        {
           header("HTTP/1.1 404 Not Found");
        }
    }
}
 
function make_archive$dir , & $zip$extdir '' )
{    // Taken from http://au3.php.net/manual/en/ref.zip.php#65998
    // credits to hostingfanatic dot com
    if ( is_dir($dir) )
    if ( $dh opendir($dir) )
    {
        while ( ($file readdir($dh)) !== false )
        {
            if( $file != '.' && $file != '..' )
            {
                if( is_dir$dir $file ) )
                {
                    $zip->addFile($dir.$file,$extdir.$file);
                    make_archive($dir.$file.'/' $zip$extdir.$file.'/');
    
                }
                else
                {
                    $zip->addFile($dir.$file,$extdir.$file);                                                        
                }
            }
        }
        closedir($dh);
    }
    return true;
}
 
 
# ---------------------------------
# Perform the script
# Created by balupton
 
# 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 $parent_dir_path.'/'.$download;
$dir_path realpath($dir_path);
 
if ( $this_dir_path && $parent_dir_path && $dir_path )
{    /* good */    }
else
    exit('something went wrong...');
 
if ( substr($dir_path0strlen($parent_dir_path)) === $parent_dir_path )
{    /* good */    }
else
    exit('stop hacking '."[$dir_path][$parent_dir_path]");
 
$file_path $this_dir_path.'/'.$download.'.zip';
 
# Prepare Directory
// chmod(dirname(__FILE__), 0777);
 
# Remove old file
if ( is_file($file_path) )
    unlink($file_path);
 
# Use Zip Library
if ( class_exists('ZipArchive') )
{
    # Create Zip
    $zip = new ZipArchive();
        
    # Create Zip File
    /*if ( function_exists('zip_open') )
    {
        $zip = zip_open($file_path);
        if ( !$zip )
              exit("cannot open <$filename>\n");
    }
    else*/if ( $zip->open($file_pathZIPARCHIVE::CREATE) !== TRUE )
        exit("cannot open <$filename>\n");
    
    # Add folder to Zip
    make_archive($dir_path$zip);
    
    # Close Zip File
    /*if ( function_exists('zip_close') )
        zip_close($zip);
    else*/
        $zip->close();
}
else
{    // Use perl
    chdir($parent_dir_path);
    `zip -rq $file_path $download`;
    chdir($this_dir_path);
}
 
# Download
become_file_download($file_path'archive/zip');
die;
 
?>

.htaccess

PHP

# Settings
RewriteEngine On
Options +FollowSymlinks -Indexes
 
# Rule
# RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} \.zip$ [NC]
RewriteRule ^([a-z0-9_\%]+)\.zipdownload.php?download=$[L]

And your all set :)


Form is loading...

powered by b2evolution – This forum is powered by b2evolution CMS, a complete engine for your website.