Merge pull request #40233 from nextcloud/fix/fix-video-seeking-public-link

[stable25] Detect aborted connection in OC\Files\View and stop writing data to the output buffer
This commit is contained in:
Arthur Schiwon 2023-09-05 18:54:31 +02:00 committed by GitHub
commit cb607b5b8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 6 deletions

View file

@ -274,6 +274,7 @@ return array(
'OCP\\Files\\Config\\IMountProviderCollection' => $baseDir . '/lib/public/Files/Config/IMountProviderCollection.php',
'OCP\\Files\\Config\\IRootMountProvider' => $baseDir . '/lib/public/Files/Config/IRootMountProvider.php',
'OCP\\Files\\Config\\IUserMountCache' => $baseDir . '/lib/public/Files/Config/IUserMountCache.php',
'OCP\\Files\\ConnectionLostException' => $baseDir . '/lib/public/Files/ConnectionLostException.php',
'OCP\\Files\\DavUtil' => $baseDir . '/lib/public/Files/DavUtil.php',
'OCP\\Files\\EmptyFileNameException' => $baseDir . '/lib/public/Files/EmptyFileNameException.php',
'OCP\\Files\\EntityTooLargeException' => $baseDir . '/lib/public/Files/EntityTooLargeException.php',

View file

@ -307,6 +307,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Files\\Config\\IMountProviderCollection' => __DIR__ . '/../../..' . '/lib/public/Files/Config/IMountProviderCollection.php',
'OCP\\Files\\Config\\IRootMountProvider' => __DIR__ . '/../../..' . '/lib/public/Files/Config/IRootMountProvider.php',
'OCP\\Files\\Config\\IUserMountCache' => __DIR__ . '/../../..' . '/lib/public/Files/Config/IUserMountCache.php',
'OCP\\Files\\ConnectionLostException' => __DIR__ . '/../../..' . '/lib/public/Files/ConnectionLostException.php',
'OCP\\Files\\DavUtil' => __DIR__ . '/../../..' . '/lib/public/Files/DavUtil.php',
'OCP\\Files\\EmptyFileNameException' => __DIR__ . '/../../..' . '/lib/public/Files/EmptyFileNameException.php',
'OCP\\Files\\EntityTooLargeException' => __DIR__ . '/../../..' . '/lib/public/Files/EntityTooLargeException.php',

View file

@ -53,6 +53,7 @@ use OC\User\LazyUser;
use OCA\Files_Sharing\SharedMount;
use OCP\Constants;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\ConnectionLostException;
use OCP\Files\EmptyFileNameException;
use OCP\Files\FileNameTooLongException;
use OCP\Files\InvalidCharacterInPathException;
@ -425,10 +426,11 @@ class View {
}
$handle = $this->fopen($path, 'rb');
if ($handle) {
$chunkSize = 524288; // 512 kB chunks
$chunkSize = 524288; // 512 kiB chunks
while (!feof($handle)) {
echo fread($handle, $chunkSize);
flush();
$this->checkConnectionStatus();
}
fclose($handle);
return $this->filesize($path);
@ -481,6 +483,7 @@ class View {
}
echo fread($handle, $len);
flush();
$this->checkConnectionStatus();
}
return ftell($handle) - $from;
}
@ -490,6 +493,14 @@ class View {
return false;
}
private function checkConnectionStatus(): void {
$connectionStatus = \connection_status();
if ($connectionStatus !== CONNECTION_NORMAL) {
throw new ConnectionLostException("Connection lost. Status: $connectionStatus");
}
}
/**
* @param string $path
* @return mixed
@ -1053,7 +1064,6 @@ class View {
public function fromTmpFile($tmpFile, $path) {
$this->assertPathLength($path);
if (Filesystem::isValidPath($path)) {
// Get directory that the file is going into
$filePath = dirname($path);
@ -1809,7 +1819,6 @@ class View {
* @return boolean
*/
private function targetIsNotShared(IStorage $targetStorage, string $targetInternalPath) {
// note: cannot use the view because the target is already locked
$fileId = (int)$targetStorage->getCache()->getId($targetInternalPath);
if ($fileId === -1) {

View file

@ -233,14 +233,15 @@ class OC_Files {
OC::$server->getLogger()->logException($ex);
$l = \OC::$server->getL10N('lib');
\OC_Template::printErrorPage($l->t('Cannot download file'), $ex->getMessage(), 200);
} catch (\OCP\Files\ConnectionLostException $ex) {
self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
OC::$server->getLogger()->logException($ex, ['level' => \OCP\ILogger::DEBUG]);
\OC_Template::printErrorPage('Connection lost', $ex->getMessage(), 200);
} catch (\Exception $ex) {
self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
OC::$server->getLogger()->logException($ex);
$l = \OC::$server->getL10N('lib');
$hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
if ($event && $event->getErrorMessage() !== null) {
$hint .= ' ' . $event->getErrorMessage();
}
\OC_Template::printErrorPage($l->t('Cannot download file'), $hint, 200);
}
}

View file

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCP\Files;
/**
* Exception for lost connection with the
* @since 25.0.11
*/
class ConnectionLostException extends \RuntimeException {
}