/** * Set headers and send the file to the client * * The $cache parameter influences how long files may be kept in caches, the $public parameter * influences if this caching may happen in public proxis or in the browser cache only FS#2734 * * This function will abort the current script when a 304 is sent or file sending is handled * through x-sendfile * * @author Andreas Gohr <*****@*****.**> * @author Ben Coburn <*****@*****.**> * @author Gerry Weissbach <*****@*****.**> * * @param string $file local file to send * @param string $mime mime type of the file * @param bool $dl set to true to force a browser download * @param int $cache remaining cache time in seconds (-1 for $conf['cache'], 0 for no-cache) * @param bool $public is this a public ressource or a private one? * @param string $orig original file to send - the file name will be used for the Content-Disposition */ function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null) { global $conf; // send mime headers header("Content-Type: {$mime}"); // calculate cache times if ($cache == -1) { $maxage = max($conf['cachetime'], 3600); // cachetime or one hour $expires = time() + $maxage; } else { if ($cache > 0) { $maxage = $cache; // given time $expires = time() + $maxage; } else { // $cache == 0 $maxage = 0; $expires = 0; // 1970-01-01 } } // smart http caching headers if ($maxage) { if ($public) { // cache publically header('Expires: ' . gmdate("D, d M Y H:i:s", $expires) . ' GMT'); header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . $maxage); header('Pragma: public'); } else { // cache in browser header('Expires: ' . gmdate("D, d M Y H:i:s", $expires) . ' GMT'); header('Cache-Control: private, no-transform, max-age=' . $maxage); header('Pragma: no-cache'); } } else { // no cache at all header('Expires: Thu, 01 Jan 1970 00:00:00 GMT'); header('Cache-Control: no-cache, no-transform'); header('Pragma: no-cache'); } //send important headers first, script stops here if '304 Not Modified' response $fmtime = @filemtime($file); http_conditionalRequest($fmtime); // Use the current $file if is $orig is not set. if ($orig == null) { $orig = $file; } //download or display? if ($dl) { header('Content-Disposition: attachment;' . rfc2231_encode('filename', utf8_basename($orig)) . ';'); } else { header('Content-Disposition: inline;' . rfc2231_encode('filename', utf8_basename($orig)) . ';'); } //use x-sendfile header to pass the delivery to compatible webservers http_sendfile($file); // send file contents $fp = @fopen($file, "rb"); if ($fp) { http_rangeRequest($fp, filesize($file), $mime); } else { http_status(500); print "Could not read {$file} - bad permissions?"; } }
/** * Set headers and send the file to the client * * @author Andreas Gohr <*****@*****.**> * @author Ben Coburn <*****@*****.**> */ function sendFile($file, $mime, $dl, $cache) { global $conf; $fmtime = @filemtime($file); // send headers header("Content-Type: {$mime}"); // smart http caching headers if ($cache == -1) { // cache // cachetime or one hour header('Expires: ' . gmdate("D, d M Y H:i:s", time() + max($conf['cachetime'], 3600)) . ' GMT'); header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . max($conf['cachetime'], 3600)); header('Pragma: public'); } else { if ($cache > 0) { // recache // remaining cachetime + 10 seconds so the newly recached media is used header('Expires: ' . gmdate("D, d M Y H:i:s", $fmtime + $conf['cachetime'] + 10) . ' GMT'); header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . max($fmtime - time() + $conf['cachetime'] + 10, 0)); header('Pragma: public'); } else { if ($cache == 0) { // nocache header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0'); header('Pragma: public'); } } } //send important headers first, script stops here if '304 Not Modified' response http_conditionalRequest($fmtime); //download or display? if ($dl) { header('Content-Disposition: attachment; filename="' . basename($file) . '";'); } else { header('Content-Disposition: inline; filename="' . basename($file) . '";'); } //use x-sendfile header to pass the delivery to compatible webservers if (http_sendfile($file)) { exit; } // send file contents $fp = @fopen($file, "rb"); if ($fp) { http_rangeRequest($fp, filesize($file), $mime); } else { header("HTTP/1.0 500 Internal Server Error"); print "Could not read {$file} - bad permissions?"; } }
$pl->gfx_error('blank'); } // cache times $data['cache'] = getCacheName($data['file'], '.pv.' . $data['zoom'] . '-' . $data['col'] . '-' . $data['row'] . '.jpg'); $data['cachet'] = @filemtime($data['cache']); // (re)generate if ($data['cachet'] < $data['mtime']) { $pl->tile_lock($data); if ($conf['im_convert']) { $pl->tile_im($data); } else { $pl->tile_gd($data); } $pl->tile_unlock($data); } // send header('Content-type: image/jpeg'); http_conditionalRequest(max($data['mtime'], $data['selft'])); //use x-sendfile header to pass the delivery to compatible webservers if (http_sendfile($data['cache'])) { exit; } // send file contents $fp = @fopen($data['cache'], "rb"); if ($fp) { http_rangeRequest($fp, filesize($data['cache']), 'image/jpeg'); } else { header("HTTP/1.0 500 Internal Server Error"); print "Could not read tile - bad permissions?"; } //Setup VIM: ex: et ts=4 enc=utf-8 :
/** * @param string $cachefile * @param string $title */ protected function sendODTFile($cachefile, $title) { header('Content-Type: application/vnd.oasis.opendocument.text'); header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0'); header('Pragma: public'); http_conditionalRequest(filemtime($cachefile)); $filename = rawurlencode(cleanID(strtr($title, ':/;"', ' '))); if ($this->getConf('output') == 'file') { header('Content-Disposition: attachment; filename="' . $filename . '.odt";'); } else { header('Content-Disposition: inline; filename="' . $filename . '.odt";'); } //try to send file, and exit if done http_sendfile($cachefile); $fp = @fopen($cachefile, "rb"); if ($fp) { http_rangeRequest($fp, filesize($cachefile), 'application/vnd.oasis.opendocument.text'); } else { header("HTTP/1.0 500 Internal Server Error"); print "Could not read file - bad permissions?"; } exit; }
/** * Do the HTML to PDF conversion work * * @param Doku_Event $event * @param array $param * @return bool */ public function convert(&$event, $param) { global $ACT; global $REV; global $ID; // our event? if ($ACT != 'export_pdfbook' && $ACT != 'export_pdf') { return false; } // check user's rights if (auth_quickaclcheck($ID) < AUTH_READ) { return false; } // one or multiple pages? $list = array(); if ($ACT == 'export_pdf') { $list[0] = $ID; $title = p_get_first_heading($ID); } elseif (isset($_COOKIE['list-pagelist']) && !empty($_COOKIE['list-pagelist'])) { //is in Bookmanager of bookcreator plugin title given if (!($title = $_GET['pdfbook_title'])) { //TODO when title is changed, the cached file contains the old title /** @var $bookcreator action_plugin_bookcreator */ $bookcreator = plugin_load('action', 'bookcreator'); msg($bookcreator->getLang('needtitle'), -1); $event->data = 'show'; $_SERVER['REQUEST_METHOD'] = 'POST'; //clears url return false; } $list = explode("|", $_COOKIE['list-pagelist']); } else { /** @var $bookcreator action_plugin_bookcreator */ $bookcreator = plugin_load('action', 'bookcreator'); msg($bookcreator->getLang('empty'), -1); $event->data = 'show'; $_SERVER['REQUEST_METHOD'] = 'POST'; //clears url return false; } // it's ours, no one else's $event->preventDefault(); // prepare cache $cache = new cache(join(',', $list) . $REV . $this->tpl, '.dw2.pdf'); $depends['files'] = array_map('wikiFN', $list); $depends['files'][] = __FILE__; $depends['files'][] = dirname(__FILE__) . '/renderer.php'; $depends['files'][] = dirname(__FILE__) . '/mpdf/mpdf.php'; $depends['files'] = array_merge($depends['files'], getConfigFiles('main')); // hard work only when no cache available if (!$this->getConf('usecache') || !$cache->useCache($depends)) { // initialize PDF library require_once dirname(__FILE__) . "/DokuPDF.class.php"; $mpdf = new DokuPDF(); // let mpdf fix local links $self = parse_url(DOKU_URL); $url = $self['scheme'] . '://' . $self['host']; if ($self['port']) { $url .= ':' . $self['port']; } $mpdf->setBasePath($url); // Set the title $mpdf->SetTitle($title); // some default settings $mpdf->mirrorMargins = 1; $mpdf->useOddEven = 1; $mpdf->setAutoTopMargin = 'stretch'; $mpdf->setAutoBottomMargin = 'stretch'; // load the template $template = $this->load_template($title); // prepare HTML header styles $html = '<html><head>'; $html .= '<style type="text/css">'; $html .= $this->load_css(); $html .= '@page { size:auto; ' . $template['page'] . '}'; $html .= '@page :first {' . $template['first'] . '}'; $html .= '</style>'; $html .= '</head><body>'; $html .= $template['html']; $html .= '<div class="dokuwiki">'; // loop over all pages $cnt = count($list); for ($n = 0; $n < $cnt; $n++) { $page = $list[$n]; $html .= p_cached_output(wikiFN($page, $REV), 'dw2pdf', $page); $html .= $this->page_depend_replacements($template['cite'], cleanID($page)); if ($n < $cnt - 1) { $html .= '<pagebreak />'; } } $html .= '</div>'; $mpdf->WriteHTML($html); // write to cache file $mpdf->Output($cache->cache, 'F'); } // deliver the file header('Content-Type: application/pdf'); header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0'); header('Pragma: public'); http_conditionalRequest(filemtime($cache->cache)); $filename = rawurlencode(cleanID(strtr($title, ':/;"', ' '))); if ($this->getConf('output') == 'file') { header('Content-Disposition: attachment; filename="' . $filename . '.pdf";'); } else { header('Content-Disposition: inline; filename="' . $filename . '.pdf";'); } if (http_sendfile($cache->cache)) { exit; } $fp = @fopen($cache->cache, "rb"); if ($fp) { http_rangeRequest($fp, filesize($cache->cache), 'application/pdf'); } else { header("HTTP/1.0 500 Internal Server Error"); print "Could not read file - bad permissions?"; } exit; }
/** * Set headers and send the file to the client * * @author Andreas Gohr <*****@*****.**> * @author Ben Coburn <*****@*****.**> */ function sendFile($file, $mime, $dl, $cache) { global $conf; $fmtime = @filemtime($file); // send headers header("Content-Type: {$mime}"); // smart http caching headers if ($cache == -1) { // cache // cachetime or one hour header('Expires: ' . gmdate("D, d M Y H:i:s", time() + max($conf['cachetime'], 3600)) . ' GMT'); header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . max($conf['cachetime'], 3600)); header('Pragma: public'); } else { if ($cache > 0) { // recache // remaining cachetime + 10 seconds so the newly recached media is used header('Expires: ' . gmdate("D, d M Y H:i:s", $fmtime + $conf['cachetime'] + 10) . ' GMT'); header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . max($fmtime - time() + $conf['cachetime'] + 10, 0)); header('Pragma: public'); } else { if ($cache == 0) { // nocache header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0'); header('Pragma: public'); } } } //send important headers first, script stops here if '304 Not Modified' response http_conditionalRequest($fmtime); //download or display? if ($dl) { header('Content-Disposition: attachment; filename="' . basename($file) . '";'); } else { header('Content-Disposition: inline; filename="' . basename($file) . '";'); } //use x-sendfile header to pass the delivery to compatible webservers if (http_sendfile($file)) { exit; } //support download continueing header('Accept-Ranges: bytes'); list($start, $len) = http_rangeRequest(filesize($file)); // send file contents $fp = @fopen($file, "rb"); if ($fp) { fseek($fp, $start); //seek to start of range $chunk = $len > CHUNK_SIZE ? CHUNK_SIZE : $len; while (!feof($fp) && $chunk > 0) { @set_time_limit(30); // large files can take a lot of time print fread($fp, $chunk); flush(); $len -= $chunk; $chunk = $len > CHUNK_SIZE ? CHUNK_SIZE : $len; } fclose($fp); } else { header("HTTP/1.0 500 Internal Server Error"); print "Could not read {$file} - bad permissions?"; } }
/** * Sends a media file with its original filename * * @see sendFile() in lib/exe/fetch.php */ function _sendFile(&$event) { global $conf; global $MEDIA; $d = $event->data; $event->preventDefault(); list($file, $mime, $dl, $cache) = array($d['file'], $d['mime'], $d['download'], $d['cache']); $fmtime = @filemtime($file); // send headers header("Content-Type: {$mime}"); // smart http caching headers if ($cache == -1) { // cache // cachetime or one hour header('Expires: ' . gmdate('D, d M Y H:i:s', time() + max($conf['cachetime'], 3600)) . ' GMT'); header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . max($conf['cachetime'], 3600)); header('Pragma: public'); } elseif ($cache > 0) { // recache // remaining cachetime + 10 seconds so the newly recached media is used header('Expires: ' . gmdate("D, d M Y H:i:s", $fmtime + $conf['cachetime'] + 10) . ' GMT'); header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . max($fmtime - time() + $conf['cachetime'] + 10, 0)); header('Pragma: public'); } elseif ($cache == 0) { // nocache header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0'); header('Pragma: public'); } // send important headers first, script stops here if '304 Not Modified' response http_conditionalRequest($fmtime); // retrieve original filename and send Content-Disposition header $filename = $this->_getOriginalFileName($MEDIA); if ($filename === false) { $filename = utf8_decodeFN($this->common->_correctBasename($d['file'])); } header($this->common->_buildContentDispositionHeader($dl, $filename)); // use x-sendfile header to pass the delivery to compatible webservers if (http_sendfile($file)) { exit; } // send file contents $fp = @fopen($file, 'rb'); if ($fp) { http_rangeRequest($fp, filesize($file), $mime); } else { header('HTTP/1.0 500 Internal Server Error'); print "Could not read {$file} - bad permissions?"; } }