Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,34 @@
const MAX_SCREENSHOT_SIZE = 2 * 1024 * 1024; // 2 MiB
const HTTP_TIMEOUT_S = 30;
const RETRY_BACKOFF_S = 6 * 3600; // don't retry a failed fetch more often than this
const PROXY_URL_PREFIX = 'https://usercontent.apps.nextcloud.com/';

/**
* The app store serves screenshot URLs already pointing at this proxy, so the
* cache key is the path of that URL and the source URL is its decoded form.
* URLs not in that form are the source URL itself, as the app store served
* them before.
*
* @param string $url screenshot URL as served by the app store
* @return array{string, string}|null cache key and source URL, or null if the key is not valid base64url
*/
function resolveScreenshotUrl(string $url): ?array {
if (!str_starts_with($url, PROXY_URL_PREFIX)) {
return [strtr(base64_encode($url), '+/', '-_'), $url];
}

$base64Url = substr($url, strlen(PROXY_URL_PREFIX));
if (preg_match('/^[A-Za-z0-9_-]+={0,2}$/', $base64Url) !== 1) {
return null;
}

$sourceUrl = base64_decode(strtr($base64Url, '-_', '+/'), true);
if ($sourceUrl === false) {
return null;
}

return [$base64Url, $sourceUrl];
}

/**
* @param string $cacheUrl path to screenshot in cache
Expand Down Expand Up @@ -169,14 +197,18 @@ function (string $ip) use ($host, $port): string {
* @param array $screenshot decoded JSON of a single screenshot entry
*/
function handleScreenshot(UrlValidator $validator, array $screenshot): void {
$url = $screenshot['url'];
$resolved = resolveScreenshotUrl($screenshot['url']);
if ($resolved === null) {
return;
}

[$base64Url, $url] = $resolved;
$trimmedUrl = trim($url);

if (!str_starts_with($trimmedUrl, 'https://')) {
return;
}

$base64Url = strtr(base64_encode($url), '+/', '-_');
$cacheUrl = __DIR__ . '/cache/' . $base64Url;
$failMarker = __DIR__ . '/cache-failed/' . $base64Url;

Expand Down