Skip to content

Fix cache_expiration_time#883

Merged
jtojnar merged 5 commits intosimplepie:masterfrom
FreshRSS:cache_expiration_time
Sep 29, 2024
Merged

Fix cache_expiration_time#883
jtojnar merged 5 commits intosimplepie:masterfrom
FreshRSS:cache_expiration_time

Conversation

@Alkarex
Copy link
Contributor

@Alkarex Alkarex commented Sep 14, 2024

Fix cache handling logic and associated tests.
fix #830 ([BUG] Cache constantly updating).
Note: the default cache implementation (legacy file cache) is still broken for allowing HTTP 304.
Replaces #846

@Alkarex
Copy link
Contributor Author

Alkarex commented Sep 14, 2024

Requires #878 first to pass the CI

@Alkarex Alkarex mentioned this pull request Sep 25, 2024
4 tasks
@jtojnar jtojnar self-requested a review September 25, 2024 20:43
Copy link
Member

@jtojnar jtojnar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. I think it would probably be cleanest to include the -1 hack in the original PR since it originally fixed the bug, and leave this one for the (IIUC) separate bug of cache_expiration_time not being updated on force_cache_fallback304.

}
// Check if the cache has been updated
elseif (isset($this->data['cache_expiration_time']) && $this->data['cache_expiration_time'] > time()) {
elseif (empty($this->data['cache_expiration_time']) || $this->data['cache_expiration_time'] < time()) {
Copy link
Member

@jtojnar jtojnar Sep 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty() is overly broad (responds to (unset)|null|false|0|0.0|[]|""|"0"), and should IMO never be used in properly typed code. !isset() would be better, or even array_key_exists(), since the former still fails for (unset)|null.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, looking at the SimplePie.php and searching for cache->set_data|this->data, I see only the following ways $this->data['cache_expiration_time'] can be unset when $this->data is not empty:

  • Consumer does not respect @access private and removes it from $this->data 💀
  • Parser does not detect any feed during init – we should probably clear the $this->data when that happens.
  • Cache is corrupted 😱
  • get_type(), get_items() or any method calling them is called without calling init(). This probably will not happen in practice as the result would be useless.

On the other hand

  • Line 1894 looks like it should not have the expiration time set at first glance but since it is conditional on being non-empty and it only extends $this->data, it must be set since it was populated elsewhere.

So this isset probably only serves to appease PHPStan in practice and && should be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair preference for isset here but not array_key_exists() as there would be a null vs. int inequality right after

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding &&, rather not. If for any reason cache_expiration_time is not set, I would want my cache to expire as soon as possible


if ($this->force_cache_fallback) {
$this->data['cache_expiration_time'] = $this->cache_duration + time();
$cache->set_data($cacheKey, $this->data, $this->cache_duration);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand this correctly, this just extends the cache lifetime ($this->data remains the same). Not sure why bb38d74 made SimplePie store cache_expiration_time in the cache when set_data already takes TTL but it makes sense to update cache_expiration_time here too.

Probably should be a separate commit from the test fix, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are still related to cache, and were preventing this PR from passing the tests, but can be put in another PR

Copy link
Contributor

@Art4 Art4 Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtojnar $this->data['cache_expiration_time'] was introduced to allow mimic the functionality of mtime() and touch(), because that allowed us to use the cached data even if it was expired.

Copy link
Member

@jtojnar jtojnar Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe we should just pass TTL as null (unlimited) to Psr16 caches, and have another layer that would emulate the old mtime()/touch() API, if we want to have access to expired cache entries. I do not see how can we fix the cache fallback/304 otherwise.

In the long term, we can probably come up with a nicer API though. For example, we could have a class CacheWrapper that would handle expiration and invalidation transparently – it could store the cache entry as follows

/** @type CacheEntry array{mtime: int, extraKeys: array<string, mixed>, value: mixed} */

and be used something like this:

$cacheWrapper = new CacheWrapper(new Psr16($this->cache), $this->cache_duration);

$this->data = $cacheWrapper->get(
    $key,
    // Extra validation keys, since the allowed size of `$key` is limited.
    // If value of any of the keys does not match the one in the `extraKeys` array,
    // the value will be considered stale and one of the following actions will be performed.
    [
        // Different version of SimplePie might have unrecognizable structure of the cache data
        // so pass `null` as `$staleData` to the callback.
        ['key' => 'build', 'expected' => Misc::get_build(), 'action' => CacheWrapper::INVALID_ACTION_DISCARD],
        // A collision. Cause the value returned by the callback to be returned by `CacheWrapper::get()` but the cache would not be updated.
        // I guess this could also be handled transparently by having the `CacheWrapper` store it in `CacheEntry`.
        ['key' => 'url', 'expected' => $this->feed_url, 'action' => CacheWrapper::INVALID_ACTION_COLLISION],
        // …
    ],
    // This callback will be executed when the cache lacks the key, or it is invalid.
    // `$staleData` will be null if the key did not exist.
    // The cache will be updated with the returned value and the mtime will be updated.
    // Except maybe when exception occurs, then we might want to unset the cache and propagate the exception.
    function(?array $staleData) use (&$obtainedFromCache): array {
        $headers = [];
        if ($staleData !== null && isset($staleData['headers']['etag'])) {
            $headers['etag'] = $staleData['headers']['etag'];
        }

        $file = fetch($url, $headers);

        if ($this->status_code === 304) {
            $obtainedFromCache = true;
            return $staleData;
        }

        // …

        return  [
            'url' => $this->feed_url,
            'feed_url' => $file->get_final_requested_uri(),
            'build' => Misc::get_build(),
            'cache_expiration_time' => $this->cache_duration + time(),
        ];
    }
);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to address this potential refactoring in another PR though :-)
The current PR fixes some relatively obvious bugs, so merging it would already be beneficial

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. Regarding the tests, the change is due to the fix of the inequality higher up, so they are directly related

$this->status_code = 0;

if ($this->force_cache_fallback) {
$this->data['cache_expiration_time'] = $this->cache_duration + time();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also probably want to do the same for 304 response.

Copy link
Contributor Author

@Alkarex Alkarex Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I was wondering why does not the in-cache TTL remove the entry when it expires, which would break the 304 and it does, as you found out in https://github.com/FreshRSS/simplepie/blob/5e92ce767597aa9f5cbb00d88c7591b2e604dc5f/src/Cache/BaseDataCache.php#L58-L62

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can happily send upstream more of the fixes / improvements, but best after some of the existing pending PRs are processed

@Alkarex Alkarex requested a review from Art4 September 27, 2024 11:15
@Alkarex
Copy link
Contributor Author

Alkarex commented Sep 27, 2024

@Art4 As far as this PR goes (and excluding future fixes / refactoring), isn't it also good from your point of you?

}
// Check if the cache has been updated
elseif (isset($this->data['cache_expiration_time']) && $this->data['cache_expiration_time'] > time()) {
elseif (!isset($this->data['cache_expiration_time']) || $this->data['cache_expiration_time'] < time()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading the explanations from both of you I think this PR is reasonable.

The last remaining thing not clear to me is how it can this patch fix anything without https://github.com/FreshRSS/simplepie/blob/5e92ce767597aa9f5cbb00d88c7591b2e604dc5f/src/Cache/BaseDataCache.php#L58-L62

If we use the same $this->cache_duration as TTL passed to $cache->set_data() and to $this->data['cache_expiration_time'], I would expect that if the cache expires, the following would return the default empty array, and the above line would never be executed, as it is within if (!empty($this->data)):

$this->data = $cache->get_data($cacheKey, []);

Copy link
Contributor Author

@Alkarex Alkarex Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how it can this patch fix anything

This patch will fix some cases when the internal TTL has not expired yet. I think this is needed in any case.

But I completely agree that to have a working 304 cache, more fixes of the logic are needed. This PR focusses on the straightforward bugs in the current logic, which are needed no matter what, and should not be controversial (hopefully).

P.S.: In other words, to properly test the behaviour of the current logic, this PR is needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how could the internal TTL not have expired when $this->data['cache_expiration_time'] did – are not they set to the same cache duration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the default cache implementation ("legacy file cache") is still broken, I believe passing another implementation might work (but I have not investigated in details)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, alright. We can set the TTL to null in all set_data calls in a follow up PR to actually fix it then.

@Art4
Copy link
Contributor

Art4 commented Sep 27, 2024

@Alkarex I hope I'll find some time reviewing this PR later today.

@Alkarex
Copy link
Contributor Author

Alkarex commented Sep 28, 2024

@jtojnar With all the commits in this PR and associated approvals and comments, I believe a squash and merge would be good, making sure to put in the commit message for instance the text describing this PR all the way up (which I have just edited).
But as you prefer, I do not really mind 🙂

Copy link
Member

@jtojnar jtojnar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, squash merge makes sense here.

I propose something like the following commit message:

Set cache_expiration_time when storing data to cache

When we switched to PSR-16 inspired DataCache in bb38d74, we introduced a regression due to impedance mismatch between PSR-16 and HTTP Caching mechanisms:

  • HTTP caching uses two step invalidation – if a cache entry is accessed after its TTL passes, a request is made with a stored HTTP caching header (e.g. ETag) and the cache is considered invalid only if the server returns something else than 304 Not Modified response.
  • On the other hand, PSR-16 cache does not allow access to entries past its TTL, forcing us to fetch the content every time, even when the remote server could tell us it is still fine.

To work around this, bb38d74 decided to store cache_expiration_time field in the cache entry so that we could bypass the PSR-16’s strict TTL and handle expiration ourselves. But there were few places where we forgot to set it. This patch fixes that.

Unfortunately, because we also pass the same value as cache_expiration_time to DataCache::set_data as TTL, the early eviction still happens. We will also need to set the TTL to null (unlimited) so that the DataCache does not evict the entries behind our back.

Partly fixes #830 ([BUG] Cache constantly updating)

This the context according to my understanding, hope I did not miss something.

@jtojnar jtojnar merged commit 194f8ff into simplepie:master Sep 29, 2024
@Alkarex Alkarex deleted the cache_expiration_time branch September 29, 2024 11:08
Alkarex added a commit to FreshRSS/simplepie that referenced this pull request Sep 29, 2024
Alkarex added a commit to Alkarex/FreshRSS that referenced this pull request Sep 29, 2024
FreshRSS upstream PR merged simplepie/simplepie#883
Alkarex added a commit to FreshRSS/FreshRSS that referenced this pull request Sep 29, 2024
@jtojnar jtojnar mentioned this pull request Sep 29, 2024
7 tasks
@Art4 Art4 added this to the 1.9.0 milestone Sep 30, 2024
Sh4kE added a commit to Sh4kE/freshrss-helm-chart that referenced this pull request Feb 24, 2025
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [freshrss](https://github.com/FreshRSS/FreshRSS) | minor | `1.24.3` -> `1.26.0` |

---

### Release Notes

<details>
<summary>FreshRSS/FreshRSS (freshrss)</summary>

### [`v1.26.0`](https://github.com/FreshRSS/FreshRSS/blob/HEAD/CHANGELOG.md#2025-02-23-FreshRSS-1260)

[Compare Source](FreshRSS/FreshRSS@1.25.0...1.26.0)

-   Features
    -   Add order-by options to sort articles by received date (existing, default), publication date, title, link, random [#&#8203;7149](FreshRSS/FreshRSS#7149)
    -   Allow searching in all feeds, also feeds only visible at category level with `&get=A`, and also those archived with `&get=Z` [#&#8203;7144](FreshRSS/FreshRSS#7144)
        -   UI accessible from user-query view
    -   Add search operator `intext:` [#&#8203;7228](FreshRSS/FreshRSS#7228)
    -   New shortcuts for adding user labels to articles [#&#8203;7274](FreshRSS/FreshRSS#7274)
    -   New *About* page with system information [#&#8203;7161](FreshRSS/FreshRSS#7161)
-   Bug fixing
    -   Fix regression denying access to app manifest [#&#8203;7158](FreshRSS/FreshRSS#7158)
    -   Fix unwanted feed description updates [#&#8203;7269](FreshRSS/FreshRSS#7269)
    -   Ensure no PHP buffer for SQLite download (some setups would first put the file in memory) [#&#8203;7230](FreshRSS/FreshRSS#7230)
    -   Fix XML encoding regression in HTML+XPath mode [#&#8203;7345](FreshRSS/FreshRSS#7345)
    -   Improve cURL proxy options and fix some constants [#&#8203;7231](FreshRSS/FreshRSS#7231)
    -   Fix UI of global view unread articles counter [#&#8203;7247](FreshRSS/FreshRSS#7247)
    -   Hide base theme in carrousel [#&#8203;7234](FreshRSS/FreshRSS#7234)
-   Deployment
    -   Reduce superfluous Docker builds [#&#8203;7137](FreshRSS/FreshRSS#7137)
    -   Docker default image (Debian 12 Bookworm) updated to PHP 8.2.26 and Apache 2.4.62
    -   Docker alternative image (Alpine 3.21) updated to PHP 8.3.16
-   UI
    -   Add footer icons to reader view [#&#8203;7133](FreshRSS/FreshRSS#7133)
    -   Remove local reference to font *Open Sans* to avoid bugs with some local versions [#&#8203;7215](FreshRSS/FreshRSS#7215)
    -   Improve stats page layout [#&#8203;7243](FreshRSS/FreshRSS#7243)
    -   Smaller *mark as read* button in mobile view [#&#8203;5220](FreshRSS/FreshRSS#5220)
    -   Add CSS class to various types of notifications to allow custom styling [#&#8203;7287](FreshRSS/FreshRSS#7287)
    -   Various UI and style improvements: [#&#8203;7162](FreshRSS/FreshRSS#7162), [#&#8203;7268](FreshRSS/FreshRSS#7268)
        Security
    -   Better authorization label for OIDC in the UI [#&#8203;7264](FreshRSS/FreshRSS#7264)
    -   Allow comments in `force-https.txt` [#&#8203;7259](FreshRSS/FreshRSS#7259)
-   I18n:
    -   Improve German [#&#8203;7177](FreshRSS/FreshRSS#7177), [#&#8203;7275](FreshRSS/FreshRSS#7275), [#&#8203;7278](FreshRSS/FreshRSS#7278)
    -   Improve Japanese [#&#8203;7187](FreshRSS/FreshRSS#7187), [#&#8203;7195](FreshRSS/FreshRSS#7195), [#&#8203;7332](FreshRSS/FreshRSS#7332)
-   Misc.
    -   Improve PHP code [#&#8203;7191](FreshRSS/FreshRSS#7191), [#&#8203;7204](FreshRSS/FreshRSS#7204)
        -   Upgrade to PHPStan 2 [#&#8203;7131](FreshRSS/FreshRSS#7131), [#&#8203;7164](FreshRSS/FreshRSS#7164), [#&#8203;7224](FreshRSS/FreshRSS#7224),
            [#&#8203;7270](FreshRSS/FreshRSS#7270), [#&#8203;7281](FreshRSS/FreshRSS#7281), [#&#8203;7282](FreshRSS/FreshRSS#7282)
    -   Update to CssXPath 1.3.0 (no change) [#&#8203;7211](FreshRSS/FreshRSS#7211)
    -   Update dev dependencies [#&#8203;7165](FreshRSS/FreshRSS#7165), [#&#8203;7166](FreshRSS/FreshRSS#7166), [#&#8203;7167](FreshRSS/FreshRSS#7167),
        [#&#8203;7279](FreshRSS/FreshRSS#7279), [#&#8203;7280](FreshRSS/FreshRSS#7280), [#&#8203;7283](FreshRSS/FreshRSS#7283),
        [#&#8203;7284](FreshRSS/FreshRSS#7284), [#&#8203;7285](FreshRSS/FreshRSS#7285), [#&#8203;7347](FreshRSS/FreshRSS#7347)
    -   Update GitHub Actions to Ubuntu 24.04 [#&#8203;7207](FreshRSS/FreshRSS#7207)

### [`v1.25.0`](https://github.com/FreshRSS/FreshRSS/blob/HEAD/CHANGELOG.md#2024-12-23-FreshRSS-1250)

[Compare Source](FreshRSS/FreshRSS@1.24.3...1.25.0)

-   Features
    -   Add support for [regex search (regular expressions)](https://freshrss.github.io/FreshRSS/en/users/10\_filter.html#regex) [#&#8203;6706](FreshRSS/FreshRSS#6706), [#&#8203;6926](FreshRSS/FreshRSS#6926)
        -   ⚠️ Advanced regex syntax for searches depends on the database used (SQLite, PostgreSQL, MariaDB, MySQL),
            but FreshRSS filter actions such as auto-mark-as-read and auto-favourite always use [PHP PCRE2 syntax](https://php.net/regexp.introduction).
    -   Allow dynamic search operator in user queries, like `search:UserQueryA date:P1d` [#&#8203;6851](FreshRSS/FreshRSS#6851)
    -   New feed mode *HTML+XPath+JSON dot notation* (JSON in HTML) [#&#8203;6888](FreshRSS/FreshRSS#6888)
    -   Better HTTP compliance with support for HTTP response headers `Cache-Control: max-age` and `Expires` [#&#8203;6812](FreshRSS/FreshRSS#6812), [FreshRSS/simplepie#26](FreshRSS/simplepie#26)
    -   Support custom HTTP request headers per feed (e.g. for `Authorization`) [#&#8203;6820](FreshRSS/FreshRSS#6820)
    -   New unicity policies and heuristic for feeds with bad article IDs [#&#8203;4487](FreshRSS/FreshRSS#4487), [#&#8203;6900](FreshRSS/FreshRSS#6900)
    -   Fallback to GUID if article link is empty [#&#8203;7051](FreshRSS/FreshRSS#7051)
    -   New option to automatically mark new articles as read if an identical title already exists in the same category [#&#8203;6922](FreshRSS/FreshRSS#6922)
    -   New reading view option to display unread articles + favourites [#&#8203;7088](FreshRSS/FreshRSS#7088)
        -   And corresponding new filter state `&state=96` (no UI button yet)
    -   Add ability to remove content from articles with CSS selectors, also when not using full content [#&#8203;6786](FreshRSS/FreshRSS#6786), [#&#8203;6807](FreshRSS/FreshRSS#6807)
    -   Update `phpgt/cssxpath` library with improved CSS selectors [#&#8203;6618](FreshRSS/FreshRSS#6618)
        -   Support for `:last-child`, `:first-of-type`, `:last-of-type`, `^=`, `|=`
    -   New condition option to selectively retrieve full content of articles
        [#&#8203;33fd07f6f26310d4806077cc87bcdf9b8b940e35](FreshRSS/FreshRSS@33fd07f), [#&#8203;7082](FreshRSS/FreshRSS#7082)
    -   Allow parentheses in quoted search [#&#8203;7055](FreshRSS/FreshRSS#7055)
    -   New UI feature to download a user’ SQLite database or a database SQLite export (to be produced by CLI) [#&#8203;6931](FreshRSS/FreshRSS#6931)
    -   New button to delete errored feeds from a category [#&#8203;7030](FreshRSS/FreshRSS#7030)
    -   Better import of Inoreader user labels [#&#8203;6791](FreshRSS/FreshRSS#6791)
    -   Rebuild feed favicon on cache clear [#&#8203;6961](FreshRSS/FreshRSS#6961)
    -   New sharing with Bluesky [#&#8203;7116](FreshRSS/FreshRSS#7116)
    -   New sharing with Telegram [#&#8203;6838](FreshRSS/FreshRSS#6838)
-   Bug fixing
    -   Fix searches with a parenthesis before an operator like `("a b")` or `(!c)` [#&#8203;6818](FreshRSS/FreshRSS#6818)
    -   Fix auto-read tags [#&#8203;6790](FreshRSS/FreshRSS#6790)
    -   Fix CSS selector for removing elements [#&#8203;7037](FreshRSS/FreshRSS#7037), [#&#8203;7073](FreshRSS/FreshRSS#7073),
        [#&#8203;7081](FreshRSS/FreshRSS#7081), [#&#8203;7091](FreshRSS/FreshRSS#7091), [#&#8203;7083](FreshRSS/FreshRSS#7083)
    -   Fix redirection error after creating a new user [#&#8203;6995](FreshRSS/FreshRSS#6995)
    -   Fix favicon error in case of wrong URL [#&#8203;6899](FreshRSS/FreshRSS#6899)
    -   Use cURL to fetch extensions list (allows e.g. IPv6) [#&#8203;6767](FreshRSS/FreshRSS#6767)
    -   Fix XML encoding in cURL options [#&#8203;6821](FreshRSS/FreshRSS#6821)
    -   Fix initial UI scroll for some browsers [#&#8203;7059](FreshRSS/FreshRSS#7059)
    -   Fix menu for article tags in some cases [#&#8203;6990](FreshRSS/FreshRSS#6990)
    -   Fix share menu shortcut [#&#8203;6825](FreshRSS/FreshRSS#6825)
    -   Fix HTML regex pattern during install for compatibility with `v` mode [#&#8203;7009](FreshRSS/FreshRSS#7009)
    -   More robust creation of user data folder [#&#8203;7000](FreshRSS/FreshRSS#7000)
-   API
    -   Fix API for categories and labels containing a `+` [#&#8203;7033](FreshRSS/FreshRSS#7033)
        -   Compatibility with FocusReader
    -   Supported by [Capy Reader](https://github.com/jocmp/capyreader) (Android, open source) [capyreader#492](jocmp/capyreader#492)
    -   Improved UI for API [#&#8203;7048](FreshRSS/FreshRSS#7048)
    -   Allow adding multiple feeds to a category via API [#&#8203;7017](FreshRSS/FreshRSS#7017)
    -   API support edit multiple tags [#&#8203;7060](FreshRSS/FreshRSS#7060)
    -   API return all categories also those without any feed [#&#8203;7020](FreshRSS/FreshRSS#7020)
-   Compatibility
    -   Require PHP 8.1+ (drop PHP 7.4) [#&#8203;6711](FreshRSS/FreshRSS#6711)
    -   Improved support of PHP 8.4+ [#&#8203;6618](FreshRSS/FreshRSS#6618), [phpgt/CssXPath#227](phpgt/CssXPath#227),
        [#&#8203;6781](FreshRSS/FreshRSS#6781), [#&#8203;4374](FreshRSS/FreshRSS#4374)
    -   Require PostgreSQL 10+ (drop PostgreSQL 9.5) [#&#8203;6705](FreshRSS/FreshRSS#6705)
    -   Require MariaDB 10.0.5+ (drop MariaDB 5.5) [#&#8203;6706](FreshRSS/FreshRSS#6706)
    -   Require MySQL 8+ (drop MySQL 5.5.3) [#&#8203;6706](FreshRSS/FreshRSS#6706)
-   Deployment
    -   Docker: dev image `freshrss/freshrss:oldest` updated to Alpine 3.16 with PHP 8.1.22 and Apache 2.4.59 [#&#8203;6711](FreshRSS/FreshRSS#6711)
    -   Docker alternative image updated to Alpine 3.21 with PHP 8.3.14 and Apache 2.4.62 [#&#8203;5383](FreshRSS/FreshRSS#5383)
    -   Update Dockerfiles to newer key-value format [#&#8203;6819](FreshRSS/FreshRSS#6819)
    -   Docker minor improvement of entrypoint [#&#8203;6827](FreshRSS/FreshRSS#6827)
-   SimplePie
    -   Refactor [our embedding](lib/README.md) of SimplePie [#&#8203;4374](FreshRSS/FreshRSS#4374)
        -   Our fork is maintained in its [own repository](https://github.com/FreshRSS/simplepie/tree/freshrss).
    -   Remove HTTP `Referer` [#&#8203;6822](FreshRSS/FreshRSS#6822), [FreshRSS/simplepie#27](FreshRSS/simplepie#27)
        -   If some sites require it, add `Referer: https://example.net/` to the custom HTTP headers of the feed [#&#8203;6820](FreshRSS/FreshRSS#6820)
    -   Upstream fixes [simplepie#878](simplepie/simplepie#878), [simplepie#883](simplepie/simplepie#883)
    -   Sync upstream [#&#8203;6840](FreshRSS/FreshRSS#6840), [#&#8203;7067](FreshRSS/FreshRSS#7067)
-   Security
    -   Apache protect more non-public folders and files [#&#8203;6881](FreshRSS/FreshRSS#6881), [#&#8203;6893](FreshRSS/FreshRSS#6893), [#&#8203;7008](FreshRSS/FreshRSS#7008)
    -   Add privacy settings on extension list retrieval [#&#8203;4603](FreshRSS/FreshRSS#4603), [#&#8203;7132](FreshRSS/FreshRSS#7132)
    -   Fix login in unsafe mode when using a password with special XML characters [#&#8203;6797](FreshRSS/FreshRSS#6797)
    -   Fix login in e.g. Brave browser by avoiding synchronous XHR [#&#8203;7023](FreshRSS/FreshRSS#7023)
    -   Fix invalid login message [#&#8203;7066](FreshRSS/FreshRSS#7066)
    -   Modernise `windows.open noopener` (to avoid flash of white page in dark mode) [#&#8203;7077](FreshRSS/FreshRSS#7077), [#&#8203;7089](FreshRSS/FreshRSS#7089)
-   UI
    -   Searchable *My Labels* field [#&#8203;6753](FreshRSS/FreshRSS#6753)
    -   Add subscription management button to reading view [#&#8203;6946](FreshRSS/FreshRSS#6946)
    -   New option for showing label menu in article row [#&#8203;6984](FreshRSS/FreshRSS#6984)
    -   Move to next unread label on mark as read [#&#8203;6886](FreshRSS/FreshRSS#6886)
    -   Improved article footer for small / mobile screens [#&#8203;7031](FreshRSS/FreshRSS#7031)
    -   Improve Web accessibility: fix `aria-hidden` bug, and use HTML5 `hidden` [#&#8203;6910](FreshRSS/FreshRSS#6910)
    -   Default styles for `<pre>` and `<code>` [#&#8203;6770](FreshRSS/FreshRSS#6770)
    -   Refactor the sharing menu to use a `<template>` instead of duplicated HTML code [#&#8203;6751](FreshRSS/FreshRSS#6751), [#&#8203;7113](FreshRSS/FreshRSS#7113)
    -   Refactor the label menu to use a `<template>` [#&#8203;6864](FreshRSS/FreshRSS#6864)
    -   Rework UI for authors [#&#8203;7054](FreshRSS/FreshRSS#7054)
        -   Avoid Unicode escape of authors in HTML UI [#&#8203;7056](FreshRSS/FreshRSS#7056)
    -   Improved subscription management page [#&#8203;6816](FreshRSS/FreshRSS#6816)
    -   Improve user query management page [#&#8203;7062](FreshRSS/FreshRSS#7062)
    -   Restore JavaScript form validation compatibility with Web browsers using older engines (SeaMonkey) [#&#8203;6777](FreshRSS/FreshRSS#6777)
    -   Reorganise some options [#&#8203;6920](FreshRSS/FreshRSS#6920)
    -   New shortcut `?` to show shortcut page and help [#&#8203;6981](FreshRSS/FreshRSS#6981)
    -   Use of consistent colours in statistics [#&#8203;7090](FreshRSS/FreshRSS#7090)
    -   Various UI and style improvements [#&#8203;6959](FreshRSS/FreshRSS#6959)
-   Extensions
    -   New extension hook `simplepie_after_init` [#&#8203;7007](FreshRSS/FreshRSS#7007)
-   I18n
    -   Add Finnish [#&#8203;6954](FreshRSS/FreshRSS#6954)
    -   Improve English [#&#8203;7049](FreshRSS/FreshRSS#7049), [#&#8203;7053](FreshRSS/FreshRSS#7053)
    -   Improve German [#&#8203;6847](FreshRSS/FreshRSS#6847), [#&#8203;7068](FreshRSS/FreshRSS#7068), [#&#8203;7128](FreshRSS/FreshRSS#7128)
    -   Improve Italian [#&#8203;6872](FreshRSS/FreshRSS#6872), [#&#8203;7069](FreshRSS/FreshRSS#7069), [#&#8203;7086](FreshRSS/FreshRSS#7086)
    -   Improve Spanish [#&#8203;6894](FreshRSS/FreshRSS#6894), [#&#8203;6908](FreshRSS/FreshRSS#6908)
    -   Improve Turkish [#&#8203;6960](FreshRSS/FreshRSS#6960)
-   Misc.
    -   Better cache name for JSON feeds [#&#8203;6768](FreshRSS/FreshRSS#6768)
    -   Fix inversed encoding logic in `Minz_Request::paramArray()` [#&#8203;6800](FreshRSS/FreshRSS#6800)
    -   Pass PHPStan `booleansInConditions` [#&#8203;6793](FreshRSS/FreshRSS#6793)
    -   Rename PHPStan configuration file to `phpstan.dist.neon` to allow custom configuration in `phpstan.neon` [#&#8203;6892](FreshRSS/FreshRSS#6892)
    -   Code improvements [#&#8203;6800](FreshRSS/FreshRSS#6800), [#&#8203;6809](FreshRSS/FreshRSS#6809), [#&#8203;6983](FreshRSS/FreshRSS#6983)
    -   Makefile improvements [#&#8203;6913](FreshRSS/FreshRSS#6913)
    -   Fix PHPCS `ControlSignature` [#&#8203;6896](FreshRSS/FreshRSS#6896)
    -   Update *PHPMailer* [#&#8203;6968](FreshRSS/FreshRSS#6968), [#&#8203;7046](FreshRSS/FreshRSS#7046)
    -   Code updates to PHP 8.1 syntax [#&#8203;6748](FreshRSS/FreshRSS#6748)
    -   Update dev dependencies [#&#8203;6780](FreshRSS/FreshRSS#6780), [#&#8203;6964](FreshRSS/FreshRSS#6964), , [#&#8203;6965](FreshRSS/FreshRSS#6965),
        [#&#8203;6966](FreshRSS/FreshRSS#6966), [#&#8203;6967](FreshRSS/FreshRSS#6967), [#&#8203;6970](FreshRSS/FreshRSS#6970),
        [#&#8203;7042](FreshRSS/FreshRSS#7042), [#&#8203;7043](FreshRSS/FreshRSS#7043), [#&#8203;7044](FreshRSS/FreshRSS#7044),
        [#&#8203;7045](FreshRSS/FreshRSS#7045), [#&#8203;7047](FreshRSS/FreshRSS#7047), [#&#8203;7052](FreshRSS/FreshRSS#7052)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS45MC4zIiwidXBkYXRlZEluVmVyIjoiMzkuMTc2LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://gitea.sh4ke.rocks/lickler/freshrss/pulls/29
Co-authored-by: Michael Wittig <[email protected]>
Co-committed-by: Michael Wittig <[email protected]>
peterwilsoncc added a commit to peterwilsoncc/wordpress-develop that referenced this pull request Jul 18, 2025
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Jul 21, 2025
Upgrades the Simple Pie library to a patched version of [https://github.com/simplepie/simplepie/releases/tag/1.8.1 Simple Pie 1.8.1]. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

* Fix locator with website missing `Content-Type` header [simplepie/simplepie#891 simplepie/simplepie#891]
* Fix `encode` argument of `SimplePie::strip_htmltags()` [simplepie/simplepie#894 simplepie/simplepie#894]

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see [simplepie/simplepie#883 simplepie/simplepie#883].

A caching test for `fetch_feed()` is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes #63717.


git-svn-id: https://develop.svn.wordpress.org/trunk@60490 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Jul 21, 2025
Upgrades the Simple Pie library to a patched version of [https://github.com/simplepie/simplepie/releases/tag/1.8.1 Simple Pie 1.8.1]. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

* Fix locator with website missing `Content-Type` header [simplepie/simplepie#891 simplepie/simplepie#891]
* Fix `encode` argument of `SimplePie::strip_htmltags()` [simplepie/simplepie#894 simplepie/simplepie#894]

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see [simplepie/simplepie#883 simplepie/simplepie#883].

A caching test for `fetch_feed()` is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes #63717.

Built from https://develop.svn.wordpress.org/trunk@60490


git-svn-id: http://core.svn.wordpress.org/trunk@59826 1a063a9b-81f0-0310-95a4-ce76da25c4cd
github-actions bot pushed a commit to platformsh/wordpress-performance that referenced this pull request Jul 21, 2025
Upgrades the Simple Pie library to a patched version of [https://github.com/simplepie/simplepie/releases/tag/1.8.1 Simple Pie 1.8.1]. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

* Fix locator with website missing `Content-Type` header [simplepie/simplepie#891 simplepie/simplepie#891]
* Fix `encode` argument of `SimplePie::strip_htmltags()` [simplepie/simplepie#894 simplepie/simplepie#894]

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see [simplepie/simplepie#883 simplepie/simplepie#883].

A caching test for `fetch_feed()` is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes #63717.

Built from https://develop.svn.wordpress.org/trunk@60490


git-svn-id: https://core.svn.wordpress.org/trunk@59826 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Ninos pushed a commit to Ninos/wordpress-develop that referenced this pull request Jul 28, 2025
Upgrades the Simple Pie library to a patched version of [https://github.com/simplepie/simplepie/releases/tag/1.8.1 Simple Pie 1.8.1]. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

* Fix locator with website missing `Content-Type` header [simplepie/simplepie#891 simplepie/simplepie#891]
* Fix `encode` argument of `SimplePie::strip_htmltags()` [simplepie/simplepie#894 simplepie/simplepie#894]

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see [simplepie/simplepie#883 simplepie/simplepie#883].

A caching test for `fetch_feed()` is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes #63717.


git-svn-id: https://develop.svn.wordpress.org/trunk@60490 602fd350-edb4-49c9-b593-d223f7449a82
jonnynews pushed a commit to spacedmonkey/wordpress-develop that referenced this pull request Sep 24, 2025
Upgrades the Simple Pie library to a patched version of [https://github.com/simplepie/simplepie/releases/tag/1.8.1 Simple Pie 1.8.1]. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

* Fix locator with website missing `Content-Type` header [simplepie/simplepie#891 simplepie/simplepie#891]
* Fix `encode` argument of `SimplePie::strip_htmltags()` [simplepie/simplepie#894 simplepie/simplepie#894]

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see [simplepie/simplepie#883 simplepie/simplepie#883].

A caching test for `fetch_feed()` is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes #63717.


git-svn-id: https://develop.svn.wordpress.org/trunk@60490 602fd350-edb4-49c9-b593-d223f7449a82
mattyrob pushed a commit to ClassicPress/ClassicPress that referenced this pull request Dec 3, 2025
Upgrades the Simple Pie library to a patched version of [https://github.com/simplepie/simplepie/releases/tag/1.8.1 Simple Pie 1.8.1]. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

* Fix locator with website missing `Content-Type` header [simplepie/simplepie#891 simplepie/simplepiehttps://core.trac.wordpress.org/ticket/891]
* Fix `encode` argument of `SimplePie::strip_htmltags()` [simplepie/simplepie#894 simplepie/simplepiehttps://core.trac.wordpress.org/ticket/894]

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see [simplepie/simplepie#883 simplepie/simplepiehttps://core.trac.wordpress.org/ticket/883].

A caching test for `fetch_feed()` is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

WP:Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes https://core.trac.wordpress.org/ticket/63717.

---

Merges https://core.trac.wordpress.org/changeset/60490 / WordPress/wordpress-develop@f0a3c68f9e to ClassicPress.
mattyrob added a commit to ClassicPress/ClassicPress that referenced this pull request Jan 7, 2026
* WP-r59382: Feeds: Avoid fatal error with empty `blog_charset` value.

After the SimplePie library was updated to version `1.8.0` in https://core.trac.wordpress.org/changeset/59141, an edge case has been discovered where a fatal error can encountered if the `blog_charset` option is missing or empty.

In `fetch_feed()`, this option is retrieved using `get_option()` instead of `get_bloginfo( ‘charset’ )`. The latter will detect this scenario and apply a default value of `UTF-8` and is already used interchangeably throughout Core. This switches to `get_bloginfo( ‘charset’ )` instead to prevent this edge case.

WP:Props david.binda, davidbaumwald, SergeyBiryukov, sabernhardt, azaozz, peterwilsoncc.
Fixes https://core.trac.wordpress.org/ticket/62354.

---

Merges https://core.trac.wordpress.org/changeset/59382 / WordPress/wordpress-develop@2762e5e92b to ClassicPress.

* Add WordPress.org news feed XML for tests

Introduced a new test data file containing the WordPress.org news RSS feed in XML format for use in PHPUnit tests.

* WP-r59408: Tests: Add missing `@covers` tag for `fetch_feed()` tests.

Includes correcting the test class name as per the naming conventions.

Follow-up to https://core.trac.wordpress.org/changeset/59382.

See https://core.trac.wordpress.org/ticket/62280.

---

Merges https://core.trac.wordpress.org/changeset/59408 / WordPress/wordpress-develop@a731b9bfc0 to ClassicPress.

* WP-r60490: External Libraries: Upgrade Simple Pie to 1.8.1 (patched).

Upgrades the Simple Pie library to a patched version of [https://github.com/simplepie/simplepie/releases/tag/1.8.1 Simple Pie 1.8.1]. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

* Fix locator with website missing `Content-Type` header [simplepie/simplepie#891 simplepie/simplepiehttps://core.trac.wordpress.org/ticket/891]
* Fix `encode` argument of `SimplePie::strip_htmltags()` [simplepie/simplepie#894 simplepie/simplepiehttps://core.trac.wordpress.org/ticket/894]

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see [simplepie/simplepie#883 simplepie/simplepiehttps://core.trac.wordpress.org/ticket/883].

A caching test for `fetch_feed()` is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

WP:Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes https://core.trac.wordpress.org/ticket/63717.

---

Merges https://core.trac.wordpress.org/changeset/60490 / WordPress/wordpress-develop@f0a3c68f9e to ClassicPress.

* WP-r60771: External Libraries: Update the SimplePie library to version 1.9.0.

References:
* [https://github.com/simplepie/simplepie/releases/tag/1.9.0 SimplePie 1.9.0 release notes]
* [simplepie/simplepie@1.8.1...1.9.0 Full list of changes in SimplePie 1.9.0]

Follow-up to https://core.trac.wordpress.org/changeset/59141, https://core.trac.wordpress.org/changeset/60490.

WP:Props swissspidy, TobiasBg, SergeyBiryukov.
Fixes https://core.trac.wordpress.org/ticket/63961.

Conflicts:
- src/wp-includes/feed.php

---

Merges https://core.trac.wordpress.org/changeset/60771 / WordPress/wordpress-develop@2553772fb0 to ClassicPress.

* Remove merge conflict markers in feed.php

Cleaned up leftover merge conflict markers and redundant code in fetch_feed function to ensure proper sanitization class is set for SimplePie.

* WP-r60947: External Libraries: Backport upstream PHP 8.5 fixes for SimplePie.

After the update to v1.9.0 in https://core.trac.wordpress.org/changeset/60771, this merges a single bug fix, in absence of a new upstream release in time for 6.9 Beta.

References:

* [simplepie/simplepie#949 Original upstream PR]

WP:Props swissspidy.
Fixes https://core.trac.wordpress.org/ticket/63961.

---

Merges https://core.trac.wordpress.org/changeset/60947 / WordPress/wordpress-develop@330deca538 to ClassicPress.

* Add removed SimplePie files to old files list

Added 'wp-includes/SimplePie/src/Decode' and 'wp-includes/SimplePie/src/Core.php' to the $_old_files array to support the upgrade to SimplePie 1.9.0.

* Update git conflict regex for 7 angled brackets

---------

Co-authored-by: Jonathan Desrosiers <[email protected]>
Co-authored-by: Sergey Biryukov <[email protected]>
Co-authored-by: Peter Wilson <[email protected]>
Co-authored-by: Pascal Birchler <[email protected]>

CP:Props mattyrob, xxsimoxx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Cache constantly updating

3 participants