1*f62ea8a1Sandi<?php 2*f62ea8a1Sandi/** 3*f62ea8a1Sandi * DokuWiki media passthrough file 4*f62ea8a1Sandi * 5*f62ea8a1Sandi * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6*f62ea8a1Sandi * @author Andreas Gohr <andi@splitbrain.org> 7*f62ea8a1Sandi */ 8*f62ea8a1Sandi 9*f62ea8a1Sandi if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__)).'/'); 10*f62ea8a1Sandi require_once(DOKU_INC.'inc/init.php'); 11*f62ea8a1Sandi require_once(DOKU_INC.'inc/common.php'); 12*f62ea8a1Sandi require_once(DOKU_INC.'inc/pageutils.php'); 13*f62ea8a1Sandi require_once(DOKU_INC.'inc/confutils.php'); 14*f62ea8a1Sandi require_once(DOKU_INC.'inc/auth.php'); 15*f62ea8a1Sandi $mimetypes = getMimeTypes(); 16*f62ea8a1Sandi 17*f62ea8a1Sandi //get input 18*f62ea8a1Sandi $MEDIA = $_REQUEST['media']; 19*f62ea8a1Sandi $CACHE = calc_cache($_REQUEST['cache']); 20*f62ea8a1Sandi $WIDTH = $_REQUEST['w']; 21*f62ea8a1Sandi $HEIGHT = $_REQUEST['h']; 22*f62ea8a1Sandi list($EXT,$MIME) = mimetype($MEDIA); 23*f62ea8a1Sandi if($EXT === false){ 24*f62ea8a1Sandi $EXT = 'unknown'; 25*f62ea8a1Sandi $MIME = 'application/octet-stream'; 26*f62ea8a1Sandi } 27*f62ea8a1Sandi 28*f62ea8a1Sandi //media to local file 29*f62ea8a1Sandi if(preg_match('#^(https?|ftp)://#i',$MEDIA)){ 30*f62ea8a1Sandi //handle external media 31*f62ea8a1Sandi $FILE = get_from_URL($MEDIA,$EXT,$CACHE); 32*f62ea8a1Sandi if(!$FILE){ 33*f62ea8a1Sandi //download failed - redirect to original URL 34*f62ea8a1Sandi header('Location: '.$MEDIA); 35*f62ea8a1Sandi exit; 36*f62ea8a1Sandi } 37*f62ea8a1Sandi }else{ 38*f62ea8a1Sandi $MEDIA = cleanID($MEDIA); 39*f62ea8a1Sandi if(empty($MEDIA)){ 40*f62ea8a1Sandi header("HTTP/1.0 400 Bad Request"); 41*f62ea8a1Sandi print 'Bad request'; 42*f62ea8a1Sandi exit; 43*f62ea8a1Sandi } 44*f62ea8a1Sandi 45*f62ea8a1Sandi //check permissions (namespace only) 46*f62ea8a1Sandi if(auth_quickaclcheck(getNS($MEDIA).':X') < AUTH_READ){ 47*f62ea8a1Sandi header("HTTP/1.0 401 Unauthorized"); 48*f62ea8a1Sandi //fixme add some image for imagefiles 49*f62ea8a1Sandi print 'Unauthorized'; 50*f62ea8a1Sandi exit; 51*f62ea8a1Sandi } 52*f62ea8a1Sandi $FILE = mediaFN($MEDIA); 53*f62ea8a1Sandi } 54*f62ea8a1Sandi 55*f62ea8a1Sandi //check file existance 56*f62ea8a1Sandi if(!@file_exists($FILE)){ 57*f62ea8a1Sandi header("HTTP/1.0 404 Not Found"); 58*f62ea8a1Sandi //FIXME add some default broken image 59*f62ea8a1Sandi print 'Not Found'; 60*f62ea8a1Sandi exit; 61*f62ea8a1Sandi } 62*f62ea8a1Sandi 63*f62ea8a1Sandi //handle image resizing 64*f62ea8a1Sandi if((substr($MIME,0,5) == 'image') && $WIDTH){ 65*f62ea8a1Sandi $FILE = get_resized($FILE,$EXT,$WIDTH,$HEIGHT); 66*f62ea8a1Sandi } 67*f62ea8a1Sandi 68*f62ea8a1Sandi 69*f62ea8a1Sandi //FIXME set sane cachecontrol headers 70*f62ea8a1Sandi //FIXME handle conditional and partial requests 71*f62ea8a1Sandi 72*f62ea8a1Sandi //send file 73*f62ea8a1Sandi header("Content-Type: $MIME"); 74*f62ea8a1Sandi header('Last-Modified: '.date('r',filemtime($FILE))); 75*f62ea8a1Sandi header('Content-Length: '.filesize($FILE)); 76*f62ea8a1Sandi 77*f62ea8a1Sandi //application mime type is downloadable 78*f62ea8a1Sandi if(substr($MIME,0,11) == 'application'){ 79*f62ea8a1Sandi header('Content-Disposition: attachment; filename="'.basename($FILE).'"'); 80*f62ea8a1Sandi } 81*f62ea8a1Sandi 82*f62ea8a1Sandi $fp = @fopen($FILE,"rb"); 83*f62ea8a1Sandi if($fp){ 84*f62ea8a1Sandi fpassthru($fp); //does a close itself 85*f62ea8a1Sandi }else{ 86*f62ea8a1Sandi header("HTTP/1.0 500 Internal Server Error"); 87*f62ea8a1Sandi print "Could not read $FILE - bad permissions?"; 88*f62ea8a1Sandi } 89*f62ea8a1Sandi 90*f62ea8a1Sandi/* ------------------------------------------------------------------------ */ 91*f62ea8a1Sandi 92*f62ea8a1Sandi/** 93*f62ea8a1Sandi * Resizes the given image to the given size 94*f62ea8a1Sandi * 95*f62ea8a1Sandi * @author Andreas Gohr <andi@splitbrain.org> 96*f62ea8a1Sandi */ 97*f62ea8a1Sandifunction get_resized($file, $ext, $w, $h=0){ 98*f62ea8a1Sandi global $conf; 99*f62ea8a1Sandi 100*f62ea8a1Sandi $md5 = md5($file); 101*f62ea8a1Sandi $info = getimagesize($file); 102*f62ea8a1Sandi if(!$h) $h = round(($w * $info[1]) / $info[0]); 103*f62ea8a1Sandi 104*f62ea8a1Sandi 105*f62ea8a1Sandi //cache 106*f62ea8a1Sandi $local = $conf['mediadir'].'/_cache/'.$md5.'.'.$w.'x'.$h.'.'.$ext; 107*f62ea8a1Sandi $mtime = @filemtime($local); // 0 if not exists 108*f62ea8a1Sandi 109*f62ea8a1Sandi if( $mtime > filemtime($file) || resize_image($ext,$file,$info[0],$info[1],$local,$w,$h) ){ 110*f62ea8a1Sandi return $local; 111*f62ea8a1Sandi } 112*f62ea8a1Sandi //still here? resizing failed 113*f62ea8a1Sandi return $file; 114*f62ea8a1Sandi} 115*f62ea8a1Sandi 116*f62ea8a1Sandi/** 117*f62ea8a1Sandi * Returns the wanted cachetime in seconds 118*f62ea8a1Sandi * 119*f62ea8a1Sandi * Resolves named constants 120*f62ea8a1Sandi * 121*f62ea8a1Sandi * @author Andreas Gohr <andi@splitbrain.org> 122*f62ea8a1Sandi */ 123*f62ea8a1Sandifunction calc_cache($cache){ 124*f62ea8a1Sandi global $conf; 125*f62ea8a1Sandi 126*f62ea8a1Sandi if(strtolower($cache) == 'nocache') return 0; //never cache 127*f62ea8a1Sandi if(strtolower($cache) == 'recache') return $conf['cachetime']; //use standard cache 128*f62ea8a1Sandi return -1; //cache endless 129*f62ea8a1Sandi} 130*f62ea8a1Sandi 131*f62ea8a1Sandi/** 132*f62ea8a1Sandi * Download a remote file and return local filename 133*f62ea8a1Sandi * 134*f62ea8a1Sandi * returns false if download fails. Uses cached file if available and 135*f62ea8a1Sandi * wanted 136*f62ea8a1Sandi * 137*f62ea8a1Sandi * @author Andreas Gohr <andi@splitbrain.org> 138*f62ea8a1Sandi */ 139*f62ea8a1Sandifunction get_from_URL($url,$ext,$cache){ 140*f62ea8a1Sandi global $conf; 141*f62ea8a1Sandi 142*f62ea8a1Sandi $url = strtolower($url); 143*f62ea8a1Sandi $md5 = md5($url); 144*f62ea8a1Sandi 145*f62ea8a1Sandi $local = $conf['mediadir']."/_cache/$md5.$ext"; 146*f62ea8a1Sandi $mtime = @filemtime($local); // 0 if not exists 147*f62ea8a1Sandi 148*f62ea8a1Sandi //decide if download needed: 149*f62ea8a1Sandi 150*f62ea8a1Sandi // never cache exists but no endless cache not exists or expired 151*f62ea8a1Sandi if( $cache == 0 || ($mtime != 0 && $cache != -1) || $mtime < time()-$cache ){ 152*f62ea8a1Sandi if(io_download($url,$local)){ 153*f62ea8a1Sandi return $local; 154*f62ea8a1Sandi }else{ 155*f62ea8a1Sandi return false; 156*f62ea8a1Sandi } 157*f62ea8a1Sandi } 158*f62ea8a1Sandi 159*f62ea8a1Sandi //if cache exists use it else 160*f62ea8a1Sandi if($mtime) return $local; 161*f62ea8a1Sandi 162*f62ea8a1Sandi //else return false 163*f62ea8a1Sandi return false; 164*f62ea8a1Sandi} 165*f62ea8a1Sandi 166*f62ea8a1Sandi/** 167*f62ea8a1Sandi * resize images 168*f62ea8a1Sandi * 169*f62ea8a1Sandi * @author Andreas Gohr <andi@splitbrain.org> 170*f62ea8a1Sandi */ 171*f62ea8a1Sandifunction resize_image($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ 172*f62ea8a1Sandi global $conf; 173*f62ea8a1Sandi 174*f62ea8a1Sandi if($conf['gdlib'] < 1) return false; //no GDlib available or wanted 175*f62ea8a1Sandi 176*f62ea8a1Sandi // create an image of the given filetype 177*f62ea8a1Sandi if ($ext == 'jpg' || $ext == 'jpeg'){ 178*f62ea8a1Sandi if(!function_exists("imagecreatefromjpeg")) return false; 179*f62ea8a1Sandi $image = @imagecreatefromjpeg($from); 180*f62ea8a1Sandi }elseif($ext == 'png') { 181*f62ea8a1Sandi if(!function_exists("imagecreatefrompng")) return false; 182*f62ea8a1Sandi $image = @imagecreatefrompng($from); 183*f62ea8a1Sandi 184*f62ea8a1Sandi }elseif($ext == 'gif') { 185*f62ea8a1Sandi if(!function_exists("imagecreatefromgif")) return false; 186*f62ea8a1Sandi $image = @imagecreatefromgif($from); 187*f62ea8a1Sandi } 188*f62ea8a1Sandi if(!$image) return false; 189*f62ea8a1Sandi 190*f62ea8a1Sandi if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor")){ 191*f62ea8a1Sandi $newimg = @imagecreatetruecolor ($to_w, $to_h); 192*f62ea8a1Sandi } 193*f62ea8a1Sandi if(!$newimg) $newimg = @imagecreate($to_w, $to_h); 194*f62ea8a1Sandi if(!$newimg) return false; 195*f62ea8a1Sandi 196*f62ea8a1Sandi //keep png alpha channel if possible 197*f62ea8a1Sandi if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){ 198*f62ea8a1Sandi imagealphablending($newimg, false); 199*f62ea8a1Sandi imagesavealpha($newimg,true); 200*f62ea8a1Sandi } 201*f62ea8a1Sandi 202*f62ea8a1Sandi // create cachedir 203*f62ea8a1Sandi io_makeFileDir($to); 204*f62ea8a1Sandi 205*f62ea8a1Sandi //try resampling first 206*f62ea8a1Sandi if(function_exists("imagecopyresampled")){ 207*f62ea8a1Sandi if(!@imagecopyresampled($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h)) { 208*f62ea8a1Sandi imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h); 209*f62ea8a1Sandi } 210*f62ea8a1Sandi }else{ 211*f62ea8a1Sandi imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h); 212*f62ea8a1Sandi } 213*f62ea8a1Sandi 214*f62ea8a1Sandi if ($ext == 'jpg' || $ext == 'jpeg'){ 215*f62ea8a1Sandi if(!function_exists("imagejpeg")) return false; 216*f62ea8a1Sandi return imagejpeg($newimg, $to, 70); 217*f62ea8a1Sandi }elseif($ext == 'png') { 218*f62ea8a1Sandi if(!function_exists("imagepng")) return false; 219*f62ea8a1Sandi return imagepng($newimg, $to); 220*f62ea8a1Sandi }elseif($ext == 'gif') { 221*f62ea8a1Sandi if(!function_exists("imagegif")) return false; 222*f62ea8a1Sandi return imagegif($newimg, $to); 223*f62ea8a1Sandi } 224*f62ea8a1Sandi 225*f62ea8a1Sandi return false; 226*f62ea8a1Sandi} 227*f62ea8a1Sandi 228*f62ea8a1Sandi 229*f62ea8a1Sandi//Setup VIM: ex: et ts=2 enc=utf-8 : 230*f62ea8a1Sandi?> 231