]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add OC_Response::setContentLengthHeader() for Apache PHP SAPI workaround.
authorAndreas Fischer <bantu@owncloud.com>
Thu, 26 Mar 2015 15:24:15 +0000 (16:24 +0100)
committerAndreas Fischer <bantu@owncloud.com>
Thu, 26 Mar 2015 15:37:38 +0000 (16:37 +0100)
Do not send Content-Length headers with a value larger than PHP_INT_MAX
(2147483647) on Apache PHP SAPI 32-bit. PHP will eat them and send 2147483647
instead.

When X-Sendfile is enabled, Apache will send a correct Content-Length header,
even for files larger than 2147483647 bytes. When X-Sendfile is not enabled,
ownCloud will not send a Content-Length header. This prevents progress bars
from working, but allows the actual transfer to work properly.

apps/files/download.php
apps/files_versions/download.php
lib/private/files.php
lib/private/response.php
lib/public/response.php

index 664a69c5959dc5638c6060795956ee624e93dfe8..8d9c539284f8f25ca395a078a14f87818ca9642d 100644 (file)
@@ -39,7 +39,7 @@ $ftype=\OC_Helper::getSecureMimeType(\OC\Files\Filesystem::getMimeType( $filenam
 header('Content-Type:'.$ftype);
 OCP\Response::setContentDispositionHeader(basename($filename), 'attachment');
 OCP\Response::disableCaching();
-header('Content-Length: '.\OC\Files\Filesystem::filesize($filename));
+OCP\Response::setContentLengthHeader(\OC\Files\Filesystem::filesize($filename));
 
 OC_Util::obEnd();
 \OC\Files\Filesystem::readfile( $filename );
index e5139450f5ee5a50fb7fc01d37237637cbb176c6..c63fde5195401659e1008d5f2957673a77a09286 100644 (file)
@@ -38,7 +38,7 @@ $ftype = $view->getMimeType('/'.$uid.'/files/'.$filename);
 header('Content-Type:'.$ftype);
 OCP\Response::setContentDispositionHeader(basename($filename), 'attachment');
 OCP\Response::disableCaching();
-header('Content-Length: '.$view->filesize($versionName));
+OCP\Response::setContentLengthHeader($view->filesize($versionName));
 
 OC_Util::obEnd();
 
index b7df99c7d70a5130d40b77cec018f85f30bea40c..be08fd37d60aa7edd83eeb7c9a57397b1c94eff0 100644 (file)
@@ -48,7 +48,7 @@ class OC_Files {
                        $filesize = \OC\Files\Filesystem::filesize($filename);
                        header('Content-Type: '.\OC_Helper::getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename)));
                        if ($filesize > -1) {
-                               header("Content-Length: ".$filesize);
+                               OC_Response::setContentLengthHeader($filesize);
                        }
                }
        }
index 2bec5e3decd5235381e455ef7664268c6e5b00a3..7cd362ecdf3d2bee0fc5209f378fdeaf4024a466 100644 (file)
@@ -171,6 +171,27 @@ class OC_Response {
                }
        }
 
+       /**
+        * Sets the content length header (with possible workarounds)
+        * @param string|int|float $length Length to be sent
+        */
+       static public function setContentLengthHeader($length) {
+               if (PHP_INT_SIZE === 4) {
+                       if ($length > PHP_INT_MAX && stripos(PHP_SAPI, 'apache') === 0) {
+                               // Apache PHP SAPI casts Content-Length headers to PHP integers.
+                               // This enforces a limit of PHP_INT_MAX (2147483647 on 32-bit
+                               // platforms). So, if the length is greater than PHP_INT_MAX,
+                               // we just do not send a Content-Length header to prevent
+                               // bodies from being received incompletely.
+                               return;
+                       }
+                       // Convert signed integer or float to unsigned base-10 string.
+                       $lfh = new \OC\LargeFileHelper;
+                       $length = $lfh->formatUnsignedInteger($length);
+               }
+               header('Content-Length: '.$length);
+       }
+
        /**
        * Send file as response, checking and setting caching headers
        * @param string $filepath of file to send
@@ -181,7 +202,7 @@ class OC_Response {
                        self::setLastModifiedHeader(filemtime($filepath));
                        self::setETagHeader(md5_file($filepath));
 
-                       header('Content-Length: '.filesize($filepath));
+                       self::setContentLengthHeader(filesize($filepath));
                        fpassthru($fp);
                }
                else {
index 24d3c81d62807c8104be70e70de7a0bc04049f24..c32eb4a05e087cec59830608c1fc74394dd0c21c 100644 (file)
@@ -63,6 +63,14 @@ class Response {
                \OC_Response::setContentDispositionHeader( $filename, $type );
        }
 
+       /**
+        * Sets the content length header (with possible workarounds)
+        * @param string|int|float $length Length to be sent
+        */
+       static public function setContentLengthHeader($length) {
+               \OC_Response::setContentLengthHeader($length);
+       }
+
        /**
         * Disable browser caching
         * @see enableCaching with cache_time = 0