From 27b3dbb0b69b5db0e63e4828876b09f1dc146f47 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Thu, 17 Mar 2022 18:08:56 +0100
Subject: [PATCH] Add missing files

---
 Online/HTTP/include/HTTP/Cache.h            | 129 +++++++++++++++++
 Online/HTTP/include/HTTP/Cache.inl.h        | 126 +++++++++++++++++
 Online/HTTP/include/HTTP/HttpCacheCheck.h   |  60 ++++++++
 Online/HTTP/include/HTTP/HttpCacheHandler.h | 104 ++++++++++++++
 Online/HTTP/src/Cache.cpp                   |  38 +++++
 Online/HTTP/src/HttpCacheCheck.cpp          |  61 ++++++++
 Online/HTTP/src/HttpCacheHandler.cpp        | 148 ++++++++++++++++++++
 7 files changed, 666 insertions(+)
 create mode 100644 Online/HTTP/include/HTTP/Cache.h
 create mode 100644 Online/HTTP/include/HTTP/Cache.inl.h
 create mode 100644 Online/HTTP/include/HTTP/HttpCacheCheck.h
 create mode 100644 Online/HTTP/include/HTTP/HttpCacheHandler.h
 create mode 100644 Online/HTTP/src/Cache.cpp
 create mode 100644 Online/HTTP/src/HttpCacheCheck.cpp
 create mode 100644 Online/HTTP/src/HttpCacheHandler.cpp

diff --git a/Online/HTTP/include/HTTP/Cache.h b/Online/HTTP/include/HTTP/Cache.h
new file mode 100644
index 000000000..5a1ab8dc3
--- /dev/null
+++ b/Online/HTTP/include/HTTP/Cache.h
@@ -0,0 +1,129 @@
+//==========================================================================
+//  LHCb Online software suite
+//--------------------------------------------------------------------------
+//  Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+//  All rights reserved.
+//
+//  For the licensing terms see OnlineSys/LICENSE.
+//
+//--------------------------------------------------------------------------
+//
+//  Package    : RPC-GUI
+//
+//  Author     : Markus Frank
+//==========================================================================
+// Please note:
+// This implementation was directly deduced (with some changes) from 
+// one of the boost::asio examples. 
+// boost::asio: one of the best I/O libraries ever !
+//
+// Hence:
+//
+//==========================================================================
+#ifndef HTTP_HTTP_CACHE_H
+#define HTTP_HTTP_CACHE_H
+
+/// Framework include files
+#include <HTTP/HttpReply.h>
+
+/// C/C++ include files
+#include <ctime>
+#include <mutex>
+#include <string>
+#include <memory>
+#include <cstdint>
+#include <climits>
+#include <unordered_map>
+
+/// Namespace for the http server and client apps
+namespace http   {
+
+  /// A abstract data cache to speed up HTTP requests
+  /**
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \date    10.01.2021
+   */
+  template <typename DATA> class Cache   {
+  public:
+    /// Internal class representing a single cache entry
+    class entry_type   {
+    public:
+      std::time_t  timeout     { std::numeric_limits<time_t>::max() };
+      std::int64_t length      { 0  };
+      std::size_t  hash        { 0u };
+      std::string  path        { };
+      std::string  encoding    { };
+      DATA         data        { };
+
+    public:
+      /// Default constructor
+      entry_type() = default;
+      /// Move constructor
+      entry_type(entry_type&& copy) = default;
+      /// Inhibit copy constructor
+      entry_type(const entry_type& copy) = delete;
+      /// Default destructor
+      ~entry_type() = default;
+      /// Move assignment operator
+      entry_type& operator=(entry_type&& copy) = default;
+      /// Inhibit assignment operator
+      entry_type& operator=(const entry_type& copy) = delete;
+    };
+
+  public:
+    typedef size_t key_type;
+    typedef std::unordered_map<key_type, std::unique_ptr<entry_type> > cache_type;
+
+  public:
+    cache_type             cache;
+    std::mutex             lock;
+    std::hash<std::string> hash;
+
+  protected:
+    void _set(entry_type*        e,
+	      key_type           key,
+	      std::time_t        timeout,
+	      const std::string& path,
+	      const std::string& encoding,
+	      const DATA&        reply);
+
+  public:
+    /// Default constructor
+    Cache();
+    /// Inhibit move constructor
+    Cache(Cache&& copy) = delete;
+    /// Inhibit copy constructor
+    Cache(const Cache& copy) = delete;
+    /// Inhibit move assignment operator
+    Cache& operator=(Cache&& copy) = delete;
+    /// Inhibit assignment operator
+    Cache& operator=(const Cache& copy) = delete;
+    /// Default destructor
+    virtual ~Cache();
+    /// Access number of entries in the cache
+    std::size_t size()  const;
+    /// Find a cache entry by path. [Not thread safe, unlocked]
+    const entry_type* find(const std::string& key,
+			   const std::string& encoding)  const;
+    /// Find a cache entry by hash key [Not thread safe, unlocked]
+    const entry_type* find(key_type key,
+			   const std::string& encoding)  const;
+    /// Insert new entry into the cache [Not thread safe, unlocked]
+    bool insert(key_type key,
+		std::time_t timeout,
+		const std::string& path,
+		const std::string& encoding,
+		const http::HttpReply& reply);
+    /// Drop a cache entry by key  [Not thread safe, unlocked]
+    std::size_t drop(key_type key);
+
+    /// Clean "old" entries from cache [Thread safe, locked]
+    std::size_t drop_expired();
+    /// Drop cache entries by key  [Thread safe, locked]
+    std::size_t drop_key(key_type key);
+    /// Drop a cache entries by key  [Thread safe, locked]
+    std::size_t drop_keys(const std::vector<key_type>& key);
+  };
+}      // End namespace http
+#endif // HTTP_HTTP_CACHE_H
diff --git a/Online/HTTP/include/HTTP/Cache.inl.h b/Online/HTTP/include/HTTP/Cache.inl.h
new file mode 100644
index 000000000..d55742f08
--- /dev/null
+++ b/Online/HTTP/include/HTTP/Cache.inl.h
@@ -0,0 +1,126 @@
+//==========================================================================
+//  LHCb Online software suite
+//--------------------------------------------------------------------------
+//  Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+//  All rights reserved.
+//
+//  For the licensing terms see OnlineSys/LICENSE.
+//
+//--------------------------------------------------------------------------
+//
+//  Package    : RPC
+//
+//  Author     : Markus Frank
+//==========================================================================
+
+// Framework include files
+#include <HTTP/Cache.h>
+
+// C/C++ include files
+#include <cstring>
+
+/// Initializing constructor
+template <typename DATA> http::Cache<DATA>::Cache()   {
+}
+
+/// Default destructor
+template <typename DATA> http::Cache<DATA>::~Cache()    {
+}
+
+/// Access number of entries in the cache
+template <typename DATA> std::size_t http::Cache<DATA>::size()  const    {
+  return this->cache.size();
+}
+
+/// Find a cache entry by path
+template <typename DATA> const typename http::Cache<DATA>::entry_type*
+http::Cache<DATA>::find(const std::string& key_name, const std::string& encoding)  const  {
+  return this->find(this->hash(key_name), encoding);
+}
+
+/// Find a cache entry by hash key
+template <typename DATA> const typename http::Cache<DATA>::entry_type*
+http::Cache<DATA>::find(key_type key, const std::string& encoding)  const  {
+  auto range = this->cache.equal_range(key);
+  for( auto it = range.first; it != range.second; ++it )   {
+    if( encoding.find(it->second->encoding) != std::string::npos )   {
+      return it->second.get();
+    }
+  }
+  return nullptr;
+}
+
+/// Drop a cache entry by key
+template <typename DATA> std::size_t http::Cache<DATA>::drop(key_type key)    {
+  auto& c = this->cache;
+  std::size_t removed = 0;
+  for( auto it = c.find(key); it != c.end(); it = c.find(key) )   {
+    c.erase(it);
+    ++removed;
+  }
+  return removed;
+}
+
+/// Insert new entry into the cache
+template <typename DATA>
+bool http::Cache<DATA>::insert(key_type               key,
+			       std::time_t            tmo,
+			       const std::string&     path,
+			       const std::string&     encoding,
+			       const http::HttpReply& reply)
+{
+  auto range = cache.equal_range(key);
+  for( auto it = range.first; it != range.second; ++it )   {
+    if( encoding == it->second->encoding )   {
+      _set(it->second.get(), key, tmo, path, encoding, reply);
+      return false;
+    }
+  }
+  auto e = std::make_unique<entry_type>();
+  _set(e.get(), key, tmo, path, encoding, reply);
+  this->cache.emplace(key, std::move(e));
+  return true;
+}
+
+/// Clean "old" entries from cache [Thread safe, locked]
+template <typename DATA>
+std::size_t http::Cache<DATA>::drop_key(key_type key)    {
+  std::lock_guard<std::mutex> lock(this->lock);
+  return this->drop(key);
+}
+
+/// Drop a cache entries by key  [Thread safe, locked]
+template <typename DATA>
+std::size_t http::Cache<DATA>::drop_keys(const std::vector<key_type>& keys)    {
+  std::size_t cnt = 0;
+  Cache<DATA>::cache_type& c = this->cache;
+  std::lock_guard<std::mutex> lock(this->lock);
+  for( auto key : keys )   {
+    for( auto it = c.find(key); it != c.end(); it = c.find(key) ) {
+      ++cnt;
+      c.erase(it);
+    }
+  }
+  return cnt;
+}
+
+/// Clean "old" entries from cache [Thread safe, locked]
+template <typename DATA>
+size_t http::Cache<DATA>::drop_expired()    {
+  key_type    last = 0;
+  std::size_t cnt  = 0;
+  std::time_t now  = ::time(0);
+  Cache<DATA>::cache_type& c = this->cache;
+  std::lock_guard<std::mutex> lock(this->lock);
+  for( auto it = c.begin(); it != c.end(); ++it )   {
+    auto* e = it->second.get();
+    if ( now > e->timeout )   {
+      ++cnt;
+      c.erase(it);
+      it = (last != 0) ? c.find(last) : c.begin();
+    }
+    last = (it == c.end()) ? 0 : it->first;
+  }
+  return cnt;
+}
+
diff --git a/Online/HTTP/include/HTTP/HttpCacheCheck.h b/Online/HTTP/include/HTTP/HttpCacheCheck.h
new file mode 100644
index 000000000..487d004d4
--- /dev/null
+++ b/Online/HTTP/include/HTTP/HttpCacheCheck.h
@@ -0,0 +1,60 @@
+//==========================================================================
+//  LHCb Online software suite
+//--------------------------------------------------------------------------
+//  Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+//  All rights reserved.
+//
+//  For the licensing terms see OnlineSys/LICENSE.
+//
+//--------------------------------------------------------------------------
+//
+//  Package    : RPC-GUI
+//
+//  Author     : Markus Frank
+//==========================================================================
+#ifndef HTTP_HTTP_HTTPCACHECHECK_H
+#define HTTP_HTTP_HTTPCACHECHECK_H
+
+/// Framework include caches
+#include <HTTP/Asio.h>
+
+/// Namespace for the http server and client apps
+namespace http   {
+
+  class HttpCacheHandler;
+  
+  /// A cachecheck to cache http requests
+  /**
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \date    10.01.2021
+   */
+  class HttpCacheCheck   {
+  protected:    
+    boost::asio::deadline_timer timer;
+    http::HttpCacheHandler&     handler;
+    int                         timeout  { 100 };
+  public:
+    /// Initializing constructor. Start timer
+    HttpCacheCheck(http::HttpCacheHandler& hdlr, boost::asio::io_service& io, int tmo);
+    /// Initializing constructor. Does not start timer.
+    HttpCacheCheck(http::HttpCacheHandler& hdlr, boost::asio::io_service& io);
+    /// Inhibit move construction
+    HttpCacheCheck(HttpCacheCheck&& copy) = delete;
+    /// Inhibit copy construction
+    HttpCacheCheck(const HttpCacheCheck& copy) = delete;
+    /// Inhibit move assignment
+    HttpCacheCheck& operator=(HttpCacheCheck&& copy) = delete;
+    /// Inhibit copy assignment
+    HttpCacheCheck& operator=(const HttpCacheCheck& copy) = delete;
+    /// Default destructor
+    virtual ~HttpCacheCheck();
+    /// Rearm timer after single shot
+    void start();
+    /// Rearm timer after single shot with new timeout
+    void start(int tmo);
+    /// Default cleanup handler: drop expired items
+    virtual void check();
+  };
+}      // End namespace http
+#endif // HTTP_HTTP_HTTPCACHECHECK_H
diff --git a/Online/HTTP/include/HTTP/HttpCacheHandler.h b/Online/HTTP/include/HTTP/HttpCacheHandler.h
new file mode 100644
index 000000000..a6c922d40
--- /dev/null
+++ b/Online/HTTP/include/HTTP/HttpCacheHandler.h
@@ -0,0 +1,104 @@
+//==========================================================================
+//  LHCb Online software suite
+//--------------------------------------------------------------------------
+//  Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+//  All rights reserved.
+//
+//  For the licensing terms see OnlineSys/LICENSE.
+//
+//--------------------------------------------------------------------------
+//
+//  Package    : RPC-GUI
+//
+//  Author     : Markus Frank
+//==========================================================================
+#ifndef HTTP_HTTP_HTTPCACHEHANDLER_H
+#define HTTP_HTTP_HTTPCACHEHANDLER_H
+
+/// Framework include caches
+#include <HTTP/HttpReply.h>
+#include <HTTP/Cache.h>
+
+/// C/C++ include files
+#include <cstdint>
+
+/// Namespace for the http server and client apps
+namespace http   {
+
+  class HttpRequest;
+  
+  /// A cachehandler to cache http requests
+  /**
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \date    10.01.2021
+   */
+  class HttpCacheHandler   {
+  public:
+    /// Structure holding cache configuration properties
+    struct cache_params_t   {
+      /// String identifier of this cache
+      std::string name          { };
+      /// Minimal content size for keeping entries in the cache
+      size_t minContentLength   { 128 };
+      /// Minimal content size for keeping entries in the cache
+      size_t maxContentLength   { 100*MegaBYTE };
+      /// Timeout in seconds for cleanup strategies
+      int    timeout            { std::numeric_limits<int>::max() };
+      /// Flag to enable data cache
+      bool   enable             { false };
+      /// Debug flag
+      bool   debug              { false };
+    };
+
+    /// Structure steering the cache if enabled
+    cache_params_t       cache;
+    
+  protected:
+    typedef Cache<HttpReply>    cache_type;
+    std::unique_ptr<cache_type> reply_cache;
+
+    /// Check cache for the existence of a given entry
+    std::pair<bool, http::Reply> check_cache(const std::string& path,
+					     const std::string& encoding);
+
+    /// Check cache for the existence of a given entry
+    std::pair<bool, http::Reply> check_cache(const std::string& path,
+					     const HttpRequest& req);
+
+    /// Add a new entry to the data cache
+    http::Reply add_cache(const std::string& path,
+			  const std::string& encoding,
+			  http::HttpReply&&  reply);
+
+    /// Auto enable or disable cache functionality
+    bool use_cache(std::mutex& handler_lock);
+
+  public:
+    /// Default construction
+    HttpCacheHandler() = default;
+    /// Inhibit move construction
+    HttpCacheHandler(HttpCacheHandler&& copy) = delete;
+    /// Inhibit copy construction
+    HttpCacheHandler(const HttpCacheHandler& copy) = delete;
+    /// Inhibit move assignment
+    HttpCacheHandler& operator=(HttpCacheHandler&& copy) = delete;
+    /// Inhibit copy assignment
+    HttpCacheHandler& operator=(const HttpCacheHandler& copy) = delete;
+    /// Default destructor
+    virtual ~HttpCacheHandler();
+
+    /// Access number of entries in the cache
+    std::size_t size()  const;
+
+    /// Clean "old" entries from cache [Thread safe, locked]
+    std::size_t drop_expired();
+
+    /// Drop cache entries by key  [Thread safe, locked]
+    std::size_t drop_key(cache_type::key_type key);
+
+    /// Drop a cache entries by key  [Thread safe, locked]
+    std::size_t drop_keys(const std::vector<cache_type::key_type>& key);
+  };
+}      // End namespace http
+#endif // HTTP_HTTP_HTTPCACHEHANDLER_H
diff --git a/Online/HTTP/src/Cache.cpp b/Online/HTTP/src/Cache.cpp
new file mode 100644
index 000000000..286756577
--- /dev/null
+++ b/Online/HTTP/src/Cache.cpp
@@ -0,0 +1,38 @@
+//==========================================================================
+//  LHCb Online software suite
+//--------------------------------------------------------------------------
+//  Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+//  All rights reserved.
+//
+//  For the licensing terms see OnlineSys/LICENSE.
+//
+//--------------------------------------------------------------------------
+//
+//  Package    : RPC
+//
+//  Author     : Markus Frank
+//==========================================================================
+
+// Framework include files
+#include <HTTP/Cache.h>
+#include <HTTP/Cache.inl.h>
+
+// C/C++ include files
+#include <cstring>
+
+template <>
+void http::Cache<http::HttpReply>::_set(http::Cache<http::HttpReply>::entry_type* e,
+					http::Cache<http::HttpReply>::key_type    key,
+					std::time_t            tmo,
+					const std::string&     path,
+					const std::string&     encoding,
+					const http::HttpReply& reply)
+{
+  e->data     = std::move(reply.clone());
+  e->timeout  = ::time(0) + tmo;
+  e->encoding = encoding;
+  e->path     = path;
+  e->hash     = key;
+}
+
+template class http::Cache<http::HttpReply>;
diff --git a/Online/HTTP/src/HttpCacheCheck.cpp b/Online/HTTP/src/HttpCacheCheck.cpp
new file mode 100644
index 000000000..37c070525
--- /dev/null
+++ b/Online/HTTP/src/HttpCacheCheck.cpp
@@ -0,0 +1,61 @@
+//==========================================================================
+//  LHCb Online software suite
+//--------------------------------------------------------------------------
+//  Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+//  All rights reserved.
+//
+//  For the licensing terms see OnlineSys/LICENSE.
+//
+//--------------------------------------------------------------------------
+//
+//  Package    : HTTP
+//
+//  Author     : Markus Frank
+//==========================================================================
+
+// Framework include files
+#include <HTTP/HttpCacheCheck.h>
+#include <HTTP/HttpCacheHandler.h>
+
+// C/C++ include files
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/bind.hpp>
+
+/// Initializing constructor. Start timer
+http::HttpCacheCheck::HttpCacheCheck(HttpCacheHandler& hdlr, boost::asio::io_service& io, int tmo)
+  : timer(io), handler(hdlr), timeout(tmo)
+{
+  this->start();
+}
+
+/// Initializing constructor. Does not start timer.
+http::HttpCacheCheck::HttpCacheCheck(HttpCacheHandler& hdlr, boost::asio::io_service& io)
+  : timer(io), handler(hdlr), timeout(10)
+{
+}
+
+/// Default destructor
+http::HttpCacheCheck::~HttpCacheCheck()    {
+}
+
+/// Rearm timer after single shot
+void http::HttpCacheCheck::start()   {
+  timer.expires_from_now(boost::posix_time::seconds(this->timeout));
+  timer.async_wait(boost::bind(&HttpCacheCheck::check, this));
+}
+
+/// Rearm timer after single shot with new timeout
+void http::HttpCacheCheck::start(int tmo)   {
+  this->timeout = tmo;
+  this->start();
+}
+
+/// Default cleanup handler: drop expired items
+void http::HttpCacheCheck::check()   {
+  if ( this->handler.cache.debug )     {
+    std::cout << std::setw(14) << std::left << this->handler.cache.name+":" 
+	      << "Timer callback: Flush old cache entries...." << std::endl;
+  }
+  this->handler.drop_expired();
+  this->start();
+}
diff --git a/Online/HTTP/src/HttpCacheHandler.cpp b/Online/HTTP/src/HttpCacheHandler.cpp
new file mode 100644
index 000000000..e30ffcf30
--- /dev/null
+++ b/Online/HTTP/src/HttpCacheHandler.cpp
@@ -0,0 +1,148 @@
+//==========================================================================
+//  LHCb Online software suite
+//--------------------------------------------------------------------------
+//  Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+//  All rights reserved.
+//
+//  For the licensing terms see OnlineSys/LICENSE.
+//
+//--------------------------------------------------------------------------
+//
+//  Package    : HTTP
+//
+//  Author     : Markus Frank
+//==========================================================================
+
+// Framework include files
+#include <HTTP/HttpCacheHandler.h>
+#include <HTTP/HttpRequest.h>
+
+// C/C++ include files
+#include <cstring>
+#include <iostream>
+
+/// Default destructor
+http::HttpCacheHandler::~HttpCacheHandler()    {
+  this->reply_cache.reset();
+}
+
+/// Access number of entries in the cache
+std::size_t http::HttpCacheHandler::size()  const    {
+  if ( reply_cache.get() )
+    return this->reply_cache->size();
+  return 0;
+}
+
+/// Auto enable or disable cache functionality
+bool http::HttpCacheHandler::use_cache(std::mutex& handler_lock)   {
+  std::lock_guard<std::mutex> lock(handler_lock);
+  if ( this->cache.enable )   {
+    if ( !this->reply_cache.get() )
+      this->reply_cache = std::make_unique<Cache<HttpReply> >();
+    return true;
+  }
+  this->reply_cache.reset();
+  return false;
+}
+
+/// Check cache for the existence of a given entry
+std::pair<bool, http::Reply>
+http::HttpCacheHandler::check_cache(const std::string& path,
+				    const http::HttpRequest& req)
+{
+  std::size_t len = ::strlen("Accept-Encoding");
+  for(const auto& h : req.headers)  {
+    if ( ::strncasecmp(h.name.c_str(),"Accept-Encoding",len) == 0 )  {
+      return this->check_cache(path, h.value);
+    }
+  }
+  return std::make_pair(false,http::Reply());
+}
+
+/// Check cache for the existence of a given entry
+std::pair<bool, http::Reply>
+http::HttpCacheHandler::check_cache(const std::string& path,
+				    const std::string& encoding)
+{
+  if ( this->reply_cache )    {
+    auto key = this->reply_cache->hash(path);
+    std::lock_guard<std::mutex> lock(this->reply_cache->lock);
+    const auto* e = this->reply_cache->find(key, encoding);
+    if ( e )   {
+      const auto& rep = e->data;
+      if ( this->cache.debug )   {
+	std::cout << "Cache-fetch:  " << e->path
+		  << " "  << e->encoding
+		  << " [" << rep.content.size() << " bytes]"
+		  << std::endl;
+      }
+      return std::make_pair(true, rep.clone());
+    }
+  }
+  return std::make_pair(false,http::Reply());
+}
+
+/// Add or update an entry in the data cache
+http::Reply
+http::HttpCacheHandler::add_cache(const std::string& path,
+				  const std::string& encoding,
+				  http::HttpReply&&  reply)
+{
+  if ( this->reply_cache )    {
+    auto key = this->reply_cache->hash(path);
+    std::lock_guard<std::mutex> lock(this->reply_cache->lock);
+    if ( this->cache.debug )   {
+      std::cout << "Cache-insert: " << path
+		<< " "  << encoding
+		<< " [" << reply.content.size() << " bytes]"
+		<< std::endl;
+    }
+    this->reply_cache->insert(key, cache.timeout, path, encoding, reply);
+  }
+  return std::move(reply);
+}
+
+/// Clean "old" entries from cache [Thread safe, locked]
+std::size_t http::HttpCacheHandler::drop_expired()    {
+  if ( this->reply_cache )    {
+    std::size_t count = this->reply_cache->drop_expired();
+    if ( this->cache.debug )   {
+      std::cout << "Cache-clean:  " << this->cache.name << " Dropped " << count
+		<< " entries from cache."
+		<< " Now: " << this->reply_cache->size() << " entries."
+		<< std::endl;
+    }
+    return count;
+  }
+  return 0;
+}
+
+/// Drop cache entries by key  [Thread safe, locked]
+std::size_t http::HttpCacheHandler::drop_key(cache_type::key_type key)    {
+  if ( this->reply_cache )    {
+    std::size_t count = this->reply_cache->drop_key(key);
+    if ( this->cache.debug )   {
+      std::cout << "Cache-clean:  " << this->cache.name << "Dropped " << count
+		<< " entries from cache."
+		<< " Now: " << this->reply_cache->size() << " entries."
+		<< std::endl;
+    }
+    return count;
+  }
+  return 0;
+}
+
+/// Drop a cache entries by key  [Thread safe, locked]
+std::size_t http::HttpCacheHandler::drop_keys(const std::vector<cache_type::key_type>& keys)   {
+  if ( this->reply_cache )    {
+    std::size_t count = this->reply_cache->drop_keys(keys);
+    if ( this->cache.debug )   {
+      std::cout << "Cache-clean:  " << this->cache.name << "Dropped " << count
+		<< " entries from cache."
+		<< " Now: " << this->reply_cache->size() << " entries."
+		<< std::endl;
+    }
+    return count;
+  }
+  return 0;
+}
-- 
GitLab