Protect against timer exhaustion

Currently there is no check to see if all timers
are used. This adds a check so that under many
connections we don't get a double free.

Tested: Spun up many connections and double free
went away

Change-Id: I7c6914f566064c57ad28d3bfe79a53e44f598a35
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/http/http_connection.h b/http/http_connection.h
index 9f6c7b6..b786175 100644
--- a/http/http_connection.h
+++ b/http/http_connection.h
@@ -864,6 +864,12 @@
 
             close();
         });
+
+        if (!timerCancelKey)
+        {
+            close();
+            return;
+        }
         BMCWEB_LOG_DEBUG << this << " timer added: " << &timerQueue << ' '
                          << *timerCancelKey;
     }
diff --git a/http/timer_queue.h b/http/timer_queue.h
index d7a427e..b61c188 100644
--- a/http/timer_queue.h
+++ b/http/timer_queue.h
@@ -13,14 +13,14 @@
 {
 
 constexpr const size_t timerQueueTimeoutSeconds = 5;
-
+constexpr const size_t maxSize = 100;
 // fast timer queue for fixed tick value.
 class TimerQueue
 {
   public:
     TimerQueue()
     {
-        dq.set_capacity(100);
+        dq.set_capacity(maxSize);
     }
 
     void cancel(size_t k)
@@ -32,8 +32,13 @@
         }
     }
 
-    size_t add(std::function<void()> f)
+    std::optional<size_t> add(std::function<void()> f)
     {
+        if (dq.size() == maxSize)
+        {
+            return std::nullopt;
+        }
+
         dq.push_back(
             std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
         size_t ret = step + dq.size() - 1;