[ Index ]
 

Code source de DokuWiki 2006-11-06

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/exe/ -> fetch.php (source)

   1  <?php
   2  /**
   3   * DokuWiki media passthrough file
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Andreas Gohr <andi@splitbrain.org>
   7   */
   8  
   9    if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
  10    define('DOKU_DISABLE_GZIP_OUTPUT', 1);
  11    require_once (DOKU_INC.'inc/init.php');
  12    require_once (DOKU_INC.'inc/common.php');
  13    require_once (DOKU_INC.'inc/pageutils.php');
  14    require_once (DOKU_INC.'inc/confutils.php');
  15    require_once (DOKU_INC.'inc/auth.php');
  16    //close sesseion
  17    session_write_close();
  18    if(!defined('CHUNK_SIZE')) define('CHUNK_SIZE',16*1024);
  19  
  20    $mimetypes = getMimeTypes();
  21  
  22    //get input
  23    $MEDIA  = stripctl(getID('media',false)); // no cleaning except control chars - maybe external
  24    $CACHE  = calc_cache($_REQUEST['cache']);
  25    $WIDTH  = (int) $_REQUEST['w'];
  26    $HEIGHT = (int) $_REQUEST['h'];
  27    list($EXT,$MIME) = mimetype($MEDIA);
  28    if($EXT === false){
  29      $EXT  = 'unknown';
  30      $MIME = 'application/octet-stream';
  31    }
  32  
  33    //media to local file
  34    if(preg_match('#^(https?)://#i',$MEDIA)){
  35      //handle external images 
  36      if(strncmp($MIME,'image/',6) == 0) $FILE = get_from_URL($MEDIA,$EXT,$CACHE);
  37      if(!$FILE){
  38        //download failed - redirect to original URL
  39        header('Location: '.$MEDIA);
  40        exit;
  41      }
  42    }else{
  43      $MEDIA = cleanID($MEDIA);
  44      if(empty($MEDIA)){
  45        header("HTTP/1.0 400 Bad Request");
  46        print 'Bad request';
  47        exit;
  48      }
  49  
  50      //check permissions (namespace only)
  51      if(auth_quickaclcheck(getNS($MEDIA).':X') < AUTH_READ){
  52        header("HTTP/1.0 401 Unauthorized");
  53        //fixme add some image for imagefiles
  54        print 'Unauthorized';
  55        exit;
  56      }
  57      $FILE  = mediaFN($MEDIA);
  58    }
  59  
  60    //check file existance
  61    if(!@file_exists($FILE)){
  62      header("HTTP/1.0 404 Not Found");
  63      //FIXME add some default broken image
  64      print 'Not Found';
  65      exit;
  66    }
  67  
  68    //handle image resizing
  69    if((substr($MIME,0,5) == 'image') && $WIDTH){
  70      $FILE = get_resized($FILE,$EXT,$WIDTH,$HEIGHT);
  71    }
  72  
  73    // finally send the file to the client
  74    sendFile($FILE,$MIME,$CACHE);
  75  
  76  /* ------------------------------------------------------------------------ */
  77  
  78  /**
  79   * Set headers and send the file to the client
  80   *
  81   * @author Andreas Gohr <andi@splitbrain.org>
  82   * @author Ben Coburn <btcoburn@silicodon.net>
  83   */
  84  function sendFile($file,$mime,$cache){
  85    global $conf;
  86    $fmtime = filemtime($file);
  87    // send headers
  88    header("Content-Type: $mime");
  89    // smart http caching headers
  90    if ($cache==-1) {
  91      // cache
  92      // cachetime or one hour
  93      header('Expires: '.gmdate("D, d M Y H:i:s", time()+max($conf['cachetime'], 3600)).' GMT');
  94      header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.max($conf['cachetime'], 3600));
  95      header('Pragma: public');
  96    } else if ($cache>0) {
  97      // recache
  98      // remaining cachetime + 10 seconds so the newly recached media is used
  99      header('Expires: '.gmdate("D, d M Y H:i:s", $fmtime+$conf['cachetime']+10).' GMT');
 100      header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.max($fmtime-time()+$conf['cachetime']+10, 0));
 101      header('Pragma: public');
 102    } else if ($cache==0) {
 103      // nocache
 104      header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0');
 105      header('Pragma: public');
 106    }
 107    header('Accept-Ranges: bytes');
 108    //send important headers first, script stops here if '304 Not Modified' response
 109    http_conditionalRequest($fmtime);
 110    list($start,$len) = http_rangeRequest(filesize($file));
 111  
 112    //application mime type is downloadable
 113    if(substr($mime,0,11) == 'application'){
 114      header('Content-Disposition: attachment; filename="'.basename($file).'";');
 115    }
 116  
 117    // send file contents
 118    $fp = @fopen($file,"rb");
 119    if($fp){
 120      fseek($fp,$start); //seek to start of range
 121  
 122      $chunk = ($len > CHUNK_SIZE) ? CHUNK_SIZE : $len;
 123      while (!feof($fp) && $chunk > 0) {
 124        @set_time_limit(); // large files can take a lot of time
 125        print fread($fp, $chunk);
 126        flush();
 127        $len -= $chunk;
 128        $chunk = ($len > CHUNK_SIZE) ? CHUNK_SIZE : $len;
 129      }
 130      fclose($fp);
 131    }else{
 132      header("HTTP/1.0 500 Internal Server Error");
 133      print "Could not read $file - bad permissions?";
 134    }
 135  }
 136  
 137  /**
 138   * Checks and sets headers to handle range requets
 139   *
 140   * @author  Andreas Gohr <andi@splitbrain.org>
 141   * @returns array The start byte and the amount of bytes to send
 142   */
 143  function http_rangeRequest($size){
 144    if(!isset($_SERVER['HTTP_RANGE'])){
 145      // no range requested - send the whole file
 146      header("Content-Length: $size");
 147      return array(0,$size);
 148    }
 149  
 150    $t = explode('=', $_SERVER['HTTP_RANGE']);
 151    if (!$t[0]=='bytes') {
 152      // we only understand byte ranges - send the whole file
 153      header("Content-Length: $size");
 154      return array(0,$size);
 155    }
 156  
 157    $r = explode('-', $t[1]);
 158    $start = (int)$r[0];
 159    $end = (int)$r[1];
 160    if (!$end) $end = $size - 1;
 161    if ($start > $end || $start > $size || $end > $size){
 162      header('HTTP/1.1 416 Requested Range Not Satisfiable');
 163      print 'Bad Range Request!';
 164      exit;
 165    }
 166  
 167    $tot = $end - $start + 1;
 168    header('HTTP/1.1 206 Partial Content');
 169    header("Content-Range: bytes {$start}-{$end}/{$size}");
 170    header("Content-Length: $tot");
 171  
 172    return array($start,$tot);
 173  }
 174  
 175  /**
 176   * Resizes the given image to the given size
 177   *
 178   * @author  Andreas Gohr <andi@splitbrain.org>
 179   */
 180  function get_resized($file, $ext, $w, $h=0){
 181    global $conf;
 182  
 183    $info  = getimagesize($file);
 184    if(!$h) $h = round(($w * $info[1]) / $info[0]);
 185  
 186    // we wont scale up to infinity
 187    if($w > 2000 || $h > 2000) return $file;
 188  
 189    //cache
 190    $local = getCacheName($file,'.media.'.$w.'x'.$h.'.'.$ext);
 191    $mtime = @filemtime($local); // 0 if not exists
 192  
 193    if( $mtime > filemtime($file) ||
 194        resize_imageIM($ext,$file,$info[0],$info[1],$local,$w,$h) ||
 195        resize_imageGD($ext,$file,$info[0],$info[1],$local,$w,$h) ){
 196      return $local;
 197    }
 198    //still here? resizing failed
 199    return $file;
 200  }
 201  
 202  /**
 203   * Returns the wanted cachetime in seconds
 204   *
 205   * Resolves named constants
 206   *
 207   * @author  Andreas Gohr <andi@splitbrain.org>
 208   */
 209  function calc_cache($cache){
 210    global $conf;
 211  
 212    if(strtolower($cache) == 'nocache') return 0; //never cache
 213    if(strtolower($cache) == 'recache') return $conf['cachetime']; //use standard cache
 214    return -1; //cache endless
 215  }
 216  
 217  /**
 218   * Download a remote file and return local filename
 219   *
 220   * returns false if download fails. Uses cached file if available and
 221   * wanted
 222   *
 223   * @author  Andreas Gohr <andi@splitbrain.org>
 224   * @author  Pavel Vitis <Pavel.Vitis@seznam.cz>
 225   */
 226  function get_from_URL($url,$ext,$cache){
 227    global $conf;
 228  
 229    // if no cache or fetchsize just redirect
 230    if ($cache==0)           return false;
 231    if (!$conf['fetchsize']) return false;
 232  
 233    $local = getCacheName(strtolower($url),".media.$ext");
 234    $mtime = @filemtime($local); // 0 if not exists
 235  
 236    //decide if download needed:
 237    if( ($mtime == 0) ||                           // cache does not exist
 238        ($cache != -1 && $mtime < time()-$cache)   // 'recache' and cache has expired
 239      ){
 240        if(image_download($url,$local)){
 241          return $local;
 242        }else{
 243          return false;
 244        }
 245    }
 246  
 247    //if cache exists use it else
 248    if($mtime) return $local;
 249  
 250    //else return false
 251    return false;
 252  }
 253  
 254  /**
 255   * Download image files
 256   *
 257   * @author Andreas Gohr <andi@splitbrain.org>
 258   */
 259  function image_download($url,$file){
 260    global $conf;
 261    $http = new DokuHTTPClient();
 262    $http->max_bodysize = $conf['fetchsize'];
 263    $http->timeout = 25; //max. 25 sec
 264    $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i';
 265  
 266    $data = $http->get($url);
 267    if(!$data) return false;
 268  
 269    $fileexists = @file_exists($file);
 270    $fp = @fopen($file,"w");
 271    if(!$fp) return false;
 272    fwrite($fp,$data);
 273    fclose($fp);
 274    if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']);
 275  
 276    // check if it is really an image
 277    $info = @getimagesize($file);
 278    if(!$info){
 279      @unlink($file);
 280      return false;
 281    }
 282  
 283    return true;
 284  }
 285  
 286  /**
 287   * resize images using external ImageMagick convert program
 288   *
 289   * @author Pavel Vitis <Pavel.Vitis@seznam.cz>
 290   * @author Andreas Gohr <andi@splitbrain.org>
 291   */
 292  function resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){
 293    global $conf;
 294  
 295    // check if convert is configured
 296    if(!$conf['im_convert']) return false;
 297  
 298    // prepare command
 299    $cmd  = $conf['im_convert'];
 300    $cmd .= ' -resize '.$to_w.'x'.$to_h.'!';
 301    if ($ext == 'jpg' || $ext == 'jpeg') {
 302        $cmd .= ' -quality '.$conf['jpg_quality'];
 303    }
 304    $cmd .= " $from $to";
 305  
 306    @exec($cmd,$out,$retval);
 307    if ($retval == 0) return true;
 308    return false;
 309  }
 310  
 311  /**
 312   * resize images using PHP's libGD support
 313   *
 314   * @author Andreas Gohr <andi@splitbrain.org>
 315   */
 316  function resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){
 317    global $conf;
 318  
 319    if($conf['gdlib'] < 1) return false; //no GDlib available or wanted
 320  
 321    // check available memory
 322    if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){
 323      return false;
 324    }
 325  
 326    // create an image of the given filetype
 327    if ($ext == 'jpg' || $ext == 'jpeg'){
 328      if(!function_exists("imagecreatefromjpeg")) return false;
 329      $image = @imagecreatefromjpeg($from);
 330    }elseif($ext == 'png') {
 331      if(!function_exists("imagecreatefrompng")) return false;
 332      $image = @imagecreatefrompng($from);
 333  
 334    }elseif($ext == 'gif') {
 335      if(!function_exists("imagecreatefromgif")) return false;
 336      $image = @imagecreatefromgif($from);
 337    }
 338    if(!$image) return false;
 339  
 340    if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor")){
 341      $newimg = @imagecreatetruecolor ($to_w, $to_h);
 342    }
 343    if(!$newimg) $newimg = @imagecreate($to_w, $to_h);
 344    if(!$newimg){
 345      imagedestroy($image);
 346      return false;
 347    }
 348  
 349    //keep png alpha channel if possible
 350    if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){
 351      imagealphablending($newimg, false);
 352      imagesavealpha($newimg,true);
 353    }
 354  
 355    //try resampling first
 356    if(function_exists("imagecopyresampled")){
 357      if(!@imagecopyresampled($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h)) {
 358        imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h);
 359      }
 360    }else{
 361      imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h);
 362    }
 363  
 364    $okay = false;
 365    if ($ext == 'jpg' || $ext == 'jpeg'){
 366      if(!function_exists('imagejpeg')){
 367        $okay = false;
 368      }else{
 369        $okay = imagejpeg($newimg, $to, $conf['jpg_quality']);
 370      }
 371    }elseif($ext == 'png') {
 372      if(!function_exists('imagepng')){
 373        $okay = false;
 374      }else{
 375        $okay =  imagepng($newimg, $to);
 376      }
 377    }elseif($ext == 'gif') {
 378      if(!function_exists('imagegif')){
 379        $okay = false;
 380      }else{
 381        $okay = imagegif($newimg, $to);
 382      }
 383    }
 384  
 385    // destroy GD image ressources
 386    if($image) imagedestroy($image);
 387    if($newimg) imagedestroy($newimg);
 388  
 389    return $okay;
 390  }
 391  
 392  /**
 393   * Checks if the given amount of memory is available
 394   *
 395   * If the memory_get_usage() function is not available the
 396   * function just assumes $used bytes of already allocated memory
 397   *
 398   * @param  int $mem  Size of memory you want to allocate in bytes
 399   * @param  int $used already allocated memory (see above)
 400   * @author Filip Oscadal <webmaster@illusionsoftworks.cz>
 401   * @author Andreas Gohr <andi@splitbrain.org>
 402   */
 403  function is_mem_available($mem,$bytes=1048576){
 404    $limit = trim(ini_get('memory_limit'));
 405    if(empty($limit)) return true; // no limit set!
 406  
 407    // parse limit to bytes
 408    $unit = strtolower(substr($limit,-1));
 409    switch($unit){
 410      case 'g':
 411        $limit = substr($limit,0,-1);
 412        $limit *= 1024*1024*1024;
 413        break;
 414      case 'm':
 415        $limit = substr($limit,0,-1);
 416        $limit *= 1024*1024;
 417        break;
 418      case 'k':
 419        $limit = substr($limit,0,-1);
 420        $limit *= 1024;
 421        break;
 422    }
 423  
 424    // get used memory if possible
 425    if(function_exists('memory_get_usage')){
 426      $used = memory_get_usage();
 427    }
 428  
 429  
 430    if($used+$mem > $limit){
 431      return false;
 432    }
 433  
 434    return true;
 435  }
 436  
 437  //Setup VIM: ex: et ts=2 enc=utf-8 :
 438  ?>


Généré le : Tue Apr 3 20:47:31 2007 par Balluche grâce à PHPXref 0.7