Skip to content

Commit

Permalink
fix: use updated user agent when fetching feeds and favicons
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Vidulich <ben@vidulich.nz>
  • Loading branch information
zl4bv authored and Grotax committed Oct 3, 2024
1 parent ad9f614 commit 32d02c0
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ You can also check [on GitHub](https://github.com/nextcloud/news/releases), the


### Fixed
- Use updated user agent when fetching feeds and favicons (#2788)

Check failure on line 13 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'favicons'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'favicons'?", "location": {"path": "CHANGELOG.md", "range": {"start": {"line": 13, "column": 50}}}, "severity": "ERROR"}
- Allow feed title to be null in DB. (#2745)
- Store HTTP last modified date from response header (#2724)
- Admin settings could not be saved (#2533)
Expand Down
7 changes: 7 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\App;

use OCA\News\Fetcher\FaviconDataAccess;
use OCA\News\Fetcher\FeedFetcher;
use OCA\News\Fetcher\Fetcher;
use OCP\User\Events\BeforeUserDeletedEvent;
Expand Down Expand Up @@ -135,9 +136,15 @@ public function register(IRegistrationContext $context): void
return new Explorer($config->getClient(), $c->get(LoggerInterface::class));
});

$context->registerService(FaviconDataAccess::class, function (ContainerInterface $c): FaviconDataAccess {
$config = $c->get(FetcherConfig::class);
return new FaviconDataAccess($config);
});

$context->registerService(Favicon::class, function (ContainerInterface $c): Favicon {
$favicon = new Favicon();
$favicon->cache(['dir' => $c->get(Cache::class)->getCache("feedFavicon")]);
$favicon->setDataAccess($c->get(FaviconDataAccess::class));
return $favicon;
});
}
Expand Down
27 changes: 26 additions & 1 deletion lib/Config/FetcherConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ class FetcherConfig
*/
protected $redirects;

/**
* Version number for the news application.
* @var string
*/
private $version;

/**
* User agent for the client.
* @var string
Expand Down Expand Up @@ -75,6 +81,11 @@ public function __construct(IConfig $config)
'maxRedirects',
Application::DEFAULT_SETTINGS['maxRedirects']
);
$this->version = $config->getAppValue(

Check failure on line 84 in lib/Config/FetcherConfig.php

View workflow job for this annotation

GitHub Actions / phpstan: Nextcloud pre-release with 8.2

Call to deprecated method getAppValue() of interface OCP\IConfig: 29.0.0 Use {@see IAppConfig} directly
Application::NAME,
'installed_version',
'1.0'
);

$proxy = $config->getSystemValue('proxy', null);
if (is_null($proxy)) {
Expand Down Expand Up @@ -127,7 +138,7 @@ public function getClient(): ClientInterface
$config = [
'timeout' => $this->client_timeout,
'headers' => [
'User-Agent' => static::DEFAULT_USER_AGENT,
'User-Agent' => $this->getUserAgent(),
'Accept' => static::DEFAULT_ACCEPT,
'Accept-Encoding' => $this->checkEncoding()
],
Expand All @@ -143,4 +154,18 @@ public function getClient(): ClientInterface
$client = new Client($config);
return new FeedIoClient($client);
}

/**
* Gets a user agent name for the client
*
* @return string
*/
public function getUserAgent(): string
{
if (is_null($this->version)) {
return self::DEFAULT_USER_AGENT;
}

return 'NextCloud-News/' . $this->version;
}
}
61 changes: 61 additions & 0 deletions lib/Fetcher/FaviconDataAccess.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Ben Vidulich <ben@vidulich.nz>
* @copyright 2024 Ben Vidulich
*/

namespace OCA\News\Fetcher;

use Favicon\DataAccess;

use OCA\News\Config\FetcherConfig;

/**
* Modified version of DataAccess with a configurable user agent header.
*/
class FaviconDataAccess extends DataAccess
{
/**
* @var FetcherConfig
*/
private $fetcherConfig;

public function __construct(
FetcherConfig $fetcherConfig,
) {
$this->fetcherConfig = $fetcherConfig;
}

public function retrieveUrl($url)
{
$this->setContext();
return @file_get_contents($url);
}

public function retrieveHeader($url)
{
$this->setContext();
$headers = @get_headers($url, 1);
return is_array($headers) ? array_change_key_case($headers) : [];
}

private function setContext()
{
stream_context_set_default(
[
'http' => [
'method' => 'GET',
'follow_location' => 0,
'max_redirects' => 1,
'timeout' => 10,
'header' => 'User-Agent: ' . $this->fetcherConfig->getUserAgent(),
]
]
);
}
}
2 changes: 1 addition & 1 deletion lib/Fetcher/FeedFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ protected function getFavicon(FeedInterface $feed, string $url): ?string
$favicon = trim($feed_logo);
}

ini_set('user_agent', FetcherConfig::DEFAULT_USER_AGENT);
ini_set('user_agent', $this->fetcherConfig->getUserAgent());

$base_url = new Net_URL2($url);
$base_url->setPath("");
Expand Down
31 changes: 31 additions & 0 deletions tests/Unit/Config/FetcherConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,35 @@ public function testGetClient()

$this->assertInstanceOf(FeedIoClient::class, $this->class->getClient());
}

public function testGetUserAgent()
{
$this->config->expects($this->exactly(3))
->method('getAppValue')
->willReturnMap([
['news', 'feedFetcherTimeout', 60, '60'],
['news', 'maxRedirects', 10, '10'],
['news', 'installed_version', '1.0', '123.45']
]);
$this->class = new FetcherConfig($this->config);

$expected = 'NextCloud-News/123.45';
$response = $this->class->getUserAgent();
$this->assertEquals($expected, $response);
}

public function testGetUserAgentUnknownVersion()
{
$this->config->expects($this->exactly(3))
->method('getAppValue')
->willReturnMap([
['news', 'feedFetcherTimeout', 60, '60'],
['news', 'maxRedirects', 10, '10']
]);
$this->class = new FetcherConfig($this->config);

$expected = 'NextCloud-News/1.0';
$response = $this->class->getUserAgent();
$this->assertEquals($expected, $response);
}
}

0 comments on commit 32d02c0

Please sign in to comment.