Overview
Comment:Finally found the issue with NextCloud Android and thumbnails, it's fixed
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: 1c9151c6e28ce4e15fc4c4e3a9315dbafa8339649ab6917f220c86f76ce643d9
User & Date: bohwaz on 2022-11-27 21:49:41
Other Links: branch diff | manifest | tags
Context
2022-11-27
21:57
NextCloud: Use new method signature check-in: 2347e7a3d3 user: bohwaz tags: dev
21:49
Finally found the issue with NextCloud Android and thumbnails, it's fixed check-in: 1c9151c6e2 user: bohwaz tags: dev
21:18
Use new serveThumbnail method check-in: ef96b639fc user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Entities/Files/File.php from [5573352f35] to [82839dbcec].

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545

			if (!$can_access && $this->checkShareLinkRequiresPassword($share_hash)) {
				$tpl = Template::getInstance();
				$has_password = (bool) $share_password;

				$tpl->assign(compact('can_access', 'has_password'));
				$tpl->display('ask_share_password.tpl');
				exit;
			}
		}

		if (!$can_access) {
			header('HTTP/1.1 403 Forbidden', true, 403);
			throw new UserException('Vous n\'avez pas accès à ce fichier.');
			return;
		}

		// Only simple files can be served, not directories
		if ($this->type != self::TYPE_FILE) {
			header('HTTP/1.1 404 Not Found', true, 404);
			throw new UserException('Page non trouvée');
		}

		$path = Files::callStorage('getFullPath', $this);
		$content = null === $path ? Files::callStorage('fetch', $this) : null;

		$this->_serve($path, $content, $download);
	}







|





|






|







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545

			if (!$can_access && $this->checkShareLinkRequiresPassword($share_hash)) {
				$tpl = Template::getInstance();
				$has_password = (bool) $share_password;

				$tpl->assign(compact('can_access', 'has_password'));
				$tpl->display('ask_share_password.tpl');
				return;
			}
		}

		if (!$can_access) {
			header('HTTP/1.1 403 Forbidden', true, 403);
			throw new UserException('Vous n\'avez pas accès à ce fichier.', 403);
			return;
		}

		// Only simple files can be served, not directories
		if ($this->type != self::TYPE_FILE) {
			header('HTTP/1.1 404 Not Found', true, 404);
			throw new UserException('Page non trouvée', 404);
		}

		$path = Files::callStorage('getFullPath', $this);
		$content = null === $path ? Files::callStorage('fetch', $this) : null;

		$this->_serve($path, $content, $download);
	}
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
	}

	/**
	 * Envoie une miniature à la taille indiquée au client HTTP
	 */
	public function serveThumbnail(?Session $session = null, string $size = null): void
	{
		if (!$this->canRead()) {
			header('HTTP/1.1 403 Forbidden', true, 403);
			throw new UserException('Accès interdit');
			return;
		}

		if (!$this->image) {
			throw new UserException('Il n\'est pas possible de fournir une miniature pour un fichier qui n\'est pas une image.');
		}








|

|







558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
	}

	/**
	 * Envoie une miniature à la taille indiquée au client HTTP
	 */
	public function serveThumbnail(?Session $session = null, string $size = null): void
	{
		if (!$this->canRead($session)) {
			header('HTTP/1.1 403 Forbidden', true, 403);
			throw new UserException('Accès interdit', 403);
			return;
		}

		if (!$this->image) {
			throw new UserException('Il n\'est pas possible de fournir une miniature pour un fichier qui n\'est pas une image.');
		}

Modified src/include/lib/Garradin/Files/WebDAV/NextCloud.php from [b4f1637737] to [4b1e5dbc60].

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
<?php

namespace Garradin\Files\WebDAV;

use KD2\WebDAV\NextCloud as WebDAV_NextCloud;
use KD2\WebDAV\Exception as WebDAV_Exception;

use Garradin\Config;
use Garradin\Utils;

use Garradin\Files\Files;
use Garradin\Entities\Files\File;

use const Garradin\{SECRET_KEY, ADMIN_URL, CACHE_ROOT, WWW_URL, ROOT};

class NextCloud extends WebDAV_NextCloud
{









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace Garradin\Files\WebDAV;

use KD2\WebDAV\NextCloud as WebDAV_NextCloud;
use KD2\WebDAV\Exception as WebDAV_Exception;

use Garradin\Config;
use Garradin\Utils;
use Garradin\UserException;
use Garradin\Files\Files;
use Garradin\Entities\Files\File;

use const Garradin\{SECRET_KEY, ADMIN_URL, CACHE_ROOT, WWW_URL, ROOT};

class NextCloud extends WebDAV_NextCloud
{
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
	public function serveThumbnail(string $uri, int $width, int $height, bool $crop = false): void
	{
		if (!preg_match('/\.(?:jpe?g|gif|png|webp)$/', $uri)) {
			http_response_code(404);
			return;
		}

		// NextCloud Android just cannot display thumbnails, not sure why
		if (false !== strpos($_SERVER['HTTP_USER_AGENT'] ?? '', 'Nextcloud-android')) {
			http_response_code(404);
			echo 'Banned client';
			return;
		}

		$this->requireAuth();
		$uri = preg_replace(self::WEBDAV_BASE_REGEXP, '', $uri);
		$file = Files::get(File::CONTEXT_DOCUMENTS . '/' . $uri);

		if (!$file) {
			throw new WebDAV_Exception('Not found', 404);
		}







<
<
<
<
<
<
<







204
205
206
207
208
209
210







211
212
213
214
215
216
217
	public function serveThumbnail(string $uri, int $width, int $height, bool $crop = false): void
	{
		if (!preg_match('/\.(?:jpe?g|gif|png|webp)$/', $uri)) {
			http_response_code(404);
			return;
		}








		$this->requireAuth();
		$uri = preg_replace(self::WEBDAV_BASE_REGEXP, '', $uri);
		$file = Files::get(File::CONTEXT_DOCUMENTS . '/' . $uri);

		if (!$file) {
			throw new WebDAV_Exception('Not found', 404);
		}
232
233
234
235
236
237
238




239




240
241
242
243
244
245
246
		elseif ($width >= 500 || $height >= 500) {
			$size = '500px';
		}
		else {
			$size = '150px';
		}





		$file->serveThumbnail(Session::getInstance(), $size);




	}

	protected function nc_avatar(): void
	{
		header('X-NC-IsCustomAvatar: 1');

		$file = Config::getInstance()->file('icon');







>
>
>
>
|
>
>
>
>







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
		elseif ($width >= 500 || $height >= 500) {
			$size = '500px';
		}
		else {
			$size = '150px';
		}

		$session = Session::getInstance();
		$this->server->log('Serving thumbnail for: %s - size: %s', $uri, $size);

		try {
			$file->serveThumbnail($session, $size);
		}
		catch (UserException $e) {
			throw new WebDAV_Exception($e->getMessage(), $e->getCode(), $e);
		}
	}

	protected function nc_avatar(): void
	{
		header('X-NC-IsCustomAvatar: 1');

		$file = Config::getInstance()->file('icon');

Modified src/include/lib/Garradin/Files/WebDAV/Storage.php from [c1d60c1323] to [e014658bf9].

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
	 */
	const PUT_IGNORE_PATTERN = '!^~(?:lock\.|^\._)|^(?:\.DS_Store|Thumbs\.db|desktop\.ini)$!';

	protected ?array $cache = null;
	protected array $root = [];

	protected NextCloud $nextcloud;
	protected bool $can_preview;

	public function __construct(NextCloud $nextcloud)
	{
		$this->nextcloud = $nextcloud;
		// NextCloud Android just cannot display previews/thumbnails
		$this->can_preview = false === strpos($_SERVER['HTTP_USER_AGENT'] ?? '', 'Nextcloud-android');
	}

	protected function populateRootCache(): void
	{
		if (isset($this->cache)) {
			return;
		}







<




<
<







24
25
26
27
28
29
30

31
32
33
34


35
36
37
38
39
40
41
	 */
	const PUT_IGNORE_PATTERN = '!^~(?:lock\.|^\._)|^(?:\.DS_Store|Thumbs\.db|desktop\.ini)$!';

	protected ?array $cache = null;
	protected array $root = [];

	protected NextCloud $nextcloud;


	public function __construct(NextCloud $nextcloud)
	{
		$this->nextcloud = $nextcloud;


	}

	protected function populateRootCache(): void
	{
		if (isset($this->cache)) {
			return;
		}
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
				if ($file->type != File::TYPE_FILE) {
					return null;
				}

				return md5_file($file->fullpath());
			// NextCloud stuff
			case NextCloud::PROP_NC_HAS_PREVIEW:
				return $file->image && $this->can_preview ? 'true' : 'false';
			case NextCloud::PROP_NC_IS_ENCRYPTED:
				return 'false';
			case NextCloud::PROP_OC_SHARETYPES:
				return WebDAV::EMPTY_PROP_VALUE;
			case NextCloud::PROP_OC_DOWNLOADURL:
				return $this->nextcloud->getDirectURL($uri, $session::getUserId());
			case Nextcloud::PROP_NC_RICH_WORKSPACE:







|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
				if ($file->type != File::TYPE_FILE) {
					return null;
				}

				return md5_file($file->fullpath());
			// NextCloud stuff
			case NextCloud::PROP_NC_HAS_PREVIEW:
				return $file->image ? 'true' : 'false';
			case NextCloud::PROP_NC_IS_ENCRYPTED:
				return 'false';
			case NextCloud::PROP_OC_SHARETYPES:
				return WebDAV::EMPTY_PROP_VALUE;
			case NextCloud::PROP_OC_DOWNLOADURL:
				return $this->nextcloud->getDirectURL($uri, $session::getUserId());
			case Nextcloud::PROP_NC_RICH_WORKSPACE: