RSSyl: Stop earlier when an invalid feed is encountered.
[claws.git] / src / plugins / rssyl / rssyl_update_feed.c
index 603d000e93dab667161ffa815a0345680e05e03e..e74045c99e650ae970cf246b9d1709b2f90b1f0e 100644 (file)
@@ -61,7 +61,7 @@ static void *rssyl_fetch_feed_thr(void *arg)
 }
 
 /* rssyl_fetch_feed() */
-void rssyl_fetch_feed(RFetchCtx *ctx, gboolean verbose)
+void rssyl_fetch_feed(RFetchCtx *ctx, RSSylVerboseFlags verbose)
 {
 #ifdef USE_PTHREAD
        pthread_t pt;
@@ -96,6 +96,9 @@ void rssyl_fetch_feed(RFetchCtx *ctx, gboolean verbose)
        } else if( ctx->response_code == FEED_ERR_FETCH ) {
                debug_print("RSSyl: libfeed reports some other error from libcurl\n");
                ctx->error = g_strdup(ctx->feed->fetcherr);
+       } 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 ) {
                switch( ctx->response_code ) {
                        case 401:
@@ -113,31 +116,43 @@ void rssyl_fetch_feed(RFetchCtx *ctx, gboolean verbose)
                }
        }
 
-       /* Here we handle "imperfect" conditions. If verbose is TRUE, we also
+       /* Here we handle "imperfect" conditions. If requested, we also
         * display error dialogs for user. We always log the error. */
        if( ctx->error != NULL ) {
                /* libcurl wasn't happy */
                debug_print("RSSyl: Error: %s\n", ctx->error);
-               if( verbose )
-                       alertpanel_error(g_markup_printf_escaped(C_("First parameter is URL, second is error text",
+               if( verbose & RSSYL_SHOW_ERRORS) {
+                       gchar *msg = g_markup_printf_escaped(
+                                       (const char *) C_("First parameter is URL, second is error text",
                                                "Error fetching feed at\n<b>%s</b>:\n\n%s"),
-                                       feed_get_url(ctx->feed), ctx->error));
+                                       feed_get_url(ctx->feed), ctx->error);
+                       alertpanel_error("%s", msg);
+                       g_free(msg);
+               }
 
                log_error(LOG_PROTOCOL, RSSYL_LOG_ERROR_FETCH, ctx->feed->url, ctx->error);
 
                ctx->success = FALSE;
        } else {
-               if( feed_get_title(ctx->feed) == NULL ) {
-                       /* libcurl was happy, but libfeed wasn't */
-                       debug_print("RSSyl: Error reading feed\n");
-                       if( verbose )
-                               alertpanel_error(g_markup_printf_escaped(_("No valid feed found at\n<b>%s</b>"),
-                                                       feed_get_url(ctx->feed)));
+               if( ctx->feed == NULL || ctx->response_code == FEED_ERR_NOFEED) {
+                       if( verbose & RSSYL_SHOW_ERRORS) {
+                               gchar *msg = g_markup_printf_escaped(
+                                               (const char *) _("No valid feed found at\n<b>%s</b>"),
+                                               feed_get_url(ctx->feed));
+                               alertpanel_error("%s", msg);
+                               g_free(msg);
+                       }
 
                        log_error(LOG_PROTOCOL, RSSYL_LOG_ERROR_NOFEED,
                                        feed_get_url(ctx->feed));
 
                        ctx->success = FALSE;
+               } else if (feed_get_title(ctx->feed) == NULL) {
+                       /* We shouldn't do this, since a title is mandatory. */
+                       feed_set_title(ctx->feed, _("Untitled feed"));
+                       log_print(LOG_PROTOCOL,
+                                       _("RSSyl: Possibly invalid feed without title at %s.\n"),
+                                       feed_get_url(ctx->feed));
                }
        }
 }
@@ -154,9 +169,19 @@ RFetchCtx *rssyl_prep_fetchctx_from_item(RFolderItem *ritem)
        ctx->success = TRUE;
        ctx->ready = FALSE;
 
-       feed_set_timeout(ctx->feed, prefs_common.io_timeout_secs);
+       if (ritem->auth->type != FEED_AUTH_NONE)
+               ritem->auth->password = rssyl_passwd_get(ritem);
+
+       feed_set_timeout(ctx->feed, prefs_common_get_prefs()->io_timeout_secs);
        feed_set_cookies_path(ctx->feed, rssyl_prefs_get()->cookies_path);
        feed_set_ssl_verify_peer(ctx->feed, ritem->ssl_verify_peer);
+       feed_set_auth(ctx->feed, ritem->auth);
+#ifdef G_OS_WIN32
+       if (!g_ascii_strncasecmp(ritem->url, "https", 5)) {
+               feed_set_cacert_file(ctx->feed, claws_ssl_get_cert_file());
+               debug_print("RSSyl: using cert file '%s'\n", feed_get_cacert_file(ctx->feed));
+       }
+#endif
 
        return ctx;
 }
@@ -173,16 +198,22 @@ RFetchCtx *rssyl_prep_fetchctx_from_url(gchar *url)
        ctx->success = TRUE;
        ctx->ready = FALSE;
 
-       feed_set_timeout(ctx->feed, prefs_common.io_timeout_secs);
+       feed_set_timeout(ctx->feed, prefs_common_get_prefs()->io_timeout_secs);
        feed_set_cookies_path(ctx->feed, rssyl_prefs_get()->cookies_path);
        feed_set_ssl_verify_peer(ctx->feed, rssyl_prefs_get()->ssl_verify_peer);
+#ifdef G_OS_WIN32
+       if (!g_ascii_strncasecmp(url, "https", 5)) {
+               feed_set_cacert_file(ctx->feed, claws_ssl_get_cert_file());
+               debug_print("RSSyl: using cert file '%s'\n", feed_get_cacert_file(ctx->feed));
+       }
+#endif
 
        return ctx;
 }
 
 /* rssyl_update_feed() */
 
-gboolean rssyl_update_feed(RFolderItem *ritem, gboolean verbose)
+gboolean rssyl_update_feed(RFolderItem *ritem, RSSylVerboseFlags verbose)
 {
        RFetchCtx *ctx = NULL;
        MainWindow *mainwin = mainwindow_get_mainwindow();
@@ -210,6 +241,11 @@ gboolean rssyl_update_feed(RFolderItem *ritem, gboolean verbose)
        /* Fetch the feed file */
        rssyl_fetch_feed(ctx, verbose);
 
+       if (ritem->auth != NULL && ritem->auth->password != NULL) {
+               memset(ritem->auth->password, 0, strlen(ritem->auth->password));
+               g_free(ritem->auth->password);
+       }
+
        debug_print("RSSyl: fetch done; success == %s\n",
                        ctx->success ? "TRUE" : "FALSE");
 
@@ -217,9 +253,14 @@ gboolean rssyl_update_feed(RFolderItem *ritem, gboolean verbose)
   if( ctx->success && !(ctx->success = rssyl_parse_feed(ritem, ctx->feed)) ) {
                /* both libcurl and libfeed were happy, but we weren't */
                debug_print("RSSyl: Error processing feed\n");
-               if( verbose )
-                       alertpanel_error(_("Couldn't process feed at\n<b>%s</b>\n\nPlease contact developers, this should not happen."),
+               if( verbose & RSSYL_SHOW_ERRORS ) {
+                       gchar *msg = g_markup_printf_escaped(
+                                       (const char *) _("Couldn't process feed at\n<b>%s</b>\n\n"
+                                               "Please contact developers, this should not happen."),
                                        feed_get_url(ctx->feed));
+                       alertpanel_error("%s", msg);
+                       g_free(msg);
+               }
 
                log_error(LOG_PROTOCOL, RSSYL_LOG_ERROR_PROC, ctx->feed->url);
        }
@@ -263,7 +304,7 @@ static gboolean rssyl_update_recursively_func(GNode *node, gpointer data)
 
        if( ritem->url != NULL ) {
                debug_print("RSSyl: Updating feed '%s'\n", item->name);
-               rssyl_update_feed(ritem, FALSE);
+               rssyl_update_feed(ritem, 0);
        } else
                debug_print("RSSyl: Updating in folder '%s'\n", item->name);
 
@@ -296,7 +337,7 @@ void rssyl_update_all_func(FolderItem *item, gpointer data)
 
 void rssyl_update_all_feeds(void)
 {
-       if (prefs_common.work_offline &&
+       if (prefs_common_get_prefs()->work_offline &&
                        !inc_offline_should_override(TRUE,
                                _("Claws Mail needs network access in order to update your feeds.")) ) {
                return;