[cpp-sp] branch main updated: Start adjusting (and reverting) some SessionCache APIs.

Scott Cantor cantor.2 at osu.edu
Wed Apr 16 19:23:54 UTC 2025


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=520667cd11b7f4145535f37cde7600b0e9f10534

The following commit(s) were added to refs/heads/main by this push:
     new 520667cd Start adjusting (and reverting) some SessionCache APIs.
520667cd is described below

commit 520667cd11b7f4145535f37cde7600b0e9f10534
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Apr 16 15:23:45 2025 -0400

    Start adjusting (and reverting) some SessionCache APIs.
---
 Projects/vc22/shibsp.vcxproj                   |  3 +-
 Projects/vc22/shibsp.vcxproj.filters           |  5 ++-
 apache/mod_shib_24.cpp                         | 18 ++++++---
 shibsp/Agent.cpp                               | 30 +++-----------
 shibsp/AgentConfig.h                           | 13 +++++-
 shibsp/Makefile.am                             |  1 +
 shibsp/handler/impl/SessionHandler.cpp         | 48 ----------------------
 shibsp/handler/impl/SessionInitiator.cpp       |  1 +
 shibsp/impl/AgentConfig.cpp                    | 10 +++++
 shibsp/impl/XMLAccessControl.cpp               | 28 ++++++-------
 shibsp/session/AbstractSessionCache.h          | 35 ++++++++++++++++
 shibsp/session/SessionCache.h                  | 56 +++++---------------------
 shibsp/session/impl/AbstractSessionCache.cpp   | 14 ++++++-
 shibsp/session/impl/FilesystemSessionCache.cpp |  4 +-
 14 files changed, 119 insertions(+), 147 deletions(-)

diff --git a/Projects/vc22/shibsp.vcxproj b/Projects/vc22/shibsp.vcxproj
index dcc64a78..4d286c22 100644
--- a/Projects/vc22/shibsp.vcxproj
+++ b/Projects/vc22/shibsp.vcxproj
@@ -66,6 +66,7 @@
     <ClInclude Include="..\..\shibsp\remoting\RemotingService.h" />
     <ClInclude Include="..\..\shibsp\remoting\SecretSource.h" />
     <ClInclude Include="..\..\shibsp\RequestMapper.h" />
+    <ClInclude Include="..\..\shibsp\session\AbstractSessionCache.h" />
     <ClInclude Include="..\..\shibsp\session\SessionCache.h" />
     <ClInclude Include="..\..\shibsp\SPRequest.h" />
     <ClInclude Include="..\..\shibsp\util\BoostPropertySet.h" />
@@ -453,4 +454,4 @@ rc.exe /D _UNICODE /D UNICODE /l"0x0409" /nologo /fo"$(IntDir)\%(Filename).res"
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/Projects/vc22/shibsp.vcxproj.filters b/Projects/vc22/shibsp.vcxproj.filters
index 97a42443..42830301 100644
--- a/Projects/vc22/shibsp.vcxproj.filters
+++ b/Projects/vc22/shibsp.vcxproj.filters
@@ -228,6 +228,9 @@
     <ClInclude Include="..\..\shibsp\session\SessionCache.h">
       <Filter>Header Files\Session</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\shibsp\session\AbstractSessionCache.h">
+      <Filter>Header Files\Session</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\shibsp\remoting\SecretSource.h">
       <Filter>Header Files\Remoting</Filter>
     </ClInclude>
@@ -409,4 +412,4 @@
       <Filter>Resource Files</Filter>
     </CustomBuild>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/apache/mod_shib_24.cpp b/apache/mod_shib_24.cpp
index 199c2c5e..08b7bd8b 100644
--- a/apache/mod_shib_24.cpp
+++ b/apache/mod_shib_24.cpp
@@ -1281,7 +1281,9 @@ extern "C" authz_status shib_acclass_check_authz(request_rec* r, const char* req
     try {
         Session* session = sta.first->getSession(false, true, false);
         lock_guard<Session> slocker(*session, adopt_lock);
-        if (session && hta.doAuthnContext(*sta.first, session->getAuthnContextClassRef(), require_line) == AccessControl::shib_acl_true)
+        if (session && hta.doShibAttr(*sta.first, session,
+                sta.first->getAgent().getString("legacy-classref-attribute", "Shib-AuthnContext-Class"),
+                require_line) == AccessControl::shib_acl_true)
             return AUTHZ_GRANTED;
         return session ? AUTHZ_DENIED : AUTHZ_DENIED_NO_USER;
     }
@@ -1442,10 +1444,8 @@ apr_status_t shib_post_config(apr_pool_t* p, apr_pool_t*, apr_pool_t*, server_re
 
 /*
  * shib_child_init()
- *  Things to do when the child process is initialized.
- *  For now, we have no background threads, but if we introduce any, we'd have to switch
- *  back to deferring their creation until this step because only the forking thread shows
- *  up in the child, losing any internal threads spun up by plugins in the agent library.
+
+ * Things to do when the child process is initialized.
  */
 extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
 {
@@ -1466,7 +1466,13 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
     // Set the cleanup handler, passing in the server_rec for logging.
     apr_pool_cleanup_register(p, s, &shib_exit, apr_pool_cleanup_null);
 
-    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, s, "child_init: shib_module config initialized");
+    if (g_Config->start()) {
+        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, s, "child_init: shib_module config initialized");
+    }
+    else {
+        ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s, "child_init: shib_module start method failed");
+    }
+
 }
 
 // Output filters
diff --git a/shibsp/Agent.cpp b/shibsp/Agent.cpp
index 079fc08f..23a788b2 100644
--- a/shibsp/Agent.cpp
+++ b/shibsp/Agent.cpp
@@ -484,33 +484,13 @@ pair<bool,long> Agent::doExport(SPRequest& request, bool requireSession) const
         }
 
         request.setHeader("Shib-Session-ID", session->getID());
-        request.setHeader("Shib-Bucket-ID", session->getBucketID());
+        request.setHeader("Shib-Application-ID", session->getApplicationID());
 
         // Check for export of "standard" variables.
-        bool stdvars = settings.first->getBool("exportStdVars", false);
-        if (stdvars) {
-            const char* hval = session->getEntityID();
-            if (hval) {
-                request.setHeader("Shib-Identity-Provider", hval);
-            }
-            time_t ts = session->getAuthnInstant();
-            if (ts > 0) {
-                // TODO: Need to see what the output format of this really is.
-                ostringstream os;
-                os << date::format("%FT%TZ", chrono::system_clock::from_time_t(ts));
-                request.setHeader("Shib-Authentication-Instant", os.str().c_str());
-            }
-            hval = session->getAuthnContextClassRef();
-            if (hval) {
-                request.setHeader("Shib-Authentication-Method", hval);
-                request.setHeader("Shib-AuthnContext-Class", hval);
-            }
-
-            request.setHeader( "Shib-Session-Expires", boost::lexical_cast<string>(session->getExpiration()).c_str());
-            unsigned int timeout = settings.first->getUnsignedInt("timeout", 3600);
-            if (timeout > 0) {
-                request.setHeader( "Shib-Session-Inactivity", boost::lexical_cast<string>(session->getLastAccess() + timeout).c_str());
-            }
+        request.setHeader( "Shib-Session-Expires", boost::lexical_cast<string>(session->getExpiration()).c_str());
+        unsigned int timeout = settings.first->getUnsignedInt("timeout", 3600);
+        if (timeout > 0) {
+            request.setHeader( "Shib-Session-Inactivity", boost::lexical_cast<string>(session->getLastAccess() + timeout).c_str());
         }
 
         // Check for export of algorithmically-derived portion of cookie names.
diff --git a/shibsp/AgentConfig.h b/shibsp/AgentConfig.h
index 367261ef..d80ff911 100644
--- a/shibsp/AgentConfig.h
+++ b/shibsp/AgentConfig.h
@@ -72,8 +72,8 @@ namespace shibsp {
         /**
          * Initializes agent/library.
          *
-         * Each process using the library MUST call this function exactly once
-         * before using any library classes.
+         * <p>Each process using the library MUST call this function exactly once
+         * before using any library classes.</p>
          *
          * @param catalog_path  delimited set of schema catalog files to load
          * @param inst_prefix   installation prefix for software
@@ -81,6 +81,15 @@ namespace shibsp {
          */
         virtual bool init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false)=0;
 
+        /**
+         * Tells the agent it may start background threads or tasks.
+         * 
+         * <p>Should only be called once per child process but the implememntation will
+         * ensure that subsequent calls are ignored. Must be called only after init()
+         * is successful, failure to do so resulting in unspecified behavior.</p>
+         */
+        virtual bool start()=0;
+
         /**
          * Shuts down agent/library
          *
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index b868e719..1bb36701 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -70,6 +70,7 @@ reminclude_HEADERS = \
 	remoting/SecretSource.h
 
 sessioninclude_HEADERS = \
+	session/AbstractSessionCache.h \
 	session/SessionCache.h
 	
 utilinclude_HEADERS = \
diff --git a/shibsp/handler/impl/SessionHandler.cpp b/shibsp/handler/impl/SessionHandler.cpp
index dddede3f..57feedb2 100644
--- a/shibsp/handler/impl/SessionHandler.cpp
+++ b/shibsp/handler/impl/SessionHandler.cpp
@@ -156,38 +156,6 @@ pair<bool,long> SessionHandler::doJSON(SPRequest& request) const
     else
         s << 0;
 
-    if (session->getClientAddress()) {
-        s << ", \"client_address\": ";
-        json_safe(s, session->getClientAddress());
-    }
-
-    if (session->getProtocol()) {
-        s << ", \"protocol\": ";
-        json_safe(s, session->getProtocol());
-    }
-
-    bool stdvars = request.getRequestSettings().first->getBool("exportStdVars", true);
-    if (stdvars) {
-        if (session->getEntityID()) {
-            s << ", \"identity_provider\": ";
-            json_safe(s, session->getEntityID());
-        }
-
-        if (session->getAuthnInstant()) {
-            s << ", \"authn_instant\": ";
-            time_t ts = session->getAuthnInstant();
-            // TODO: Need to see what the output format of this really is.
-            ostringstream os;
-            os << date::format("%FT%TZ", chrono::system_clock::from_time_t(ts));
-            json_safe(s, os.str().c_str());
-        }
-
-        if (session->getAuthnContextClassRef()) {
-            s << ", \"authncontext_class\": ";
-            json_safe(s, session->getAuthnContextClassRef());
-        }
-    }
-
     /*
         attributes: [ { "name": "foo", "values" : count } ]
 
@@ -274,22 +242,6 @@ pair<bool,long> SessionHandler::doHTML(SPRequest& request) const
     else
         s << "Infinite" << endl;
 
-    s << "<strong>Client Address:</strong> " << (session->getClientAddress() ? session->getClientAddress() : "(none)") << endl;
-    s << "<strong>SSO Protocol:</strong> " << (session->getProtocol() ? session->getProtocol() : "(none)") << endl;
-
-    bool stdvars = request.getRequestSettings().first->getBool("exportStdVars", true);
-    if (stdvars) {
-        s << "<strong>Identity Provider:</strong> " << (session->getEntityID() ? session->getEntityID() : "(none)") << endl;
-        time_t ts = session->getAuthnInstant();
-        if (ts > 0) {
-            // TODO: Need to see what the output format of this really is.
-            ostringstream os;
-            os << date::format("%FT%TZ", chrono::system_clock::from_time_t(ts));
-            s << "<strong>Authentication Time:</strong> " << os.str() << endl;
-        }
-        s << "<strong>Authentication Context Class:</strong> " << (session->getAuthnContextClassRef() ? session->getAuthnContextClassRef() : "(none)") << endl;
-    }
-
     s << endl << "<u>Attributes</u>" << endl;
 
     string key;
diff --git a/shibsp/handler/impl/SessionInitiator.cpp b/shibsp/handler/impl/SessionInitiator.cpp
index 313d6ce0..d049b0ea 100644
--- a/shibsp/handler/impl/SessionInitiator.cpp
+++ b/shibsp/handler/impl/SessionInitiator.cpp
@@ -106,6 +106,7 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
             }
             else {
                 // target will come from query string, map, or handler or fall back to this request.
+                // TODO: shouldm't this fall back to homeURL?
                 target = getString("target", request, request.getRequestURL());
                 // handler is derived from the target resource.
                 handlerBaseURL = request.getHandlerURL(target.c_str());
diff --git a/shibsp/impl/AgentConfig.cpp b/shibsp/impl/AgentConfig.cpp
index 3ae0dcb6..6cfbeffb 100644
--- a/shibsp/impl/AgentConfig.cpp
+++ b/shibsp/impl/AgentConfig.cpp
@@ -68,6 +68,9 @@ namespace shibsp {
         }
 
         bool init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false);
+        bool start() {
+            call_once(m_startonce, &AgentInternalConfig::_start, this);
+        }
         void term();
 
         const PathResolver& getPathResolver() const {
@@ -83,6 +86,7 @@ namespace shibsp {
 
     private:
         bool _init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false);
+        bool _start();
         void _term();
 
         bool initLogging();
@@ -90,6 +94,7 @@ namespace shibsp {
         void loadExtensions(Category& log);
 
         unsigned int m_initCount;
+        once_flag m_startonce;
         mutex m_lock;
         ptree m_config;
         bool m_cli;
@@ -307,6 +312,11 @@ void AgentInternalConfig::term()
     _term();
 }
 
+bool AgentInternalConfig::_start()
+{
+    return true;
+}
+
 void AgentInternalConfig::_term()
 {
     Category& log=Category::getInstance(SHIBSP_LOGCAT ".AgentConfig");
diff --git a/shibsp/impl/XMLAccessControl.cpp b/shibsp/impl/XMLAccessControl.cpp
index 380b1cc2..bdf78628 100644
--- a/shibsp/impl/XMLAccessControl.cpp
+++ b/shibsp/impl/XMLAccessControl.cpp
@@ -22,6 +22,7 @@
 #include "exceptions.h"
 
 #include "AccessControl.h"
+#include "Agent.h"
 #include "SPRequest.h"
 #include "attribute/Attribute.h"
 #include "logging/Category.h"
@@ -166,6 +167,8 @@ AccessControl::aclresult_t Rule::authorized(const SPRequest& request, const Sess
     // We can make this more complex later using pluggable comparison functions,
     // but for now, just a straight port to the new Attribute API.
 
+    string actual_alias(m_alias);
+
     // Map alias in rule to the attribute.
     if (!session) {
         request.log(Priority::SHIB_WARN, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");
@@ -187,23 +190,18 @@ AccessControl::aclresult_t Rule::authorized(const SPRequest& request, const Sess
         return shib_acl_false;
     }
     else if (m_alias == "authnContextClassRef") {
-        const char* ref = session->getAuthnContextClassRef();
-        if (ref && m_vals.find(ref) != m_vals.end()) {
-            request.log(Priority::SHIB_DEBUG, string("AccessControl rule expecting authnContextClassRef (") + ref + "), authz granted");
-            return shib_acl_true;
-        }
-        return shib_acl_false;
+        actual_alias = request.getAgent().getString("legacy-classref-attribute", "Shib-AuthnContext-Class");
     }
 
     // Find the attribute(s) matching the require rule.
     pair<multimap<string,const Attribute*>::const_iterator, multimap<string,const Attribute*>::const_iterator> attrs =
-        session->getIndexedAttributes().equal_range(m_alias);
+        session->getIndexedAttributes().equal_range(actual_alias);
     if (attrs.first == attrs.second) {
-        request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + m_alias + "), not found in session");
+        request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + actual_alias + "), not found in session");
         return shib_acl_false;
     }
     else if (m_vals.empty()) {
-        request.log(Priority::SHIB_DEBUG, string("AccessControl rule requires presence of attribute (") + m_alias + "), authz granted");
+        request.log(Priority::SHIB_DEBUG, string("AccessControl rule requires presence of attribute (") + actual_alias + "), authz granted");
         return shib_acl_true;
     }
 
@@ -251,6 +249,8 @@ AccessControl::aclresult_t RuleRegex::authorized(const SPRequest& request, const
 
     static regexp::regex_constants::match_flag_type match_flags = regexp::regex_constants::match_any | regexp::regex_constants::match_not_null;
 
+    string actual_alias(m_alias);
+
     if (!session) {
         request.log(Priority::SHIB_WARN, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");
         return shib_acl_false;
@@ -272,17 +272,13 @@ AccessControl::aclresult_t RuleRegex::authorized(const SPRequest& request, const
         return shib_acl_false;
     }
     else if (m_alias == "authnContextClassRef") {
-        if (session->getAuthnContextClassRef() && regexp::regex_match(session->getAuthnContextClassRef(), m_re, match_flags)) {
-            request.log(Priority::SHIB_DEBUG, string("AccessControl rule expecting authnContextClassRef regex (") + m_exp + "), authz granted");
-            return shib_acl_true;
-        }
-        return shib_acl_false;
+        actual_alias = request.getAgent().getString("legacy-classref-attribute", "Shib-AuthnContext-Class");
     }
 
     // Find the attribute(s) matching the require rule.
-    auto attrs = session->getIndexedAttributes().equal_range(m_alias);
+    auto attrs = session->getIndexedAttributes().equal_range(actual_alias);
     if (attrs.first == attrs.second) {
-        request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + m_alias + "), not found in session");
+        request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + actual_alias + "), not found in session");
         return shib_acl_false;
     }
 
diff --git a/shibsp/session/AbstractSessionCache.h b/shibsp/session/AbstractSessionCache.h
new file mode 100644
index 00000000..3e2d0f5f
--- /dev/null
+++ b/shibsp/session/AbstractSessionCache.h
@@ -0,0 +1,35 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file session/AbstractSessionCache.h
+ *
+ * Base class for SessionCache implementations.
+ */
+
+#include <session/SessionCache.h>
+
+namespace shibsp {
+
+    class SHIBSP_API AbstractSessionCache : public virtual SessionCache {
+    protected:
+        /** Constructor. */
+        AbstractSessionCache();
+        virtual ~AbstractSessionCache();
+
+    public:
+        bool start();
+    };
+
+};
diff --git a/shibsp/session/SessionCache.h b/shibsp/session/SessionCache.h
index 916ec84f..769402f8 100644
--- a/shibsp/session/SessionCache.h
+++ b/shibsp/session/SessionCache.h
@@ -36,11 +36,6 @@ namespace shibsp {
 
     /**
      * Encapsulates access to a user's security session.
-     *
-     * <p>The SessionCache does not itself require locking to manage
-     * concurrency, but access to each Session is generally exclusive
-     * or at least controlled, and the caller must unlock a Session
-     * to dispose of it.</p>
      */
     class SHIBSP_API Session : public virtual BasicLockable
     {
@@ -57,12 +52,12 @@ namespace shibsp {
         virtual const char* getID() const=0;
 
         /**
-         * Returns the session's "bucket" ID, i.e., a value separating sessions into
+         * Returns the session's "application" ID, i.e., a value separating sessions into
          * specific buckets based on resources.
          *
-         * @return unique ID of session bucket
+         * @return unique ID of application/bucket
          */
-        virtual const char* getBucketID() const=0;
+        virtual const char* getApplicationID() const=0;
 
         /**
          * Returns the session expiration.
@@ -78,43 +73,6 @@ namespace shibsp {
          */
         virtual time_t getLastAccess() const=0;
 
-        /**
-         * Returns the address of the client associated with the session.
-         *
-         * @return  the client's network address
-         */
-        virtual const char* getClientAddress() const=0;
-
-        /**
-         * Returns the entityID of the IdP that initiated the session.
-         *
-         * @return the IdP's entityID
-         */
-        virtual const char* getEntityID() const=0;
-
-        /**
-         * Returns the protocol family used to initiate the session.
-         *
-         * @return the protocol constant that represents the general SSO protocol used
-         */
-        virtual const char* getProtocol() const=0;
-
-        /**
-         * Returns the timestamp of the authentication event at the IdP.
-         *
-         * @return  the authentication timestamp
-         */
-        virtual time_t getAuthnInstant() const=0;
-
-        /**
-         * Returns a URI containing an AuthnContextClassRef provided with the session.
-         *
-         * <p>SAML 1.x AuthenticationMethods will be returned as class references.</p>
-         *
-         * @return  a URI identifying the authentication context class
-         */
-        virtual const char* getAuthnContextClassRef() const=0;
-
         /**
          * Returns the resolved attributes associated with the session.
          *
@@ -147,6 +105,14 @@ namespace shibsp {
     public:
         virtual ~SessionCache();
 
+        /**
+         * Signals the implementation it may start any background tasks or do any
+         * additional once-per-process work.
+         * 
+         * <p>This method is guaranteed to be called only once per process.</p>
+         */
+        virtual bool start()=0;
+
 #ifndef SHIBSP_LITE
         /**
          * Inserts a new session into the cache and binds the session to the outgoing
diff --git a/shibsp/session/impl/AbstractSessionCache.cpp b/shibsp/session/impl/AbstractSessionCache.cpp
index 3a012c11..ee9ca01d 100644
--- a/shibsp/session/impl/AbstractSessionCache.cpp
+++ b/shibsp/session/impl/AbstractSessionCache.cpp
@@ -21,7 +21,7 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "AgentConfig.h"
-#include "session/SessionCache.h"
+#include "session/AbstractSessionCache.h"
 #include "logging/Category.h"
 
 #include <boost/property_tree/ptree.hpp>
@@ -56,3 +56,15 @@ SessionCache::SessionCache()
 SessionCache::~SessionCache()
 {
 }
+
+AbstractSessionCache::AbstractSessionCache()
+{
+}
+
+AbstractSessionCache::~AbstractSessionCache()
+{
+}
+
+bool AbstractSessionCache::start()
+{
+}
diff --git a/shibsp/session/impl/FilesystemSessionCache.cpp b/shibsp/session/impl/FilesystemSessionCache.cpp
index 8874f749..c2932274 100644
--- a/shibsp/session/impl/FilesystemSessionCache.cpp
+++ b/shibsp/session/impl/FilesystemSessionCache.cpp
@@ -20,7 +20,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "session/SessionCache.h"
+#include "session/AbstractSessionCache.h"
 #include "logging/Category.h"
 
 #include <boost/property_tree/ptree.hpp>
@@ -30,7 +30,7 @@ using namespace boost::property_tree;
 using namespace std;
 
 namespace {
-    class FilesystemSessionCache : public virtual SessionCache {
+    class FilesystemSessionCache : public virtual AbstractSessionCache {
     public:
         FilesystemSessionCache(const ptree& pt);
         ~FilesystemSessionCache();

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list