bool CDAVDirectory::GetDirectory(const CURL& url, CFileItemList &items) { CCurlFile dav; std::string strRequest = "PROPFIND"; dav.SetCustomRequest(strRequest); dav.SetMimeType("text/xml; charset=\"utf-8\""); dav.SetRequestHeader("depth", 1); dav.SetPostData( "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" " <D:propfind xmlns:D=\"DAV:\">" " <D:prop>" " <D:resourcetype/>" " <D:getcontentlength/>" " <D:getlastmodified/>" " <D:creationdate/>" " <D:displayname/>" " </D:prop>" " </D:propfind>"); if (!dav.Open(url)) { CLog::Log(LOGERROR, "%s - Unable to get dav directory (%s)", __FUNCTION__, url.GetRedacted().c_str()); return false; } std::string strResponse; dav.ReadData(strResponse); std::string fileCharset(dav.GetProperty(XFILE::FILE_PROPERTY_CONTENT_CHARSET)); CXBMCTinyXML davResponse; davResponse.Parse(strResponse, fileCharset); if (!davResponse.Parse(strResponse)) { CLog::Log(LOGERROR, "%s - Unable to process dav directory (%s)", __FUNCTION__, url.GetRedacted().c_str()); dav.Close(); return false; } TiXmlNode *pChild; // Iterate over all responses for (pChild = davResponse.RootElement()->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) { if (CDAVCommon::ValueWithoutNamespace(pChild, "response")) { CFileItem item; ParseResponse(pChild->ToElement(), item); CURL url2(url); CURL url3(item.GetPath()); std::string itemPath(URIUtils::AddFileToFolder(url2.GetWithoutFilename(), url3.GetFileName())); if (item.GetLabel().empty()) { std::string name(itemPath); URIUtils::RemoveSlashAtEnd(name); item.SetLabel(CURL::Decode(URIUtils::GetFileName(name))); } if (item.m_bIsFolder) URIUtils::AddSlashAtEnd(itemPath); // Add back protocol options if (!url2.GetProtocolOptions().empty()) itemPath += "|" + url2.GetProtocolOptions(); item.SetPath(itemPath); if (!item.IsURL(url)) { CFileItemPtr pItem(new CFileItem(item)); items.Add(pItem); } } } dav.Close(); return true; }
void CRssReader::Process() { while (GetQueueSize()) { CSingleLock lock(m_critical); int iFeed = m_vecQueue.front(); m_vecQueue.erase(m_vecQueue.begin()); m_strFeed[iFeed].clear(); m_strColors[iFeed].clear(); CCurlFile http; http.SetUserAgent(CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_userAgent); http.SetTimeout(2); std::string strXML; std::string strUrl = m_vecUrls[iFeed]; lock.Leave(); int nRetries = 3; CURL url(strUrl); std::string fileCharset; // we wait for the network to come up if ((url.IsProtocol("http") || url.IsProtocol("https")) && !CServiceBroker::GetNetwork().IsAvailable()) { CLog::Log(LOGWARNING, "RSS: No network connection"); strXML = "<rss><item><title>"+g_localizeStrings.Get(15301)+"</title></item></rss>"; } else { XbmcThreads::EndTime timeout(15000); while (!m_bStop && nRetries > 0) { if (timeout.IsTimePast()) { CLog::Log(LOGERROR, "Timeout while retrieving rss feed: %s", strUrl.c_str()); break; } nRetries--; if (!url.IsProtocol("http") && !url.IsProtocol("https")) { CFile file; auto_buffer buffer; if (file.LoadFile(strUrl, buffer) > 0) { strXML.assign(buffer.get(), buffer.length()); break; } } else { if (http.Get(strUrl, strXML)) { fileCharset = http.GetProperty(XFILE::FILE_PROPERTY_CONTENT_CHARSET); CLog::Log(LOGDEBUG, "Got rss feed: %s", strUrl.c_str()); break; } else if (nRetries > 0) Sleep(5000); // Network problems? Retry, but not immediately. else CLog::Log(LOGERROR, "Unable to obtain rss feed: %s", strUrl.c_str()); } } http.Cancel(); } if (!strXML.empty() && m_pObserver) { // erase any <content:encoded> tags (also unsupported by tinyxml) size_t iStart = strXML.find("<content:encoded>"); size_t iEnd = 0; while (iStart != std::string::npos) { // get <content:encoded> end position iEnd = strXML.find("</content:encoded>", iStart) + 18; // erase the section strXML = strXML.erase(iStart, iEnd - iStart); iStart = strXML.find("<content:encoded>"); } if (Parse(strXML, iFeed, fileCharset)) CLog::Log(LOGDEBUG, "Parsed rss feed: %s", strUrl.c_str()); } } UpdateObserver(); }