From 65b365733562d0101e76945603c7c3b93f2fa97d Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Fri, 29 Jan 2016 19:54:46 -0500 Subject: [PATCH] SSPCPP-669 - cached samlds.json files prematurely removed w/ multiple applicationIds https://issues.shibboleth.net/jira/browse/SSPCPP-669 Split management of disco feed files into app-specific queues and embed applicationId hash into feed file names. --- shibsp/handler/impl/DiscoveryFeed.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/shibsp/handler/impl/DiscoveryFeed.cpp b/shibsp/handler/impl/DiscoveryFeed.cpp index f0f3514..f60293b 100644 --- a/shibsp/handler/impl/DiscoveryFeed.cpp +++ b/shibsp/handler/impl/DiscoveryFeed.cpp @@ -92,9 +92,10 @@ namespace shibsp { string m_dir; bool m_cacheToClient; #ifndef SHIBSP_LITE - // A queue of feed files, linked to the last time of "access". + // Application-specific queues of feed files, linked to the last time of "access". // Each filename is also a cache tag. - mutable queue< pair > m_feedQueue; + typedef queue< pair > feedqueue_t; + mutable map m_feedQueues; scoped_ptr m_feedLock; #endif }; @@ -142,10 +143,12 @@ DiscoveryFeed::~DiscoveryFeed() // Remove any files unused for more than a couple of minutes. // Anything left will be orphaned, but that shouldn't happen too often. time_t now = time(nullptr); - while (!m_feedQueue.empty() && now - m_feedQueue.front().second > 120) { - string fname = m_dir + '/' + m_feedQueue.front().first + ".json"; - remove(fname.c_str()); - m_feedQueue.pop(); + for (map::iterator i = m_feedQueues.begin(); i != m_feedQueues.end(); ++i) { + while (!i->second.empty() && now - i->second.front().second > 120) { + string fname = m_dir + '/' + i->second.front().first + ".json"; + remove(fname.c_str()); + i->second.pop(); + } } } #endif @@ -157,8 +160,9 @@ pair DiscoveryFeed::run(SPRequest& request, bool isHandler) const SPConfig& conf = SPConfig::getConfig(); string s; - if (m_cacheToClient) + if (m_cacheToClient) { s = request.getHeader("If-None-Match"); + } if (conf.isEnabled(SPConfig::OutOfProcess)) { // When out of process, we run natively and directly process the message. @@ -215,7 +219,7 @@ pair DiscoveryFeed::run(SPRequest& request, bool isHandler) const return make_pair(true, request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_NOTMODIFIED)); } - string fname = m_dir + '/' + s + ".json"; + string fname = m_dir + '/' + request.getApplication().getHash() + '_' + s + ".json"; ifstream feed(fname.c_str()); if (!feed) throw ConfigurationException("Unable to access cached feed in ($1).", params(1,fname.c_str())); @@ -294,15 +298,16 @@ void DiscoveryFeed::feedToFile(const Application& application, string& cacheTag) time_t now = time(nullptr); // Clean up any old files. - while (m_feedQueue.size() > 1 && (now - m_feedQueue.front().second > 120)) { - string fname = m_dir + '/' + m_feedQueue.front().first + ".json"; + feedqueue_t q = m_feedQueues[application.getId()]; + while (q.size() > 1 && (now - q.front().second > 120)) { + string fname = m_dir + '/' + application.getHash() + '_' + q.front().first + ".json"; remove(fname.c_str()); - m_feedQueue.pop(); + q.pop(); } - if (m_feedQueue.empty() || m_feedQueue.back().first != feedTag) { + if (q.empty() || q.back().first != feedTag) { // We're out of date. - string fname = m_dir + '/' + feedTag + ".json"; + string fname = m_dir + '/' + application.getHash() + '_' + feedTag + ".json"; ofstream ofile(fname.c_str()); if (!ofile) throw ConfigurationException("Unable to create feed in ($1).", params(1,fname.c_str())); @@ -312,11 +317,11 @@ void DiscoveryFeed::feedToFile(const Application& application, string& cacheTag) else ofile << "[\n]"; ofile.close(); - m_feedQueue.push(make_pair(feedTag, now)); + q.push(make_pair(feedTag, now)); } else { // Update the back of the queue. - m_feedQueue.back().second = now; + q.back().second = now; } #else throw ConfigurationException("Build does not support discovery feed."); -- 2.1.4