talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 0cc52c0d67e5121b107ec5cc360140c797f25221
parent 73f147dd45d559c01178822a1f8b6b5ebf3ffbbc
Author: Paul <paul@claws-mail.org>
Date:   Mon,  7 Apr 2025 12:56:25 +0100

persist and reuse ETag and Last-Modified

patch by Ivan Krylov

Diffstat:
Msrc/plugins/rssyl/rssyl.c | 31+++++++++++++++++++++++++++++++
Msrc/plugins/rssyl/rssyl.h | 2++
Msrc/plugins/rssyl/rssyl_feed.h | 1+
Msrc/plugins/rssyl/rssyl_update_feed.c | 19++++++++++++++++++-
4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/plugins/rssyl/rssyl.c b/src/plugins/rssyl/rssyl.c @@ -333,6 +333,16 @@ static void rssyl_item_set_xml(Folder *folder, FolderItem *item, XMLTag *tag) g_free(ritem->specific_user_agent); ritem->specific_user_agent = g_strdup(attr->value); } + /* (str) Last-Modified header */ + if( !strcmp(attr->name, "last_modified")) { + g_free(ritem->last_modified); + ritem->last_modified = g_strdup(attr->value); + } + /* (str) ETag header */ + if( !strcmp(attr->name, "etag")) { + g_free(ritem->etag); + ritem->etag = g_strdup(attr->value); + } } } @@ -392,6 +402,12 @@ static XMLTag *rssyl_item_get_xml(Folder *folder, FolderItem *item) (ri->use_default_user_agent ? "1" : "0")) ); if( ri->specific_user_agent != NULL ) xml_tag_add_attr(tag, xml_attr_new("specific_user_agent", ri->specific_user_agent)); + /* (str) Last-Modified header */ + if( ri->last_modified != NULL ) + xml_tag_add_attr(tag, xml_attr_new("last_modified", ri->last_modified)); + /* (str) ETag header */ + if( ri->etag != NULL ) + xml_tag_add_attr(tag, xml_attr_new("etag", ri->etag)); return tag; } @@ -460,6 +476,8 @@ static FolderItem *rssyl_item_new(Folder *folder) ritem->refresh_id = 0; ritem->use_default_user_agent = 1; ritem->specific_user_agent = NULL; + ritem->last_modified = NULL; + ritem->etag = NULL; return (FolderItem *)ritem; } @@ -484,6 +502,9 @@ static void rssyl_item_destroy(Folder *folder, FolderItem *item) if( ritem->refresh_id != 0) g_source_remove(ritem->refresh_id); + g_free(ritem->last_modified); + g_free(ritem->etag); + g_free(ritem); } @@ -1004,6 +1025,16 @@ static void rssyl_copy_private_data(Folder *folder, FolderItem *oldi, newitem->specific_user_agent = g_strdup(olditem->specific_user_agent); } + /* ETag, Last-Modified */ + if (olditem->etag != NULL) { + g_free(newitem->etag); + newitem->etag = g_strdup(olditem->etag); + } + if (olditem->last_modified != NULL) { + g_free(newitem->last_modified); + newitem->last_modified = g_strdup(olditem->last_modified); + } + pathold = rssyl_item_get_path(oldi->folder, oldi); dpathold = g_strconcat(pathold, G_DIR_SEPARATOR_S, RSSYL_DELETED_FILE, NULL); pathnew = rssyl_item_get_path(newi->folder, newi); diff --git a/src/plugins/rssyl/rssyl.h b/src/plugins/rssyl/rssyl.h @@ -70,6 +70,8 @@ struct _RFolderItem { guint refresh_id; gboolean fetching_comments; time_t last_update; + gchar *last_modified; + gchar *etag; gboolean use_default_user_agent; gchar *specific_user_agent; diff --git a/src/plugins/rssyl/rssyl_feed.h b/src/plugins/rssyl/rssyl_feed.h @@ -28,6 +28,7 @@ #define RSSYL_LOG_SUBSCRIBING _("RSSyl: Subscribing new feed: %s\n") #define RSSYL_LOG_SUBSCRIBED _("RSSyl: New feed subscribed: '%s' (%s)\n") #define RSSYL_LOG_UPDATING _("RSSyl: Updating feed: %s (User-Agent: %s)\n") +#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_ERROR_NOFEED _("RSSyl: No valid feed found at '%s'\n") diff --git a/src/plugins/rssyl/rssyl_update_feed.c b/src/plugins/rssyl/rssyl_update_feed.c @@ -179,7 +179,7 @@ void rssyl_fetch_feed(RFetchCtx *ctx, RSSylVerboseFlags verbose) log_error(LOG_PROTOCOL, RSSYL_LOG_ERROR_FETCH, ctx->feed->url, ctx->error); ctx->success = FALSE; - } else { + } else if (ctx->response_code != 304) { if( ctx->feed == NULL || ctx->response_code == FEED_ERR_NOFEED) { if( verbose & RSSYL_SHOW_ERRORS) { gchar *msg = g_markup_printf_escaped( @@ -229,6 +229,8 @@ RFetchCtx *rssyl_prep_fetchctx_from_item(RFolderItem *ritem) debug_print("RSSyl: using cert file '%s'\n", feed_get_cacert_file(ctx->feed)); } #endif + feed_set_etag(ctx->feed, ritem->etag); + feed_set_last_modified(ctx->feed, ritem->last_modified); return ctx; } @@ -309,6 +311,20 @@ gboolean rssyl_update_feed(RFolderItem *ritem, RSSylVerboseFlags verbose) return FALSE; } + g_free(ritem->etag); + gchar *etag = feed_get_etag(ctx->feed); + ritem->etag = etag ? g_strdup(etag) : NULL; + g_free(ritem->last_modified); + gchar *last_modified = feed_get_last_modified(ctx->feed); + ritem->last_modified = last_modified ? g_strdup(last_modified) : NULL; + + /* Not modified, no content, nothing to parse */ + if (ctx->response_code == 304) { + STATUSBAR_POP(mainwin); + log_print(LOG_PROTOCOL, RSSYL_LOG_NOT_MODIFIED, ritem->url); + goto cleanup; + } + rssyl_deleted_update(ritem); debug_print("RSSyl: Starting to parse feed\n"); @@ -347,6 +363,7 @@ gboolean rssyl_update_feed(RFolderItem *ritem, RSSylVerboseFlags verbose) rssyl_deleted_store(ritem); rssyl_deleted_free(ritem); +cleanup: /* Clean up. */ success = ctx->success; feed_free(ctx->feed);