예제 #1
0
파일: UtilsTest.php 프로젝트: getgrav/grav
 public function testGetMimeByExtension()
 {
     $this->assertEquals('application/octet-stream', Utils::getMimeByExtension(''));
     $this->assertEquals('text/html', Utils::getMimeByExtension('html'));
     $this->assertEquals('application/json', Utils::getMimeByExtension('json'));
     $this->assertEquals('application/atom+xml', Utils::getMimeByExtension('atom'));
     $this->assertEquals('application/rss+xml', Utils::getMimeByExtension('rss'));
     $this->assertEquals('image/jpeg', Utils::getMimeByExtension('jpg'));
     $this->assertEquals('image/png', Utils::getMimeByExtension('png'));
     $this->assertEquals('text/plain', Utils::getMimeByExtension('txt'));
     $this->assertEquals('application/msword', Utils::getMimeByExtension('doc'));
     $this->assertEquals('application/octet-stream', Utils::getMimeByExtension('foo'));
     $this->assertEquals('foo/bar', Utils::getMimeByExtension('foo', 'foo/bar'));
     $this->assertEquals('text/html', Utils::getMimeByExtension('foo', 'text/html'));
 }
예제 #2
0
 /**
  * Provides the ability to download a file to the browser
  *
  * @param string $file the full path to the file to be downloaded
  * @param bool $force_download as opposed to letting browser choose if to download or render
  * @param int $sec      Throttling, try 0.1 for some speed throttling of downloads
  * @param int $bytes    Size of chunks to send in bytes. Default is 1024
  * @throws \Exception
  */
 public static function download($file, $force_download = true, $sec = 0, $bytes = 1024)
 {
     if (file_exists($file)) {
         // fire download event
         Grav::instance()->fireEvent('onBeforeDownload', new Event(['file' => $file]));
         $file_parts = pathinfo($file);
         $mimetype = Utils::getMimeByExtension($file_parts['extension']);
         $size = filesize($file);
         // File size
         // clean all buffers
         while (ob_get_level()) {
             ob_end_clean();
         }
         // required for IE, otherwise Content-Disposition may be ignored
         if (ini_get('zlib.output_compression')) {
             ini_set('zlib.output_compression', 'Off');
         }
         header("Content-Type: " . $mimetype);
         header('Accept-Ranges: bytes');
         if ($force_download) {
             // output the regular HTTP headers
             header('Content-Disposition: attachment; filename="' . $file_parts['basename'] . '"');
         }
         // multipart-download and download resuming support
         if (isset($_SERVER['HTTP_RANGE'])) {
             list($a, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2);
             list($range) = explode(",", $range, 2);
             list($range, $range_end) = explode("-", $range);
             $range = intval($range);
             if (!$range_end) {
                 $range_end = $size - 1;
             } else {
                 $range_end = intval($range_end);
             }
             $new_length = $range_end - $range + 1;
             header("HTTP/1.1 206 Partial Content");
             header("Content-Length: {$new_length}");
             header("Content-Range: bytes {$range}-{$range_end}/{$size}");
         } else {
             $new_length = $size;
             header("Content-Length: " . $size);
             if (Grav::instance()['config']->get('system.cache.enabled')) {
                 $expires = Grav::instance()['config']->get('system.pages.expires');
                 if ($expires > 0) {
                     $expires_date = gmdate('D, d M Y H:i:s T', time() + $expires);
                     header('Cache-Control: max-age=' . $expires);
                     header('Expires: ' . $expires_date);
                     header('Pragma: cache');
                 }
                 header('Last-Modified: ' . gmdate("D, d M Y H:i:s T", filemtime($file)));
                 // Return 304 Not Modified if the file is already cached in the browser
                 if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($file)) {
                     header('HTTP/1.1 304 Not Modified');
                     exit;
                 }
             }
         }
         /* output the file itself */
         $chunksize = $bytes * 8;
         //you may want to change this
         $bytes_send = 0;
         $fp = @fopen($file, 'r');
         if ($fp) {
             if (isset($_SERVER['HTTP_RANGE'])) {
                 fseek($fp, $range);
             }
             while (!feof($fp) && !connection_aborted() && $bytes_send < $new_length) {
                 $buffer = fread($fp, $chunksize);
                 echo $buffer;
                 //echo($buffer); // is also possible
                 flush();
                 usleep($sec * 1000000);
                 $bytes_send += strlen($buffer);
             }
             fclose($fp);
         } else {
             throw new \Exception('Error - can not open file.');
         }
         exit;
     }
 }
예제 #3
0
 /**
  * Set response header.
  */
 public function header()
 {
     /** @var Page $page */
     $page = $this['page'];
     $format = $page->templateFormat();
     header('Content-type: ' . Utils::getMimeByExtension($format, 'text/html'));
     // Calculate Expires Headers if set to > 0
     $expires = $page->expires();
     if ($expires > 0) {
         $expires_date = gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT';
         header('Cache-Control: max-age=' . $expires);
         header('Expires: ' . $expires_date);
     }
     // Set the last modified time
     if ($page->lastModified()) {
         $last_modified_date = gmdate('D, d M Y H:i:s', $page->modified()) . ' GMT';
         header('Last-Modified: ' . $last_modified_date);
     }
     // Calculate a Hash based on the raw file
     if ($page->eTag()) {
         header('ETag: ' . md5($page->raw() . $page->modified()));
     }
     // Set debugger data in headers
     if (!($format === null || $format == 'html')) {
         $this['debugger']->enabled(false);
     }
     // Set HTTP response code
     if (isset($this['page']->header()->http_response_code)) {
         http_response_code($this['page']->header()->http_response_code);
     }
     // Vary: Accept-Encoding
     if ($this['config']->get('system.pages.vary_accept_encoding', false)) {
         header('Vary: Accept-Encoding');
     }
 }