Description: Fix authentication issues when using external APIs
 Prevents HTTP header reset on subsequent reloads which caused the authenication
 headers to be removed.
 Please note that this patch, for reasons unknown at the time of writing
 this, heavily increases memory usage in some cases. The issue is tracked
 upstream at https://github.com/akrennmair/newsbeuter/issues/458
Origin: upstream, https://github.com/akrennmair/newsbeuter/commit/fccad71a21fadbfc0da4bfd1527de56ca03f67e5
Bug: https://github.com/akrennmair/newsbeuter/issues/150

--- a/include/feedhq_api.h
+++ b/include/feedhq_api.h
@@ -13,7 +13,7 @@
 		virtual ~feedhq_api();
 		virtual bool authenticate();
 		virtual std::vector<tagged_feedurl> get_subscribed_urls();
-		virtual void configure_handle(CURL * handle);
+		virtual void configure_handle(curl_slist** custom_headers);
 		virtual bool mark_all_read(const std::string& feedurl);
 		virtual bool mark_article_read(const std::string& guid, bool read);
 		virtual bool update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid);
@@ -27,6 +27,7 @@
 		bool share_article(const std::string& guid, bool share);
 		bool mark_article_read_with_token(const std::string& guid, bool read, const std::string& token);
 		std::string auth;
+		std::string auth_header;
 };
 
 class feedhq_urlreader : public urlreader {
--- a/include/newsblur_api.h
+++ b/include/newsblur_api.h
@@ -18,7 +18,7 @@
 		virtual ~newsblur_api();
 		virtual bool authenticate();
 		virtual std::vector<tagged_feedurl> get_subscribed_urls();
-		virtual void configure_handle(CURL * handle);
+		virtual void configure_handle(curl_slist** custom_headers);
 		virtual bool mark_all_read(const std::string& feedurl);
 		virtual bool mark_article_read(const std::string& guid, bool read);
 		virtual bool update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid);
--- a/include/oldreader_api.h
+++ b/include/oldreader_api.h
@@ -13,7 +13,7 @@
 		virtual ~oldreader_api();
 		virtual bool authenticate();
 		virtual std::vector<tagged_feedurl> get_subscribed_urls();
-		virtual void configure_handle(CURL * handle);
+		virtual void configure_handle(curl_slist** custom_headers);
 		virtual bool mark_all_read(const std::string& feedurl);
 		virtual bool mark_article_read(const std::string& guid, bool read);
 		virtual bool update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid);
@@ -27,6 +27,7 @@
 		bool share_article(const std::string& guid, bool share);
 		bool mark_article_read_with_token(const std::string& guid, bool read, const std::string& token);
 		std::string auth;
+		std::string auth_header;
 };
 
 class oldreader_urlreader : public urlreader {
--- a/include/remote_api.h
+++ b/include/remote_api.h
@@ -17,7 +17,7 @@
 		virtual ~remote_api() { }
 		virtual bool authenticate() = 0;
 		virtual std::vector<tagged_feedurl> get_subscribed_urls() = 0;
-		virtual void configure_handle(CURL * handle) = 0;
+		virtual void configure_handle(curl_slist** custom_headers) = 0;
 		virtual bool mark_all_read(const std::string& feedurl) = 0;
 		virtual bool mark_article_read(const std::string& guid, bool read) = 0;
 		virtual bool update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid) = 0;
--- a/include/ttrss_api.h
+++ b/include/ttrss_api.h
@@ -16,7 +16,7 @@
 		virtual struct json_object * run_op(const std::string& op, const std::map<std::string, std::string>& args,
 		                                    bool try_login = true);
 		virtual std::vector<tagged_feedurl> get_subscribed_urls();
-		virtual void configure_handle(CURL * handle);
+		virtual void configure_handle(curl_slist** custom_headers);
 		virtual bool mark_all_read(const std::string& feedurl);
 		virtual bool mark_article_read(const std::string& guid, bool read);
 		virtual bool update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid);
--- a/rss/parser.cpp
+++ b/rss/parser.cpp
@@ -72,6 +72,7 @@
 feed parser::parse_url(const std::string& url, time_t lastmodified, const std::string& etag, newsbeuter::remote_api * api, const std::string& cookie_cache, CURL *ehandle) {
 	std::string buf;
 	CURLcode ret;
+	curl_slist* custom_headers {};
 
 	CURL * easyhandle = ehandle;
 	if (!easyhandle) {
@@ -84,8 +85,9 @@
 	if (ua) {
 		curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, ua);
 	}
+
 	if (api) {
-		api->configure_handle(easyhandle);
+		api->configure_handle(&custom_headers);
 	}
 	curl_easy_setopt(easyhandle, CURLOPT_URL, url.c_str());
 	curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, verify_ssl);
@@ -122,9 +124,13 @@
 		curl_easy_setopt(easyhandle, CURLOPT_TIMEVALUE, lastmodified);
 	}
 
-	curl_slist * custom_headers = NULL;
 	if (etag.length() > 0) {
-		custom_headers = curl_slist_append(custom_headers, utils::strprintf("If-None-Match: %s", etag.c_str()).c_str());
+		custom_headers = curl_slist_append(
+				custom_headers,
+				utils::strprintf("If-None-Match: %s", etag.c_str()).c_str());
+	}
+
+	if(custom_headers) {
 		curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, custom_headers);
 	}
 
@@ -147,6 +153,8 @@
 		LOG(LOG_USERERROR, _("Error: trying to download feed `%s' returned HTTP status code %ld."), url.c_str(), status);
 	}
 
+	curl_easy_reset(easyhandle);
+
 	if (!ehandle)
 		curl_easy_cleanup(easyhandle);
 
--- a/src/feedhq_api.cpp
+++ b/src/feedhq_api.cpp
@@ -118,7 +118,9 @@
 
 	CURL * handle = curl_easy_init();
 	std::string result;
-	configure_handle(handle);
+	curl_slist* custom_headers {};
+	configure_handle(&custom_headers);
+	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, custom_headers);
 
 	utils::set_common_curl_options(handle, cfg);
 	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_data);
@@ -175,12 +177,14 @@
 	return urls;
 }
 
-void feedhq_api::configure_handle(CURL * handle) {
-	struct curl_slist *chunk = NULL;
-	std::string header = utils::strprintf("Authorization: GoogleLogin auth=%s", auth.c_str());
-	LOG(LOG_DEBUG, "feedhq_api::configure_handle header = %s", header.c_str());
-	chunk = curl_slist_append(chunk, header.c_str());
-	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, chunk);
+void feedhq_api::configure_handle(curl_slist** custom_headers) {
+	if(auth_header.empty()) {
+		auth_header = utils::strprintf(
+				"Authorization: GoogleLogin auth=%s", auth.c_str());
+	}
+	LOG(LOG_DEBUG, "feedhq_api::configure_handle header = %s",
+			auth_header.c_str());
+	*custom_headers = curl_slist_append(*custom_headers, auth_header.c_str());
 }
 
 bool feedhq_api::mark_all_read(const std::string& feedurl) {
@@ -240,9 +244,11 @@
 std::string feedhq_api::get_new_token() {
 	CURL * handle = curl_easy_init();
 	std::string result;
+	curl_slist* custom_headers {};
 
 	utils::set_common_curl_options(handle, cfg);
-	configure_handle(handle);
+	configure_handle(&custom_headers);
+	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, custom_headers);
 	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_data);
 	curl_easy_setopt(handle, CURLOPT_WRITEDATA, &result);
 	curl_easy_setopt(handle, CURLOPT_URL, FEEDHQ_API_TOKEN_URL);
@@ -310,10 +316,12 @@
 
 std::string feedhq_api::post_content(const std::string& url, const std::string& postdata) {
 	std::string result;
+	curl_slist* custom_headers {};
 
 	CURL * handle = curl_easy_init();
 	utils::set_common_curl_options(handle, cfg);
-	configure_handle(handle);
+	configure_handle(&custom_headers);
+	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, custom_headers);
 	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_data);
 	curl_easy_setopt(handle, CURLOPT_WRITEDATA, &result);
 	curl_easy_setopt(handle, CURLOPT_POSTFIELDS, postdata.c_str());
--- a/src/newsblur_api.cpp
+++ b/src/newsblur_api.cpp
@@ -69,7 +69,7 @@
 	return result;
 }
 
-void newsblur_api::configure_handle(CURL * /*handle*/) {
+void newsblur_api::configure_handle(curl_slist** /* custom_headers */) {
 	// nothing required
 }
 
--- a/src/oldreader_api.cpp
+++ b/src/oldreader_api.cpp
@@ -117,10 +117,12 @@
 
 std::vector<tagged_feedurl> oldreader_api::get_subscribed_urls() {
 	std::vector<tagged_feedurl> urls;
+	curl_slist* custom_headers {};
 
 	CURL * handle = curl_easy_init();
 	std::string result;
-	configure_handle(handle);
+	configure_handle(&custom_headers);
+	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, custom_headers);
 
 	utils::set_common_curl_options(handle, cfg);
 	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_data);
@@ -158,9 +160,19 @@
 		json_object_object_get_ex(sub, "title", &node);
 		const char * title = json_object_get_string(node);
 
-		tags.push_back(std::string("~") + title);
-
-		urls.push_back(tagged_feedurl(utils::strprintf("%s%s?n=%u", OLDREADER_FEED_PREFIX, id, cfg->get_configvalue_as_int("oldreader-min-items")), tags));
+		// Ignore URLs where ID start with given prefix - those never load,
+		// always returning 404 and annoying people
+		const char* prefix = "tor/sponsored/";
+		if(strncmp(id, prefix, strlen(prefix)) != 0) {
+			tags.push_back(std::string("~") + title);
+
+			auto url = utils::strprintf(
+				"%s%s?n=%u",
+				OLDREADER_FEED_PREFIX,
+				id,
+				cfg->get_configvalue_as_int("oldreader-min-items"));
+			urls.push_back(tagged_feedurl(url, tags));
+		}
 	}
 
 	json_object_put(reply);
@@ -168,12 +180,12 @@
 	return urls;
 }
 
-void oldreader_api::configure_handle(CURL * handle) {
-	struct curl_slist *chunk = NULL;
-	std::string header = utils::strprintf("Authorization: GoogleLogin auth=%s", auth.c_str());
-	LOG(LOG_DEBUG, "oldreader_api::configure_handle header = %s", header.c_str());
-	chunk = curl_slist_append(chunk, header.c_str());
-	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, chunk);
+void oldreader_api::configure_handle(curl_slist** custom_headers) {
+	if(auth_header.empty()) {
+		auth_header = utils::strprintf("Authorization: GoogleLogin auth=%s", auth.c_str());
+	}
+	LOG(LOG_DEBUG, "oldreader_api::configure_handle header = %s", auth_header.c_str());
+	*custom_headers = curl_slist_append(*custom_headers, auth_header.c_str());
 }
 
 bool oldreader_api::mark_all_read(const std::string& feedurl) {
@@ -232,9 +244,11 @@
 std::string oldreader_api::get_new_token() {
 	CURL * handle = curl_easy_init();
 	std::string result;
+	curl_slist* custom_headers {};
 
 	utils::set_common_curl_options(handle, cfg);
-	configure_handle(handle);
+	configure_handle(&custom_headers);
+	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, custom_headers);
 	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_data);
 	curl_easy_setopt(handle, CURLOPT_WRITEDATA, &result);
 	curl_easy_setopt(handle, CURLOPT_URL, OLDREADER_API_TOKEN_URL);
@@ -302,10 +316,12 @@
 
 std::string oldreader_api::post_content(const std::string& url, const std::string& postdata) {
 	std::string result;
+	curl_slist* custom_headers {};
 
 	CURL * handle = curl_easy_init();
 	utils::set_common_curl_options(handle, cfg);
-	configure_handle(handle);
+	configure_handle(&custom_headers);
+	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, custom_headers);
 	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_data);
 	curl_easy_setopt(handle, CURLOPT_WRITEDATA, &result);
 	curl_easy_setopt(handle, CURLOPT_POSTFIELDS, postdata.c_str());
--- a/src/ttrss_api.cpp
+++ b/src/ttrss_api.cpp
@@ -181,7 +181,7 @@
 	return feeds;
 }
 
-void ttrss_api::configure_handle(CURL * /*handle*/) {
+void ttrss_api::configure_handle(curl_slist** /* custom_headers */) {
 	// nothing required
 }
 
