X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Frssclient%2Fserv_rssclient.c;h=acae637871a5830a0b3aac56ead9ab2662b36738;hb=d268ace45e855ddadeea5c837a31dea33f0f26bd;hp=c8f67c5c8c33d450e7bccaab377ad04d393805a9;hpb=15456771533c4b86f6593d28fad7bc69700e2448;p=citadel.git diff --git a/citadel/modules/rssclient/serv_rssclient.c b/citadel/modules/rssclient/serv_rssclient.c index c8f67c5c8..acae63787 100644 --- a/citadel/modules/rssclient/serv_rssclient.c +++ b/citadel/modules/rssclient/serv_rssclient.c @@ -1,7 +1,7 @@ /* * Bring external RSS feeds into rooms. * - * Copyright (c) 2007-2012 by the citadel.org team + * Copyright (c) 2007-2016 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -108,6 +108,37 @@ ConstStr RSSStates[] = { {HKEY("checking usetable")} }; + +static size_t GetLocationString( void *ptr, size_t size, size_t nmemb, void *userdata) +{ +#define LOCATION "location" + if (strncasecmp((char*)ptr, LOCATION, sizeof(LOCATION) - 1) == 0) + { + AsyncIO *IO = (AsyncIO *) userdata; + rss_aggregator *RSSAggr = (rss_aggregator *)IO->Data; + + char *pch = (char*) ptr; + char *pche; + + pche = pch + (size * nmemb); + pch += sizeof(LOCATION); + + while (isspace(*pch) || (*pch == ':')) + pch ++; + + while (isspace(*pche) || (*pche == '\0')) + pche--; + if (RSSAggr->RedirectUrl == NULL) { + RSSAggr->RedirectUrl = NewStrBufPlain(pch, pche - pch + 1); + } + else { + FlushStrBuf(RSSAggr->RedirectUrl); + StrBufPlain(RSSAggr->RedirectUrl, pch, pche - pch + 1); + } + } + return size * nmemb; +} + static void SetRSSState(AsyncIO *IO, RSSState State) { CitContext* CCC = IO->CitContext; @@ -191,6 +222,7 @@ void DeleteRssCfg(void *vptr) EVRSSCM_syslog(LOG_DEBUG, "RSS: destroying\n"); FreeStrBuf(&RSSAggr->Url); + FreeStrBuf(&RSSAggr->RedirectUrl); FreeStrBuf(&RSSAggr->rooms); FreeStrBuf(&RSSAggr->CData); FreeStrBuf(&RSSAggr->Key); @@ -333,7 +365,7 @@ int rss_format_item(AsyncIO *IO, networker_save_message *SaveMsg) CM_SetField(&SaveMsg->Msg, eAuthor, HKEY("rss")); } - CM_SetField(&SaveMsg->Msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(&SaveMsg->Msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); if (SaveMsg->title != NULL) { long len; char *Sbj; @@ -343,20 +375,25 @@ int rss_format_item(AsyncIO *IO, networker_save_message *SaveMsg) StrBufSpaceToBlank(SaveMsg->title); len = StrLength(SaveMsg->title); Sbj = html_to_ascii(ChrPtr(SaveMsg->title), len, 512, 0); - len = strlen(Sbj); - if ((len > 0) && (Sbj[len - 1] == '\n')) - { - len --; - Sbj[len] = '\0'; - } - Encoded = NewStrBufPlain(Sbj, len); - free(Sbj); - - StrBufTrim(Encoded); - StrBufRFC2047encode(&QPEncoded, Encoded); + if (!IsEmptyStr(Sbj)) { + len = strlen(Sbj); + if ((Sbj[len - 1] == '\n')) + { + len --; + Sbj[len] = '\0'; + } + Encoded = NewStrBufPlain(Sbj, len); + - CM_SetAsFieldSB(&SaveMsg->Msg, eMsgSubject, &QPEncoded); - FreeStrBuf(&Encoded); + StrBufTrim(Encoded); + StrBufRFC2047encode(&QPEncoded, Encoded); + + CM_SetAsFieldSB(&SaveMsg->Msg, eMsgSubject, &QPEncoded); + FreeStrBuf(&Encoded); + } + if (Sbj != NULL) { + free(Sbj); + } } if (SaveMsg->link == NULL) SaveMsg->link = NewStrBufPlain(HKEY("")); @@ -470,9 +507,9 @@ eNextState RSS_FetchNetworkUsetableEntry(AsyncIO *IO) void UpdateLastKnownGood(pRSSConfig *pCfg, time_t now) { - OneRoomNetCfg* pRNCfg; + OneRoomNetCfg *pRNCfg; begin_critical_section(S_NETCONFIGS); - pRNCfg = CtdlGetNetCfgForRoom (pCfg->QRnumber); + pRNCfg = CtdlGetNetCfgForRoom(pCfg->QRnumber); if (pRNCfg != NULL) { RSSCfgLine *RSSCfg = (RSSCfgLine *)pRNCfg->NetConfigs[rssclient]; @@ -491,6 +528,8 @@ void UpdateLastKnownGood(pRSSConfig *pCfg, time_t now) } } + SaveRoomNetConfigFile(pRNCfg, pCfg->QRnumber); + FreeRoomNetworkStruct(&pRNCfg); end_critical_section(S_NETCONFIGS); } @@ -505,8 +544,11 @@ eNextState RSSAggregator_AnalyseReply(AsyncIO *IO) StrBuf *guid; rss_aggregator *Ctx = (rss_aggregator *) IO->Data; - if (IO->HttpReq.httpcode != 200) - { + + if ((IO->HttpReq.httpcode >= 300) && + (IO->HttpReq.httpcode < 400) && + (Ctx->RedirectUrl != NULL)) { + StrBuf *ErrMsg; long lens[2]; const char *strs[2]; @@ -515,7 +557,55 @@ eNextState RSSAggregator_AnalyseReply(AsyncIO *IO) ErrMsg = NewStrBuf(); if (IO) EVRSSC_syslog(LOG_ALERT, "need a 200, got a %ld !\n", IO->HttpReq.httpcode); + strs[0] = ChrPtr(Ctx->Url); + lens[0] = StrLength(Ctx->Url); + + strs[1] = ChrPtr(Ctx->rooms); + lens[1] = StrLength(Ctx->rooms); + + if (IO->HttpReq.CurlError == NULL) + IO->HttpReq.CurlError = ""; + + StrBufPrintf(ErrMsg, + "Error while RSS-Aggregation Run of %s\n" + " need a 200, got a %ld !\n" + " Curl Error message: \n%s / %s\n" + " Redirect header points to: %s\n" + " Response text was: \n" + " \n %s\n", + ChrPtr(Ctx->Url), + IO->HttpReq.httpcode, + IO->HttpReq.errdesc, + IO->HttpReq.CurlError, + ChrPtr(Ctx->RedirectUrl), + ChrPtr(IO->HttpReq.ReplyData) + ); + + CtdlAideFPMessage( + ChrPtr(ErrMsg), + "RSS Aggregation run failure", + 2, strs, (long*) &lens, + CCID, + IO->ID, + EvGetNow(IO)); + FreeStrBuf(&ErrMsg); + EVRSSC_syslog(LOG_DEBUG, + "RSS feed returned an invalid http status code. <%s>\n", + ChrPtr(Ctx->Url), + IO->HttpReq.httpcode); + return eAbort; + } + else if (IO->HttpReq.httpcode != 200) + { + StrBuf *ErrMsg; + long lens[2]; + const char *strs[2]; + + SetRSSState(IO, eRSSFailure); + ErrMsg = NewStrBuf(); + if (IO) EVRSSC_syslog(LOG_ALERT, "need a 200, got a %ld !\n", + IO->HttpReq.httpcode); strs[0] = ChrPtr(Ctx->Url); lens[0] = StrLength(Ctx->Url); @@ -602,7 +692,7 @@ eNextState RSSAggregator_AnalyseReply(AsyncIO *IO) guid, EvGetNow(IO), EvGetNow(IO) - USETABLE_ANTIEXPIRE, - eCheckUpdate, + eUpdate, CCID, IO->ID) != 0) { @@ -630,6 +720,9 @@ int rss_do_fetching(rss_aggregator *RSSAggr) AsyncIO *IO = &RSSAggr->IO; rss_item *ri; time_t now; + CURLcode sta; + CURL *chnd; + now = time(NULL); @@ -651,6 +744,9 @@ int rss_do_fetching(rss_aggregator *RSSAggr) EVRSSCM_syslog(LOG_ALERT, "Unable to initialize libcurl.\n"); return 0; } + chnd = IO->HttpReq.chnd; + OPT(HEADERDATA, IO); + OPT(HEADERFUNCTION, GetLocationString); SetRSSState(IO, eRSSCreated); safestrncpy(((CitContext*)RSSAggr->IO.CitContext)->cs_host, @@ -676,6 +772,8 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data, OneRoomNetCfg *OneR rss_aggregator *use_this_RSSAggr = NULL; void *vptr; + TRACE; + pthread_mutex_lock(&RSSQueueMutex); if (GetHash(RSSQueueRooms, LKEY(qrbuf->QRnumber), &vptr)) {