[TASK] Add possibility to dump file to browser 35/26835/2
authorSteffen Ritter <info@rs-websystems.de>
Wed, 15 Jan 2014 13:49:42 +0000 (14:49 +0100)
committerBenjamin Mack <benni@typo3.org>
Thu, 30 Jan 2014 18:14:23 +0000 (19:14 +0100)
The FileAbstractionLayer currently only provides the possibility to
retrieve the contents of a file as a string. If you want to output
a file this would lead to a massive memory overhead for large files
when building some kind of download/jumpurl/access-restricted download
script.

This change adds a method "dumpFileContents" to the ResourceStorage
allowing to directly output the contents of the file including setting
correct headers.

In addition it introduces a new method (same name) in the DriverInterface
and implements it in the LocalDriver.

Resolves: #52589
Releases: 6.2
Change-Id: I050da59b136fafbf3f05ac814bd3f11f20ae2396
Reviewed-on: https://review.typo3.org/26835
Reviewed-by: Frans Saris
Reviewed-by: Philipp Gampe
Reviewed-by: Ingo Schmitt
Reviewed-by: Sebastian Fischer
Tested-by: Sebastian Fischer
Reviewed-by: Benjamin Mack
Tested-by: Benjamin Mack
typo3/sysext/core/Classes/Resource/Driver/DriverInterface.php
typo3/sysext/core/Classes/Resource/Driver/LocalDriver.php
typo3/sysext/core/Classes/Resource/ResourceStorage.php

index fbebf65..bd5698a 100644 (file)
@@ -364,6 +364,16 @@ interface DriverInterface {
         */
        public function getPermissions($identifier);
 
+       /**
+        * Directly output the contents of the file to the output
+        * buffer. Should not take care of header files or flushing
+        * buffer before. Will be taken care of by the Storage.
+        *
+        * @param string $identifier
+        * @return void
+        */
+       public function dumpFileContents($identifier);
+
        /**
         * Checks if a given identifier is within a container, e.g. if
         * a file or folder is within another folder.
index f0bf41b..62d64ef 100644 (file)
@@ -1185,4 +1185,18 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                return $role;
        }
 
+       /**
+        * Directly output the contents of the file to the output
+        * buffer. Should not take care of header files or flushing
+        * buffer before. Will be taken care of by the Storage.
+        *
+        * @param string $identifier
+        *
+        * @return void
+        */
+       public function dumpFileContents($identifier) {
+               readfile($this->getAbsolutePath($this->canonicalizeAndCheckFileIdentifier($identifier)), 0);
+       }
+
+
 }
index 55aa737..3e12b70 100644 (file)
@@ -1432,6 +1432,33 @@ class ResourceStorage {
                return $this->driver->getFileContents($file->getIdentifier());
        }
 
+       /**
+        * Outputs file Contents,
+        * clears output buffer first and sends headers accordingly.
+        *
+        * @param FileInterface $file
+        * @param boolean $asDownload If set Content-Disposition headers are sent
+        * @param string $alternativeFilename the filename for the download (if $asDownload is set)
+        * @return void
+        */
+       public function dumpFileContents(FileInterface $file, $asDownload = FALSE, $alternativeFilename = NULL) {
+               if ($asDownload) {
+                       $downloadName = $alternativeFilename ?: $file->getName();
+                       header('Content-Disposition: attachment; filename=' . $downloadName);
+               }
+               header('Content-Type: ' . $file->getMimeType());
+               header('Content-Length: ' . $file->getSize());
+               header('Last-Modified: ' .
+                       gmdate('D, d M Y H:i:s', array_pop($this->driver->getFileInfoByIdentifier($file->getIdentifier(), array('mtime')))) . ' GMT',
+                       TRUE,
+                       200
+               );
+               ob_clean();
+               $this->driver->dumpFileContents($file->getIdentifier());
+               flush();
+               exit();
+       }
+
        /**
         * Set contents of a file object.
         *