myserver-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myserver-commit] [SCM] GNU MyServer branch, master, updated. v0.9.2-389


From: Giuseppe Scrivano
Subject: [myserver-commit] [SCM] GNU MyServer branch, master, updated. v0.9.2-389-gf9eafc6
Date: Mon, 30 Aug 2010 11:53:18 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU MyServer".

The branch, master has been updated
       via  f9eafc6c5ea79ad6804f16de5b0fcd37cefc6d1d (commit)
      from  99eb202fbb6442f0d8a3cebc1de824b76ec1d8c6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------


commit f9eafc6c5ea79ad6804f16de5b0fcd37cefc6d1d
Author: Giuseppe Scrivano <address@hidden>
Date:   Mon Aug 30 13:47:13 2010 +0200

    SecurityCache: track number of references to any node.

diff --git a/myserver/include/conf/security/security_cache.h 
b/myserver/include/conf/security/security_cache.h
index 5fe1039..c3bd750 100644
--- a/myserver/include/conf/security/security_cache.h
+++ b/myserver/include/conf/security/security_cache.h
@@ -28,32 +28,48 @@
 # include <include/conf/security/auth_method.h>
 # include <include/conf/security/validator_factory.h>
 # include <include/conf/security/validator.h>
-# include <include/conf/security/xml_validator.h>
 
+# include <list>
 # include <string>
 
 using namespace std;
 
 class SecurityCache
 {
-
 public:
+  struct CacheNode
+  {
+    SecurityCache *cache;
+    CacheNode (SecurityCache *cache) {this->cache = cache; ref = 0;}
+    void addRef (){ref++;}
+    int getRef () {return ref;}
+    void decRef ();
+    XmlParser parser;
+    int ref;
+    string key;
+  };
+
   SecurityCache ();
   ~SecurityCache ();
   void free ();
   void setMaxNodes (int);
   int getMaxNodes ();
 
-  XmlParser* getParser (const string &dir, const string &sys, bool useXpath = 
true,
-                        const char* secName = ".security.xml", u_long maxSize 
= 0);
+  SecurityCache::CacheNode* getParser (const string &dir, const string &sys,
+                                       bool useXpath = true,
+                                       const char* secName = ".security.xml",
+                                       u_long maxSize = 0);
   int getSecurityFile (const string &file, const string &sys,
                        string &out, const char* secName = ".security.xml");
   int getErrorFileName (const char *root, int error,
                         const char* sysdirectory, string& out){return 0;}
-private:
+  void mayDrop (CacheNode *cn);
 
+private:
+  Mutex mutex;
   /* Store a list of opened files using a hash dictionary.  */
-  HashMap<string, XmlParser*> dictionary;
+  HashMap<string, CacheNode *> dictionary;
+  list<CacheNode *> toRemove;
   int limit;
 };
 
diff --git a/myserver/include/conf/security/xml_validator.h 
b/myserver/include/conf/security/xml_validator.h
index 0ccae7e..2fa9c80 100644
--- a/myserver/include/conf/security/xml_validator.h
+++ b/myserver/include/conf/security/xml_validator.h
@@ -22,6 +22,8 @@
 # include "myserver.h"
 # include <include/base/hash_map/hash_map.h>
 
+# include <include/conf/security/security_cache.h>
+
 # include <include/conf/security/security_domain.h>
 # include <include/conf/security/security_manager.h>
 # include <include/server/server.h>
@@ -31,8 +33,6 @@
 
 # include <include/base/crypt/crypt_algo_manager.h>
 
-class SecurityCache;
-
 class XmlValidator : public Validator, public AuthMethod
 {
 public:
@@ -41,14 +41,14 @@ public:
 
   using Validator::getPermissionMask;
 
-  virtual int getPermissionMask (SecurityToken* st);
+  virtual int getPermissionMask (SecurityToken *st);
 
   virtual int
-  getPermissionMaskImpl (SecurityToken* st,
+  getPermissionMaskImpl (SecurityToken *st,
                          HashMap<string, SecurityDomain*> *hashedDomains,
                          AuthMethod* authMethod);
 private:
-  XmlParser* getParser (SecurityToken* st);
+  SecurityCache::CacheNode *getParser (SecurityToken *st);
   bool doCondition (xmlNodePtr node,
                     HashMap<string, SecurityDomain*> *hashedDomains);
 
diff --git a/myserver/src/conf/security/security_cache.cpp 
b/myserver/src/conf/security/security_cache.cpp
index ea8f15f..d66525c 100644
--- a/myserver/src/conf/security/security_cache.cpp
+++ b/myserver/src/conf/security/security_cache.cpp
@@ -52,12 +52,19 @@ SecurityCache::~SecurityCache ()
 */
 void SecurityCache::free ()
 {
-  HashMap<string, XmlParser*>::Iterator it = dictionary.begin ();
+  HashMap<string, CacheNode *>::Iterator it = dictionary.begin ();
 
   for (;it != dictionary.end (); it++)
     delete (*it);
 
+
   dictionary.clear ();
+
+  list<CacheNode *>::iterator it2;
+  for (it2 = toRemove.begin (); it2 != toRemove.end (); it2++)
+    delete *it2;
+
+  toRemove.clear ();
 }
 
 /*!
@@ -70,13 +77,6 @@ void SecurityCache::setMaxNodes (int newLimit)
   if (newLimit <= 0)
     newLimit = 1;
 
-  /*! Remove all the additional nodes from the dictionary. */
-  while (newLimit < dictionary.size ())
-    {
-      XmlParser* toremove = dictionary.remove (dictionary.begin ());
-      if (toremove)
-        delete toremove;
-    }
   limit = newLimit;
 }
 
@@ -167,26 +167,36 @@ int SecurityCache::getMaxNodes ()
   \param secFileName The security file name.
   \param maxSize The maximum file size allowed for the security file.
 */
-XmlParser* SecurityCache::getParser (const string &dir,
-                                     const string &sys,
-                                     bool useXpath,
-                                     const char* secFileName,
-                                     u_long maxSize)
+SecurityCache::CacheNode *SecurityCache::getParser (const string &dir,
+                                                    const string &sys,
+                                                    bool useXpath,
+                                                    const char* secFileName,
+                                                    u_long maxSize)
 {
   XmlParser* parser;
   string file;
+  CacheNode* node;
 
   if (getSecurityFile (dir, sys, file, secFileName))
     return NULL;
 
-  parser = dictionary.get (file);
+  mutex.lock ();
+  try
+    {
+      node = dictionary.get (file);
+      if (node)
+        node->addRef ();
+    }
+  catch (...)
+    {}
+  mutex.unlock ();
 
   /* If the parser is already present and satisfy XPath then use it.  */
-  if (parser && (!useXpath || parser->isXpathEnabled ()))
+  if (node && (!useXpath || node->parser.isXpathEnabled ()))
     {
       time_t fileModTime;
       fileModTime = FilesUtility::getLastModTime (file.c_str ());
-
+      parser = &(node->parser);
       if ((fileModTime != static_cast<time_t>(-1))  &&
           (parser->getLastModTime () != fileModTime))
         {
@@ -207,36 +217,58 @@ XmlParser* SecurityCache::getParser (const string &dir,
             }
 
           if (parser->open (file.c_str (), useXpath) == -1)
-            {
-              dictionary.remove (file.c_str ());
-              return NULL;
-            }
-
+            return NULL;
         }
     }
   else
     {
       /* Create the parser and add it to the dictionary.  */
-      XmlParser* old;
-      parser = new XmlParser ();
+      CacheNode* old;
+      node = new CacheNode (this);
+      node->key = file;
+      if (node->parser.open (file.c_str (), useXpath) == -1)
+        {
+          delete node;
+          return NULL;
+        }
 
-      if (parser == NULL)
-        return NULL;
+      old = dictionary.put (file, node);
+      if (old)
+        toRemove.push_back (old);
+    }
 
-      if (dictionary.size () >= limit)
+  return node;
+}
+
+void SecurityCache::mayDrop (CacheNode *cn)
+{
+  mutex.lock ();
+  try
+    {
+      list<CacheNode *>::iterator it;
+      for (it = toRemove.begin (); it != toRemove.end (); it++)
         {
-          XmlParser* toremove = dictionary.remove (dictionary.begin ());
-          if (toremove)
-            delete toremove;
+          CacheNode *cn = *it;
+          if (cn->getRef () == 0)
+            {
+              delete cn;
+              toRemove.erase (it);
+            }
         }
 
-      if (parser->open (file.c_str (), useXpath) == -1)
-        return NULL;
-
-      old = dictionary.put (file, parser);
-      if (old)
-        delete old;
+      if (dictionary.size () >= limit)
+        {
+          dictionary.remove (cn->key);
+          toRemove.push_back (cn);
+        }
     }
+  catch (...)
+    {}
+  mutex.unlock ();
+}
 
-  return parser;
+void SecurityCache::CacheNode::decRef ()
+{
+  if (--ref == 0)
+    cache->mayDrop (this);
 }
diff --git a/myserver/src/conf/security/xml_validator.cpp 
b/myserver/src/conf/security/xml_validator.cpp
index 1a17f97..f6cd99c 100644
--- a/myserver/src/conf/security/xml_validator.cpp
+++ b/myserver/src/conf/security/xml_validator.cpp
@@ -17,7 +17,6 @@
 
 #include "myserver.h"
 
-
 #include <include/conf/security/xml_validator.h>
 #include <include/conf/security/auth_domain.h>
 #include <include/conf/security/security_cache.h>
@@ -62,10 +61,9 @@ SecurityCache* XmlValidator::getCache (SecurityToken *st)
 /*!
   Get the XML parser to use.
 */
-XmlParser* XmlValidator::getParser (SecurityToken* st)
+SecurityCache::CacheNode* XmlValidator::getParser (SecurityToken* st)
 {
   const char *secName;
-
   SecurityCache *cache = getCache (st);
 
   if (!cache)
@@ -85,11 +83,13 @@ XmlParser* XmlValidator::getParser (SecurityToken* st)
 int XmlValidator::getPermissionMask (SecurityToken* st)
 {
   xmlNodePtr root;
-  XmlParser* xmlFile = getParser (st);
+  SecurityCache::CacheNode *node = getParser (st);
 
-  if (!xmlFile)
+  if (! node)
     return 0;
 
+  XmlParser* xmlFile = &node->parser;
+
   for (xmlNodePtr cur = xmlFile->getDoc ()->children; cur; cur = cur->next)
     if (cur->type == XML_ELEMENT_NODE)
       {
@@ -139,9 +139,11 @@ int XmlValidator::getPermissionMask (SecurityToken* st)
           st->setMask (0);
         }
 
+      node->decRef ();
       return st->getMask ();
     }
 
+  node->decRef ();
   return 0;
 }
 
@@ -212,9 +214,14 @@ XmlValidator::getPermissionMaskImpl (SecurityToken* st,
                                HashMap<string, SecurityDomain*> *hashedDomains,
                                      AuthMethod* authMethod)
 {
-  XmlParser* xmlFile = getParser (st);
+  SecurityCache::CacheNode *node = getParser (st);
+
+  if (! node)
+    return 0;
+
+  XmlParser* xmlFile = &node->parser;
 
-  if (!xmlFile || !xmlFile->getDoc ())
+  if (! xmlFile->getDoc ())
     return 0;
 
   for (xmlNodePtr cur = xmlFile->getDoc ()->children; cur; cur = cur->next)
@@ -226,19 +233,27 @@ XmlValidator::getPermissionMaskImpl (SecurityToken* st,
 
         /* By default return ALLOW.  */
         if (cmd == -1)
-          return 1;
+          {
+            node->decRef ();
+            return 1;
+          }
 
         if (cmd == 0)
-          return 0;
+          {
+            node->decRef ();
+            return 0;
+          }
 
         if (cmd == 1)
           {
+            node->decRef ();
             st->setMask (MYSERVER_PERMISSION_ALL);
             return 1;
           }
 
       }
 
+  node->decRef ();
   return 0;
 }
 
diff --git a/myserver/src/http_handler/proxy/proxy.cpp 
b/myserver/src/http_handler/proxy/proxy.cpp
index c4f9cdd..da8fa56 100644
--- a/myserver/src/http_handler/proxy/proxy.cpp
+++ b/myserver/src/http_handler/proxy/proxy.cpp
@@ -30,6 +30,7 @@
 #include <include/protocol/http/http_data_handler.h>
 #include <include/protocol/http/http_headers.h>
 #include <include/filter/filters_chain.h>
+#include <include/server/server.h>
 
 #include <sstream>
 
diff --git a/myserver/src/protocol/http/webdav/webdav.cpp 
b/myserver/src/protocol/http/webdav/webdav.cpp
index 0c425ba..5a06373 100644
--- a/myserver/src/protocol/http/webdav/webdav.cpp
+++ b/myserver/src/protocol/http/webdav/webdav.cpp
@@ -20,6 +20,7 @@
 #include <include/protocol/http/http.h>
 #include <include/protocol/http/http_errors.h>
 #include <include/http_handler/http_file/http_file.h>
+#include <include/server/server.h>
 
 #include <fts_.h>
 
diff --git a/myserver/src/server/server.cpp b/myserver/src/server/server.cpp
index e02b3b4..d5d4e50 100644
--- a/myserver/src/server/server.cpp
+++ b/myserver/src/server/server.cpp
@@ -37,6 +37,7 @@
 #include <include/base/crypt/sha1.h>
 
 #include <include/conf/main/xml_main_configuration.h>
+#include <include/conf/security/xml_validator.h>
 
 #include <cstdarg>
 
diff --git a/myserver/tests/test_security_cache.cpp 
b/myserver/tests/test_security_cache.cpp
index 768ef9d..144c4a9 100644
--- a/myserver/tests/test_security_cache.cpp
+++ b/myserver/tests/test_security_cache.cpp
@@ -81,7 +81,8 @@ public:
   {
     string dir ("foo/bar/not/exist/in/reality");
     string file ("baz");
-    CPPUNIT_ASSERT_EQUAL (secCache->getParser (dir, dir, false), 
(XmlParser*)NULL);
+    CPPUNIT_ASSERT_EQUAL (secCache->getParser (dir, dir, false),
+                          (SecurityCache::CacheNode *) NULL);
   }
 
 

-----------------------------------------------------------------------

Summary of changes:
 myserver/include/conf/security/security_cache.h |   28 +++++--
 myserver/include/conf/security/xml_validator.h  |   10 +-
 myserver/src/conf/security/security_cache.cpp   |  104 +++++++++++++++--------
 myserver/src/conf/security/xml_validator.cpp    |   33 +++++--
 myserver/src/http_handler/proxy/proxy.cpp       |    1 +
 myserver/src/protocol/http/webdav/webdav.cpp    |    1 +
 myserver/src/server/server.cpp                  |    1 +
 myserver/tests/test_security_cache.cpp          |    3 +-
 8 files changed, 124 insertions(+), 57 deletions(-)


hooks/post-receive
-- 
GNU MyServer



reply via email to

[Prev in Thread] Current Thread [Next in Thread]