[BUGFIX] Make generated thumbnails browser-cachable
authorDmitry Dulepov <dmitry@typo3.org>
Wed, 23 Nov 2011 13:50:53 +0000 (15:50 +0200)
committerXavier Perseguers <xavier@typo3.org>
Tue, 16 Oct 2012 09:50:02 +0000 (11:50 +0200)
Thumbnail generation code appends current timestamp in each
invocation of the thumbnail generation script. This is useless
because it prevents caching. Removing this timestamp will not
cause any issues with old vs new versions because the URL
includes an md5 checksum of the file size and file timestamp.
So when the file is updated, the md5 sum will change. The
patch also changes short md5 to full md5.

Additionally proper last-modified, expires and etag headers
are sent.

Change-Id: Icb32ca8fbde91dffa65b835ac9c0954f3f5da53f
Fixes: #21481
Releases: 4.7, 4.6, 4.5
Reviewed-on: http://review.typo3.org/12820
Reviewed-by: Philipp Gampe
Reviewed-by: Marcus Schwemer
Reviewed-by: Wouter Wolters
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
t3lib/class.t3lib_befunc.php
t3lib/thumbs.php
typo3/class.file_list.inc
typo3/show_item.php
typo3/sysext/cms/tslib/class.tslib_content.php

index 3188bf2..07f27bc 100644 (file)
@@ -1570,27 +1570,19 @@ final class t3lib_BEfunc {
                                        $check = basename($theFile_abs) . ':' . filemtime($theFile_abs) . ':' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
                                        $params = '&file=' . rawurlencode($theFile);
                                        $params .= $size ? '&size=' . $size : '';
-                                       $params .= '&md5sum=' . t3lib_div::shortMD5($check);
+                                       $params .= '&md5sum=' . md5($check);
 
-                                       $url = $thumbScript . '?&dummy=' . $GLOBALS['EXEC_TIME'] . $params;
+                                       $url = $thumbScript . '?' . $params;
                                        $onClick = 'top.launchView(\'' . $theFile . '\',\'\',\'' . $backPath . '\');return false;';
                                        $thumbData .= '<a href="#" onclick="' . htmlspecialchars($onClick) . '"><img src="' . htmlspecialchars($backPath . $url) . '" hspace="2" border="0" title="' . trim($theFile) . '"' . $tparams . ' alt="" /></a> ';
                                } else {
                                                // Icon
-                                       $theFile_abs = PATH_site . ($uploaddir ? $uploaddir . '/' : '') . trim($theFile);
                                        $theFile = ($abs ? '' : '../') . ($uploaddir ? $uploaddir . '/' : '') . trim($theFile);
-
                                        $fileIcon = t3lib_iconWorks::getSpriteIconForFile(
                                                strtolower($ext),
                                                array('title' => htmlspecialchars(trim($theFile)))
                                        );
 
-                                       $check = basename($theFile_abs) . ':' . filemtime($theFile_abs) . ':' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
-                                       $params = '&file=' . rawurlencode($theFile);
-                                       $params .= $size ? '&size=' . $size : '';
-                                       $params .= '&md5sum=' . t3lib_div::shortMD5($check);
-
-                                       $url = $thumbScript . '?&dummy=' . $GLOBALS['EXEC_TIME'] . $params;
                                        $onClick = 'top.launchView(\'' . $theFile . '\',\'\',\'' . $backPath . '\');return false;';
                                        $thumbData .= '<a href="#" onclick="' . htmlspecialchars($onClick) . '">' . $fileIcon . '</a> ';
                                }
@@ -1612,9 +1604,9 @@ final class t3lib_BEfunc {
                $check = basename($theFile) . ':' . filemtime($theFile) . ':' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
                $params = '&file=' . rawurlencode($theFile);
                $params .= trim($size) ? '&size=' . trim($size) : '';
-               $params .= '&md5sum=' . t3lib_div::shortMD5($check);
+               $params .= '&md5sum=' . md5($check);
 
-               $url = $thumbScript . '?&dummy=' . $GLOBALS['EXEC_TIME'] . $params;
+               $url = $thumbScript . '?' . $params;
                $th = '<img src="' . htmlspecialchars($url) . '" title="' . trim(basename($theFile)) . '"' . ($tparams ? " " . $tparams : "") . ' alt="" />';
                return $th;
        }
index 6a997dc..d05a7a5 100644 (file)
@@ -151,8 +151,9 @@ class SC_t3lib_thumbs {
                if ($mtime) {
                                // Always use the absolute path for this check!
                        $check = basename($file).':'.$mtime.':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
-                       $md5_real = t3lib_div::shortMD5($check);
-                       if (!strcmp($md5_real,$md5sum)) {
+                       $md5pre47 = t3lib_div::shortMD5($check);
+                       $md5from47 = md5($check);
+                       if (!strcmp($md5pre47, $md5sum) || !strcmp($md5from47, $md5sum)) {
                                $OK = TRUE;
                        }
                }
@@ -231,8 +232,13 @@ class SC_t3lib_thumbs {
                                        }
                                }
                                        // The thumbnail is read and output to the browser
-                               if($fd = @fopen($this->output,'rb')) {
+                               if (($fd = @fopen($this->output, 'rb'))) {
+                                       $fileModificationTime = filemtime($this->output);
                                        header('Content-type: image/' . $outext);
+                                       header('Last-Modified: '. date('r', $fileModificationTime));
+                                       header('Etag: ' . md5($this->output) . '-' . $fileModificationTime);
+                                               // Expiration time is choosen arbitrary to 1 month
+                                       header('Expires: ' . date('r', $fileModificationTime + 30*24*60*60));
                                        fpassthru($fd);
                                        fclose($fd);
                                } else {
@@ -400,4 +406,4 @@ $SOBE = t3lib_div::makeInstance('SC_t3lib_thumbs');
 $SOBE->init();
 $SOBE->main();
 
-?>
\ No newline at end of file
+?>
index 97a3ff4..4a3ca56 100644 (file)
@@ -477,20 +477,22 @@ class fileList extends t3lib_recordList {
                                                                $theData[$field]=$this->makeRef($theFile);
                                                        break;
                                                        case 'file':
-                                                               $theData[$field] = $this->linkWrapFile($theFile[$field],$theFile['path'].$theFile['file']);
+                                                               $theData[$field] = $this->linkWrapFile($theFile[$field], $theFile['path'] . $theFile['file']);
                                                                        // Thumbsnails?
-                                                               if ($this->thumbs && $this->isImage($theFile['fileext']))       {
+                                                               if ($this->thumbs && $this->isImage($theFile['fileext'])) {
                                                                        $thumbData = array();
-                                                                       $theFile_R = rawurlencode($theFile['path'].$theFile['file']);
+                                                                       $theFile_R = rawurlencode($theFile['path'] . $theFile['file']);
                                                                        $titleCol = $this->fieldArray[0];
 
-                                                                       $theFile_abs = $theFile['path'].$theFile['file'];
-                                                                       $check = basename($theFile_abs).':'.filemtime($theFile_abs).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
-                                                                       $params = '&file='.$theFile_R;
-                                                                       $params.= '&md5sum='.t3lib_div::shortMD5($check);
-                                                                       $href = $this->backPath.$this->thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
+                                                                       $theFile_abs = $theFile['path'] . $theFile['file'];
+                                                                       $check = basename($theFile_abs) . ':' . filemtime($theFile_abs) .
+                                                                                       ':' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
+                                                                       $params = '&file=' . $theFile_R;
+                                                                       $params.= '&md5sum=' . md5($check);
+                                                                       $href = $this->backPath . $this->thumbScript . '?' . $params;
 
-                                                                       $theData[$field] .= '<br /><img src="'.htmlspecialchars($href).'" hspace="2" title="'.htmlspecialchars(trim($theFile['file'])).'" alt="'.htmlspecialchars(trim($theFile['file'])).'" />';
+                                                                       $theData[$field] .= '<br /><img src="' . htmlspecialchars($href) . '" hspace="2" title="' .
+                                                                                       htmlspecialchars(trim($theFile['file'])) . '" alt="' . htmlspecialchars(trim($theFile['file'])) . '" />';
                                                                }
                                                        break;
                                                        default:
index 53f0a6b..3292af1 100644 (file)
@@ -401,15 +401,16 @@ class SC_show_item {
                        }
 
                                // Font files:
-                       if ($ext=='ttf')        {
+                       if ($ext == 'ttf') {
                                $thumbScript = 'thumbs.php';
-                               $check = basename($this->file).':'.filemtime($this->file).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
-                               $params = '&file='.rawurlencode($this->file);
-                               $params.= '&md5sum='.t3lib_div::shortMD5($check);
-                               $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
+                               $check = basename($this->file) . ':' . filemtime($this->file) . ':' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
+                               $params = '&file=' . rawurlencode($this->file);
+                               $params .= '&md5sum=' . md5($check);
+                               $url = $thumbScript . '?' . $params;
                                $thumb = '<br />
-                                       <div align="center">'.$returnLinkTag.'<img src="'.htmlspecialchars($url).'" border="0" title="'.htmlspecialchars(trim($this->file)).'" alt="" /></a></div>';
-                               $this->content.= $this->doc->section('',$thumb);
+                                       <div align="center">' . $returnLinkTag . '<img src="' . htmlspecialchars($url) .
+                                       '" border="0" title="' . htmlspecialchars(trim($this->file)) . '" alt="" /></a></div>';
+                               $this->content .= $this->doc->section('', $thumb);
                        }
                }
 
index 7855c74..1ca3efa 100644 (file)
@@ -4004,8 +4004,8 @@ class tslib_cObj {
                                                                        : $conf['icon_thumbSize']);
                                                        }
                                                        $check = basename($theFile) . ':' . filemtime($theFile) . ':' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
-                                                       $md5sum = '&md5sum=' . t3lib_div::shortMD5($check);
-                                                       $icon = 't3lib/thumbs.php?dummy=' . $GLOBALS['EXEC_TIME'] . '&file=' .
+                                                       $md5sum = '&md5sum=' . md5($check);
+                                                       $icon = 't3lib/thumbs.php?file=' .
                                                                rawurlencode('../' . $theFile) . $thumbSize . $md5sum;
                                                } else {
                                                        $icon = t3lib_extMgm::siteRelPath('cms') . 'tslib/media/miscicons/notfound_thumb.gif';