Skip to content
Merged
Show file tree
Hide file tree
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
38 changes: 33 additions & 5 deletions tests/ImageProxyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function run(): void {
$this->testInvalidUtf8();
$this->testHtmlDocumentsAndTagSoup();
$this->testImageAttributes();
$this->testVideoPosters();
$this->testUriSchemes();
} catch (FreshRSS_Context_Exception $e) {
throw new RuntimeException('ImageProxy configuration failed', 0, $e);
Expand Down Expand Up @@ -163,6 +164,28 @@ private function testImageAttributes(): void {
$this->assertSame(false, $images[2]->hasAttribute('src'), 'Images without src must remain without src');
}

/** @throws FreshRSS_Context_Exception */
private function testVideoPosters(): void {
$input = '<video src="https://videos.example/one.mp4" poster="http://images.example/poster.jpg"></video>'
. '<video src="https://videos.example/two.mp4"></video>';
$output = ImageProxyExtension::swapUris($input);
$videos = $this->elements($output, 'video');

$this->assertSame(2, count($videos), 'All video elements must remain present');
$this->assertSame(
self::PROXY_URL . 'http://images.example/poster.jpg',
$videos[0]->getAttribute('poster'),
'Video posters must be proxied',
);
$this->assertSame(
'http://images.example/poster.jpg',
$videos[0]->getAttribute('data-xextension-imageproxy-original-poster'),
'Original poster must be retained',
);
$this->assertSame('https://videos.example/one.mp4', $videos[0]->getAttribute('src'), 'Video sources must not be proxied');
$this->assertSame(false, $videos[1]->hasAttribute('poster'), 'Videos without poster must remain without poster');
}

/** @throws FreshRSS_Context_Exception */
private function testUriSchemes(): void {
$this->assertSame(
Expand Down Expand Up @@ -197,14 +220,19 @@ private function textContent(string $html): string {

/** @return list<DOMElement> */
private function images(string $html): array {
return $this->elements($html, 'img');
}

/** @return list<DOMElement> */
private function elements(string $html, string $tagName): array {
$doc = $this->parseFragment($html);
$images = [];
foreach ($doc->getElementsByTagName('img') as $image) {
if ($image instanceof DOMElement) {
$images[] = $image;
$elements = [];
foreach ($doc->getElementsByTagName($tagName) as $element) {
if ($element instanceof DOMElement) {
$elements[] = $element;
}
}
return $images;
return $elements;
}

private function parseFragment(string $html): DOMDocument {
Expand Down
1 change: 1 addition & 0 deletions xExtension-ImageProxy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ To use it, upload this entire directory to the FreshRSS `./extensions` directory

## Changelog

* 1.0.3 Proxy the poster images of videos
* 1.0.1 Replace deprecated HTML entity conversion on PHP 8.2+
* 1.0 Breaking changes due to significant code upgrade: settings must be saved again
* 0.7.3 Turkish language support added
Expand Down
11 changes: 11 additions & 0 deletions xExtension-ImageProxy/extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ public static function swapUris(string $content): string {
}
}

// Video posters are images too; keep the original URL for the same reason as above
$videos = $doc->getElementsByTagName('video');
foreach ($videos as $video) {
if (!($video instanceof DOMElement) || !$video->hasAttribute('poster')) {
continue;
}
$poster = $video->getAttribute('poster');
$video->setAttribute('data-xextension-imageproxy-original-poster', $poster);
$video->setAttribute('poster', self::getProxyImageUri($poster));
}

$body = $doc->getElementsByTagName('body')->item(0);

$output = $doc->saveHTML($body);
Expand Down
2 changes: 1 addition & 1 deletion xExtension-ImageProxy/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Image Proxy",
"author": "Frans de Jonge",
"description": "No insecure content warnings or disappearing images.",
"version": "1.0.2",
"version": "1.0.3",
"entrypoint": "ImageProxy",
"type": "user"
}