Skip to content

Commit 0634b62

Browse files
authored
Merge pull request #54487 from nextcloud/backport/54402/stable31
[stable31] fix(Streamer): use localtime for ZIP files
2 parents c7f8afb + 3e61569 commit 0634b62

File tree

5 files changed

+28
-5
lines changed

5 files changed

+28
-5
lines changed

apps/dav/lib/Connector/Sabre/ServerFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use OCP\Files\IFilenameValidator;
2121
use OCP\Files\Mount\IMountManager;
2222
use OCP\IConfig;
23+
use OCP\IDateTimeZone;
2324
use OCP\IDBConnection;
2425
use OCP\IL10N;
2526
use OCP\IPreview;
@@ -79,6 +80,7 @@ public function createServer(string $baseUri,
7980
$objectTree,
8081
$this->logger,
8182
$this->eventDispatcher,
83+
\OCP\Server::get(IDateTimeZone::class),
8284
));
8385

8486
// Some WebDAV clients do require Class 2 WebDAV support (locking), since

apps/dav/lib/Connector/Sabre/ZipFolderPlugin.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use OCP\Files\File as NcFile;
1616
use OCP\Files\Folder as NcFolder;
1717
use OCP\Files\Node as NcNode;
18+
use OCP\IDateTimeZone;
1819
use Psr\Log\LoggerInterface;
1920
use Sabre\DAV\Server;
2021
use Sabre\DAV\ServerPlugin;
@@ -41,6 +42,7 @@ public function __construct(
4142
private Tree $tree,
4243
private LoggerInterface $logger,
4344
private IEventDispatcher $eventDispatcher,
45+
private IDateTimeZone $timezoneFactory,
4446
) {
4547
}
4648

@@ -163,7 +165,7 @@ public function handleDownload(Request $request, Response $response): ?bool {
163165
// Full folder is loaded to rename the archive to the folder name
164166
$archiveName = $folder->getName();
165167
}
166-
$streamer = new Streamer($tarRequest, -1, count($content));
168+
$streamer = new Streamer($tarRequest, -1, count($content), $this->timezoneFactory);
167169
$streamer->sendHeaders($archiveName);
168170
// For full folder downloads we also add the folder itself to the archive
169171
if (empty($files)) {

apps/dav/lib/Server.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
use OCP\IAppConfig;
7676
use OCP\ICacheFactory;
7777
use OCP\IConfig;
78+
use OCP\IDateTimeZone;
7879
use OCP\IPreview;
7980
use OCP\IRequest;
8081
use OCP\IUserSession;
@@ -230,6 +231,7 @@ public function __construct(
230231
$this->server->tree,
231232
$logger,
232233
$eventDispatcher,
234+
\OCP\Server::get(IDateTimeZone::class),
233235
));
234236
$this->server->addPlugin(\OCP\Server::get(PaginatePlugin::class));
235237

lib/private/Streamer.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OCP\Files\IRootFolder;
1515
use OCP\Files\NotFoundException;
1616
use OCP\Files\NotPermittedException;
17+
use OCP\IDateTimeZone;
1718
use OCP\IRequest;
1819
use ownCloud\TarStreamer\TarStreamer;
1920
use Psr\Log\LoggerInterface;
@@ -40,7 +41,12 @@ public static function isUserAgentPreferTar(IRequest $request): bool {
4041
* @param int $numberOfFiles The number of files (and directories) that will
4142
* be included in the streamed file
4243
*/
43-
public function __construct(IRequest|bool $preferTar, int|float $size, int $numberOfFiles) {
44+
public function __construct(
45+
IRequest|bool $preferTar,
46+
int|float $size,
47+
int $numberOfFiles,
48+
private IDateTimeZone $timezoneFactory,
49+
) {
4450
if ($preferTar instanceof IRequest) {
4551
$preferTar = self::isUserAgentPreferTar($preferTar);
4652
}
@@ -156,7 +162,7 @@ public function addFileFromStream($stream, string $internalName, int|float $size
156162
$options = [];
157163
if ($time) {
158164
$options = [
159-
'timestamp' => $time
165+
'timestamp' => $this->fixTimestamp($time),
160166
];
161167
}
162168

@@ -176,7 +182,7 @@ public function addFileFromStream($stream, string $internalName, int|float $size
176182
public function addEmptyDir(string $dirName, int $timestamp = 0): bool {
177183
$options = null;
178184
if ($timestamp > 0) {
179-
$options = ['timestamp' => $timestamp];
185+
$options = ['timestamp' => $this->fixTimestamp($timestamp)];
180186
}
181187

182188
return $this->streamerInstance->addEmptyDir($dirName, $options);
@@ -191,4 +197,14 @@ public function addEmptyDir(string $dirName, int $timestamp = 0): bool {
191197
public function finalize() {
192198
return $this->streamerInstance->finalize();
193199
}
200+
201+
private function fixTimestamp(int $timestamp): int {
202+
if ($this->streamerInstance instanceof ZipStreamer) {
203+
// Zip does not support any timezone information
204+
// while tar is interpreted as Unix time the Zip time is interpreted as local time of the user...
205+
$zone = $this->timezoneFactory->getTimeZone($timestamp);
206+
$timestamp += $zone->getOffset(new \DateTimeImmutable('@' . (string)$timestamp));
207+
}
208+
return $timestamp;
209+
}
194210
}

lib/public/AppFramework/Http/ZipResponse.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use OC\Streamer;
1111
use OCP\AppFramework\Http;
12+
use OCP\IDateTimeZone;
1213
use OCP\IRequest;
1314

1415
/**
@@ -65,7 +66,7 @@ public function callback(IOutput $output) {
6566
$size += $resource['size'];
6667
}
6768

68-
$zip = new Streamer($this->request, $size, $files);
69+
$zip = new Streamer($this->request, $size, $files, \OCP\Server::get(IDateTimeZone::class));
6970
$zip->sendHeaders($this->name);
7071

7172
foreach ($this->resources as $resource) {

0 commit comments

Comments
 (0)