[Commits] [SCM] claws branch, master, updated. 4.3.1-91-gdf3833d36
paul at claws-mail.org
paul at claws-mail.org
Mon Apr 7 11:59:36 UTC 2025
The branch, master has been updated
via df3833d369d125250f30a1ea1f20f9dca0f21a2a (commit)
from 0cc52c0d67e5121b107ec5cc360140c797f25221 (commit)
Summary of changes:
src/plugins/rssyl/libfeed/feed.c | 17 +++++++++++++++++
src/plugins/rssyl/libfeed/feed.h | 1 +
src/plugins/rssyl/rssyl.c | 15 +++++++++++++++
src/plugins/rssyl/rssyl.h | 1 +
src/plugins/rssyl/rssyl_feed.c | 7 ++++++-
src/plugins/rssyl/rssyl_feed.h | 1 +
src/plugins/rssyl/rssyl_update_feed.c | 11 ++++++++++-
7 files changed, 51 insertions(+), 2 deletions(-)
- Log -----------------------------------------------------------------
commit df3833d369d125250f30a1ea1f20f9dca0f21a2a
Author: Paul <paul at claws-mail.org>
Date: Mon Apr 7 12:59:31 2025 +0100
postpone auto-updates if Retry-After: given
Sometimes when a feed returns an HTTP error code due to having received
too many requests in too short a period of time (especially 403 or 429),
they specify a safe interval after which the request could be retried
using the Retry-After: HTTP header. Parse the value and skip automatic
updates if it's set to a date in the future.
When a manual update succeeds, clear the retry_after value, making it
possible to unstuck automatic updates in case a Retry-After: value was
accidentally set too far in the future.
patch by Ivan Krylov
diff --git a/src/plugins/rssyl/libfeed/feed.c b/src/plugins/rssyl/libfeed/feed.c
index 1baa786ca..f9090b79e 100644
--- a/src/plugins/rssyl/libfeed/feed.c
+++ b/src/plugins/rssyl/libfeed/feed.c
@@ -22,6 +22,7 @@
#include <glib.h>
#include <curl/curl.h>
#include <expat.h>
+#include <procheader.h>
#include "feed.h"
#include "../rssyl_prefs.h"
@@ -53,6 +54,7 @@ Feed *feed_new(gchar *url)
feed->cookies_path = NULL;
feed->last_modified = NULL;
feed->etag = NULL;
+ feed->retry_after = 0;
feed->ssl_verify_peer = TRUE;
feed->cacert_file = NULL;
@@ -374,6 +376,21 @@ guint feed_update(Feed *feed, const gchar *user_agent)
feed_set_last_modified(feed,
ret == CURLHE_OK ? header->value
: NULL);
+ ret = curl_easy_header(eh, "Retry-After", 0,
+ CURLH_HEADER, -1,
+ &header);
+ if (ret == CURLHE_OK && *header->value) {
+ /* Retry-After: either delay >= 0 seconds or HTTP Date */
+ char * end = NULL;
+ unsigned long long seconds = strtoull(header->value, &end, 10);
+ if (!*end && seconds > 0) { /* parse successful */
+ feed->retry_after = time(NULL) + seconds;
+ } else { /* will set to 0 if fails to parse */
+ feed->retry_after = procheader_date_parse(NULL,
+ header->value,
+ 0);
+ }
+ }
}
cleanup:
diff --git a/src/plugins/rssyl/libfeed/feed.h b/src/plugins/rssyl/libfeed/feed.h
index 2986ce1bd..7d4b55383 100644
--- a/src/plugins/rssyl/libfeed/feed.h
+++ b/src/plugins/rssyl/libfeed/feed.h
@@ -61,6 +61,7 @@ struct _Feed {
gchar *cacert_file;
gchar *last_modified;
gchar *etag;
+ time_t retry_after;
GSList *items;
};
diff --git a/src/plugins/rssyl/rssyl.c b/src/plugins/rssyl/rssyl.c
index 7d7be0d52..36616ba1d 100644
--- a/src/plugins/rssyl/rssyl.c
+++ b/src/plugins/rssyl/rssyl.c
@@ -36,9 +36,11 @@
#include <prefs_toolbar.h>
#include <utils.h>
#include <file-utils.h>
+#include <procheader.h>
/* Local includes */
#include "libfeed/feeditem.h"
+#include "libfeed/date.h"
#include "rssyl.h"
#include "rssyl_deleted.h"
#include "rssyl_gtk.h"
@@ -343,6 +345,10 @@ static void rssyl_item_set_xml(Folder *folder, FolderItem *item, XMLTag *tag)
g_free(ritem->etag);
ritem->etag = g_strdup(attr->value);
}
+ /* (time_t) Retry-After header */
+ if( !strcmp(attr->name, "retry_after")) {
+ ritem->retry_after = procheader_date_parse(NULL, attr->value, 0);
+ }
}
}
@@ -408,6 +414,13 @@ static XMLTag *rssyl_item_get_xml(Folder *folder, FolderItem *item)
/* (str) ETag header */
if( ri->etag != NULL )
xml_tag_add_attr(tag, xml_attr_new("etag", ri->etag));
+ /* (time_t) Retry-After */
+ time_t now = time(NULL);
+ if (ri->retry_after > now) {
+ tmp = createRFC822Date(&now);
+ xml_tag_add_attr(tag, xml_attr_new("retry_after", tmp));
+ g_free(tmp);
+ }
return tag;
}
@@ -478,6 +491,7 @@ static FolderItem *rssyl_item_new(Folder *folder)
ritem->specific_user_agent = NULL;
ritem->last_modified = NULL;
ritem->etag = NULL;
+ ritem->retry_after = 0;
return (FolderItem *)ritem;
}
@@ -1024,6 +1038,7 @@ static void rssyl_copy_private_data(Folder *folder, FolderItem *oldi,
g_free(newitem->specific_user_agent);
newitem->specific_user_agent = g_strdup(olditem->specific_user_agent);
}
+ newitem->retry_after = olditem->retry_after;
/* ETag, Last-Modified */
if (olditem->etag != NULL) {
diff --git a/src/plugins/rssyl/rssyl.h b/src/plugins/rssyl/rssyl.h
index 8144180fe..768ce3c64 100644
--- a/src/plugins/rssyl/rssyl.h
+++ b/src/plugins/rssyl/rssyl.h
@@ -72,6 +72,7 @@ struct _RFolderItem {
time_t last_update;
gchar *last_modified;
gchar *etag;
+ time_t retry_after;
gboolean use_default_user_agent;
gchar *specific_user_agent;
diff --git a/src/plugins/rssyl/rssyl_feed.c b/src/plugins/rssyl/rssyl_feed.c
index e762d93f2..2bc8260a7 100644
--- a/src/plugins/rssyl/rssyl_feed.c
+++ b/src/plugins/rssyl/rssyl_feed.c
@@ -1,6 +1,6 @@
/*
* Claws Mail -- a GTK based, lightweight, and fast e-mail client
- * Copyright (C) 2006-2023 the Claws Mail Team and Andrej Kacian <andrej at kacian.sk>
+ * Copyright (C) 2006-2025 the Claws Mail Team and Andrej Kacian <andrej at kacian.sk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -85,6 +85,11 @@ gboolean rssyl_refresh_timeout_cb(gpointer data)
if (prefs_common_get_prefs()->work_offline) {
debug_print("RSSyl: %s: skipping update of %s (%d), we are offline\n",
tmpdate, ctx->ritem->url, ctx->ritem->refresh_id);
+ } else if (ctx->ritem->retry_after > tt) {
+ gchar *whenretry = createRFC822Date(&ctx->ritem->retry_after);
+ debug_print("RSSyl: %s: skipping update of %s (%d): Retry-After = %s\n",
+ tmpdate, ctx->ritem->url, ctx->ritem->refresh_id, whenretry);
+ g_free(whenretry);
} else {
debug_print("RSSyl: %s: updating %s (%d)\n",
tmpdate, ctx->ritem->url, ctx->ritem->refresh_id);
diff --git a/src/plugins/rssyl/rssyl_feed.h b/src/plugins/rssyl/rssyl_feed.h
index 25d3189b3..6a722c03c 100644
--- a/src/plugins/rssyl/rssyl_feed.h
+++ b/src/plugins/rssyl/rssyl_feed.h
@@ -31,6 +31,7 @@
#define RSSYL_LOG_NOT_MODIFIED _("RSSyl: Feed not modified: %s\n")
#define RSSYL_LOG_UPDATED _("RSSyl: Feed update finished: %s\n")
#define RSSYL_LOG_ERROR_FETCH _("RSSyl: Error fetching feed at '%s': %s\n")
+#define RSSYL_LOG_RETRY_AFTER _("RSSyl: Told to update feed at '%s' after %s\n")
#define RSSYL_LOG_ERROR_NOFEED _("RSSyl: No valid feed found at '%s'\n")
#define RSSYL_LOG_ERROR_PROC _("RSSyl: Couldn't process feed at '%s'\n")
#define RSSYL_LOG_ABORTED_EXITING _("RSSyl: Application is exiting, couldn't finish updating feed at '%s'\n")
diff --git a/src/plugins/rssyl/rssyl_update_feed.c b/src/plugins/rssyl/rssyl_update_feed.c
index 2da7f9352..5ee014ced 100644
--- a/src/plugins/rssyl/rssyl_update_feed.c
+++ b/src/plugins/rssyl/rssyl_update_feed.c
@@ -37,6 +37,7 @@
/* Local includes */
#include "libfeed/feed.h"
+#include "libfeed/date.h"
#include "rssyl.h"
#include "rssyl_deleted.h"
#include "rssyl_feed.h"
@@ -145,7 +146,7 @@ void rssyl_fetch_feed(RFetchCtx *ctx, RSSylVerboseFlags verbose)
} else if( ctx->response_code == FEED_ERR_UNAUTH ) {
debug_print("RSSyl: URL authorization type is unknown\n");
ctx->error = g_strdup("Unknown value for URL authorization type");
- } else if( ctx->response_code >= 400 && ctx->response_code < 500 ) {
+ } else if( ctx->response_code >= 400 && ctx->response_code <= 599 ) {
switch( ctx->response_code ) {
case 401:
ctx->error = g_strdup(_("401 (Authorisation required)"));
@@ -304,12 +305,20 @@ gboolean rssyl_update_feed(RFolderItem *ritem, RSSylVerboseFlags verbose)
ctx->success ? "TRUE" : "FALSE");
if (!ctx->success) {
+ ritem->retry_after = ctx->feed->retry_after;
+ if (ritem->retry_after) {
+ gchar *tmp = createRFC822Date(&ritem->retry_after);
+ log_print(LOG_PROTOCOL, RSSYL_LOG_RETRY_AFTER, ritem->url, tmp);
+ g_free(tmp);
+ }
feed_free(ctx->feed);
g_free(ctx->error);
g_free(ctx);
STATUSBAR_POP(mainwin);
return FALSE;
}
+ /* Successful reply means we don't have to throttle auto-updates */
+ ritem->retry_after = 0;
g_free(ritem->etag);
gchar *etag = feed_get_etag(ctx->feed);
-----------------------------------------------------------------------
hooks/post-receive
--
Claws Mail
More information about the Commits
mailing list