]> 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>
Sat, 4 Apr 2015 09:53:32 +0000 (11:53 +0200)
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 2fe56d2e6383e4089729b9d53f3b4409c0ced431..33d68c8c235cd879338a349784936467742bd8bd 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 a983f6f32f57a99457f91ae01d91f23903d94411..e6ba9a420dbf9aab13d57e3318050a61b04a60a6 100644 (file)
@@ -51,7 +51,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 caa382af77696b856b5d88e0626cb810c568e743..f8173117c4d4f5de84982ab2876ad04b1091467d 100644 (file)
@@ -170,6 +170,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
@@ -180,7 +201,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