Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Negotiate cache_expiration_time #26

Merged
merged 15 commits into from
Sep 20, 2024
Merged

Conversation

Alkarex
Copy link
Member

@Alkarex Alkarex commented Sep 15, 2024

Negotiate the cache expiration time based on the HTTP response headers.
Return the cache duration time in number of seconds since the Unix Epoch, accounting for:

  • Cache-Control: max-age minus Age, bounded by $cache_duration_min and $cache_duration_max
  • Cache-Control: must-revalidate will set $cache_duration to $cache_duration_min
  • Cache-Control: no-cache will return time() + $cache_duration_min
  • Cache-Control: no-store will return time() + $cache_duration_min - 3 (to distinguish from no-cache if needed)
  • Expires like Cache-Control: max-age but only if it is absent

Parameters:

  • $cache_duration Desired cache duration in seconds, potentially overridden by HTTP response headers
  • $cache_duration_min Minimal cache duration (in seconds), overriding HTTP response headers Cache-Control and Expires
  • $cache_duration_max Maximal cache duration (in seconds), overriding HTTP response headers Cache-Control and Expires

- `Cache-Control: max-age` minus `Age`, extendable by `$simplepie_cache_duration`
- `Cache-Control: must-revalidate` will prevent `$simplepie_cache_duration` from extending past the `max-age`
- `Cache-Control: no-cache` will return the current time
- `Cache-Control: no-store` will return `0`
- `Expires` but only if `Cache-Control: max-age` is absent
@Alkarex
Copy link
Member Author

Alkarex commented Sep 15, 2024

@Frenzie , @marienfressinaud, @Art4 and others: discussion welcome.

At the moment SimplePie is not HTTP compliant when it comes to HTTP requests and caching. This PR addresses some of it.

But I have some doubts. On my local tests, I see plenty of feeds responding with Cache-Control: no-cache, no-store, max-age=0, must-revalidate or a variation of that. no-store being the strictest.

For instance, our own GitHub releases feed returns cache-control: max-age=0, private, must-revalidate (it does support conditional requests though, luckily).

So on FreshRSS instances with many users, there is a good likelihood of having several users subscribing to the same feed(s) (for instance this GitHub release feed), and preventing the cache from being used by the following users during a refresh cron job would be a waste of resources - but potentially good for servers which care about download statistics.

We could consider updating our heuristics based on e.g. Cache-Control: private. There are fewer feeds with this directive but still a number in my own test set, such as https://www.journalduhacker.net/rss (returns Cache-Control: max-age=0, private, must-revalidate) or https://www.blogger.com/feeds/8698702854482141883/posts/default (returns cache-control: private, max-age=0, must-revalidate, no-transform)

Thoughts?

@Frenzie
Copy link
Member

Frenzie commented Sep 15, 2024

At least on GH I would suspect it's closer to a mistake, intended to make sure the comments are up to date on a page like this one.

But you can certainly think of scenarios where it would be intentional. Perhaps something like a server minimum cache time constant at 5 or 10 minutes by default?

@Alkarex
Copy link
Member Author

Alkarex commented Sep 15, 2024

Perhaps something like a server minimum cache time constant at 5 or 10 minutes by default

I have introduced $cache_duration_min: Minimal cache duration (in seconds), overriding HTTP response headers Cache-Control: max-age and Expires, but without effect on Cache-Control: no-store and Cache-Control: no-cache and Cache-Control: must-revalidate

Its default is 60s but can be set higher. But not obeying Cache-Control: no-store or Cache-Control: no-cache or Cache-Control: must-revalidate would not be HTTP compliant.

Alkarex added a commit to Alkarex/FreshRSS that referenced this pull request Sep 15, 2024
@Alkarex Alkarex closed this Sep 15, 2024
@Alkarex Alkarex deleted the negociate_cache_expiration_time branch September 15, 2024 22:25
@Alkarex Alkarex restored the negociate_cache_expiration_time branch September 15, 2024 22:31
@Alkarex Alkarex reopened this Sep 15, 2024
@Alkarex Alkarex changed the title Negociate_cache_expiration_time Negotiate cache_expiration_time Sep 15, 2024
@Alkarex
Copy link
Member Author

Alkarex commented Sep 16, 2024

Changed logic, to account for the many servers disabling cache all-together. Simpler, and probably more pragmatic

@Frenzie
Copy link
Member

Frenzie commented Sep 16, 2024

You don't think 24h sounds a bit short as a default maximum if the site is explicitly asking for it? :-)

@Alkarex
Copy link
Member Author

Alkarex commented Sep 16, 2024

You don't think 24h sounds a bit short as a default maximum if the site is explicitly asking for it? :-)

Maybe, but I am balancing that with users, who will believe that the refresh is broken...

P.S.: And I can also see some feeds returning high values, which are most likely broken.
For instance 30d for https://gts-net.dk/feed/ during the conditional response (I need to debug that one a bit more).

@Frenzie
Copy link
Member

Frenzie commented Sep 16, 2024

Right, I'm not saying to just listen to whatever the feed might say, just that a few days still seems reasonable. But the point about users makes sense.

@Alkarex
Copy link
Member Author

Alkarex commented Sep 18, 2024

For some unknown reason, I observe some strange feeds (e.g. https://gts-net.dk/feed/ ), which are returning a much higher max-age (30d) for a 304 response than for the initial 200 response (1h).

$ curl -v -A 'FreshRSS/1.25.0-dev (Linux; https://freshrss.org)' -H "Accept: application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8" 'https://gts-net.dk/feed/'
> GET /feed/ HTTP/2
> Host: gts-net.dk
> User-Agent: FreshRSS/1.25.0-dev (Linux; https://freshrss.org)
> Accept: application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8
>
< HTTP/2 200
< date: Wed, 18 Sep 2024 10:38:12 GMT
< content-type: application/rss+xml; charset=UTF-8
< server: Apache
< link: <https://gts-net.dk/wp-json/>; rel="https://api.w.org/", <https://gts-net.dk/>; rel="canonical"
< x-tec-api-version: v1
< x-tec-api-root: https://gts-net.dk/wp-json/tribe/events/v1/
< x-tec-api-origin: https://gts-net.dk
< last-modified: Wed, 18 Sep 2024 10:24:19 GMT
< cache-control: max-age=3600
< expires: Wed, 18 Sep 2024 11:38:12 GMT
< vary: Accept-Encoding
< x-content-type-options: nosniff
< simplycom-server: Apache
< simplycom-server: nginx
< alt-svc: h3=":443"; ma=86400, h3-29=":443"
<
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:wfw="http://wellformedweb.org/CommentAPI/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:atom="http://www.w3.org/2005/Atom"
        xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
        xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
        >
<!-- ... -->
</rss>

$ curl -v -A 'FreshRSS/1.25.0-dev (Linux; https://freshrss.org)' -H "Accept: application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8" -H 'If-Modified-Since: Wed, 18 Sep 2024 10:24:19 GMT' 'https://gts-net.dk/feed/'
> GET /feed/ HTTP/2
> Host: gts-net.dk
> User-Agent: FreshRSS/1.25.0-dev (Linux; https://freshrss.org)
> Accept: application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8
> If-Modified-Since: Wed, 18 Sep 2024 10:24:19 GMT
>
< HTTP/2 304
< date: Wed, 18 Sep 2024 10:41:23 GMT
< server: Apache
< last-modified: Wed, 18 Sep 2024 10:24:19 GMT
< cache-control: max-age=2592000
< expires: Fri, 18 Oct 2024 10:41:23 GMT
< x-content-type-options: nosniff
< simplycom-server: Apache
< vary: Accept-Encoding
< simplycom-server: nginx
<

@Frenzie
Copy link
Member

Frenzie commented Sep 18, 2024

Oof. :-/

@Alkarex
Copy link
Member Author

Alkarex commented Sep 20, 2024

Another feed with same problem: https://www.smappee.com/blog/feed/

< HTTP/2 200
< server: nginx
< date: Fri, 20 Sep 2024 13:46:47 GMT
< content-type: application/rss+xml; charset=UTF-8
< last-modified: Thu, 19 Sep 2024 14:26:27 GMT
< cache-control: max-age=3600
< expires: Fri, 20 Sep 2024 14:46:45 GMT
< HTTP/2 304
< server: nginx
< date: Fri, 20 Sep 2024 13:47:32 GMT
< last-modified: Thu, 19 Sep 2024 14:26:27 GMT
< cache-control: max-age=2592000
< expires: Sun, 20 Oct 2024 13:47:31 GMT

@Alkarex
Copy link
Member Author

Alkarex commented Sep 20, 2024

Well, when nginx is in the equation, it is often the culprit...
An explanation h5bp/server-configs-nginx#230

Problem:

  1. Expiration time is currently determined by content-type.

  2. Content-type is not set for 304 responses.

  3. This means 304 responses gets the default expiration time, which could be very different from the original.

@Alkarex
Copy link
Member Author

Alkarex commented Sep 20, 2024

Workaround implemented: Allow servers to return a shorter cache duration for 304 responses, but not longer than the value in the 200 response

@Alkarex
Copy link
Member Author

Alkarex commented Sep 20, 2024

Seems to work quite fine

@Alkarex Alkarex merged commit 7090eed into freshrss Sep 20, 2024
18 checks passed
@Alkarex Alkarex deleted the negociate_cache_expiration_time branch September 20, 2024 21:19
Alkarex added a commit to FreshRSS/FreshRSS that referenced this pull request Sep 20, 2024
* SimplePie support for HTTP cache policies
Discussion in FreshRSS/simplepie#26

* Bump SimplePie commit

* Typos

* Typos

* Simpler logic

* Explicitly disable cache for non-GET flows

* Bump SimplePie commit

* Bump SimplePie commit

* Bump SimplePie commit

* Bump SimplePie commit
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants