fix include names

cppcheck isn't smart enough to recognize these are c++ headers, not c
headers.  Considering we're already inconsistent about our naming, it's
easier to just be consistent, and move the last few files to use .hpp
instead of .h.

Tested:
Code builds, no changes.

Signed-off-by: Ed Tanous <ed@tanous.net>
Change-Id: Ic348d695f8527fa4a0ded53f433e1558c319db40
diff --git a/http/http_server.hpp b/http/http_server.hpp
new file mode 100644
index 0000000..0be487f
--- /dev/null
+++ b/http/http_server.hpp
@@ -0,0 +1,240 @@
+#pragma once
+
+#include "http_connection.hpp"
+#include "logging.hpp"
+#include "timer_queue.hpp"
+
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/signal_set.hpp>
+#include <boost/asio/ssl/context.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/beast/ssl/ssl_stream.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <ssl_key_handler.hpp>
+
+#include <atomic>
+#include <chrono>
+#include <cstdint>
+#include <filesystem>
+#include <future>
+#include <memory>
+#include <utility>
+#include <vector>
+
+namespace crow
+{
+
+template <typename Handler, typename Adaptor = boost::asio::ip::tcp::socket>
+class Server
+{
+  public:
+    Server(Handler* handlerIn,
+           std::unique_ptr<boost::asio::ip::tcp::acceptor>&& acceptorIn,
+           std::shared_ptr<boost::asio::ssl::context> adaptor_ctx,
+           std::shared_ptr<boost::asio::io_context> io =
+               std::make_shared<boost::asio::io_context>()) :
+        ioService(std::move(io)),
+        acceptor(std::move(acceptorIn)),
+        signals(*ioService, SIGINT, SIGTERM, SIGHUP), timer(*ioService),
+        handler(handlerIn), adaptorCtx(std::move(adaptor_ctx))
+    {}
+
+    Server(Handler* handlerIn, const std::string& bindaddr, uint16_t port,
+           const std::shared_ptr<boost::asio::ssl::context>& adaptor_ctx,
+           const std::shared_ptr<boost::asio::io_context>& io =
+               std::make_shared<boost::asio::io_context>()) :
+        Server(handlerIn,
+               std::make_unique<boost::asio::ip::tcp::acceptor>(
+                   *io, boost::asio::ip::tcp::endpoint(
+                            boost::asio::ip::make_address(bindaddr), port)),
+               adaptor_ctx, io)
+    {}
+
+    Server(Handler* handlerIn, int existing_socket,
+           const std::shared_ptr<boost::asio::ssl::context>& adaptor_ctx,
+           const std::shared_ptr<boost::asio::io_context>& io =
+               std::make_shared<boost::asio::io_context>()) :
+        Server(handlerIn,
+               std::make_unique<boost::asio::ip::tcp::acceptor>(
+                   *io, boost::asio::ip::tcp::v6(), existing_socket),
+               adaptor_ctx, io)
+    {}
+
+    void updateDateStr()
+    {
+        time_t lastTimeT = time(nullptr);
+        tm myTm{};
+
+        gmtime_r(&lastTimeT, &myTm);
+
+        dateStr.resize(100);
+        size_t dateStrSz =
+            strftime(&dateStr[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &myTm);
+        dateStr.resize(dateStrSz);
+    }
+
+    void run()
+    {
+        loadCertificate();
+        updateDateStr();
+
+        getCachedDateStr = [this]() -> std::string {
+            static std::chrono::time_point<std::chrono::steady_clock>
+                lastDateUpdate = std::chrono::steady_clock::now();
+            if (std::chrono::steady_clock::now() - lastDateUpdate >=
+                std::chrono::seconds(10))
+            {
+                lastDateUpdate = std::chrono::steady_clock::now();
+                updateDateStr();
+            }
+            return this->dateStr;
+        };
+
+        timer.expires_after(std::chrono::seconds(1));
+
+        timerHandler = [this](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            timerQueue.process();
+            timer.expires_after(std::chrono::seconds(1));
+            timer.async_wait(timerHandler);
+        };
+        timer.async_wait(timerHandler);
+
+        BMCWEB_LOG_INFO << "bmcweb server is running, local endpoint "
+                        << acceptor->local_endpoint();
+        startAsyncWaitForSignal();
+        doAccept();
+    }
+
+    void loadCertificate()
+    {
+#ifdef BMCWEB_ENABLE_SSL
+        namespace fs = std::filesystem;
+        // Cleanup older certificate file existing in the system
+        fs::path oldCert = "/home/root/server.pem";
+        if (fs::exists(oldCert))
+        {
+            fs::remove("/home/root/server.pem");
+        }
+        fs::path certPath = "/etc/ssl/certs/https/";
+        // if path does not exist create the path so that
+        // self signed certificate can be created in the
+        // path
+        if (!fs::exists(certPath))
+        {
+            fs::create_directories(certPath);
+        }
+        fs::path certFile = certPath / "server.pem";
+        BMCWEB_LOG_INFO << "Building SSL Context file=" << certFile;
+        std::string sslPemFile(certFile);
+        ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile);
+        std::shared_ptr<boost::asio::ssl::context> sslContext =
+            ensuressl::getSslContext(sslPemFile);
+        adaptorCtx = sslContext;
+        handler->ssl(std::move(sslContext));
+#endif
+    }
+
+    void startAsyncWaitForSignal()
+    {
+        signals.async_wait([this](const boost::system::error_code& ec,
+                                  int signalNo) {
+            if (ec)
+            {
+                BMCWEB_LOG_INFO << "Error in signal handler" << ec.message();
+            }
+            else
+            {
+                if (signalNo == SIGHUP)
+                {
+                    BMCWEB_LOG_INFO << "Receivied reload signal";
+                    loadCertificate();
+                    boost::system::error_code ec2;
+                    acceptor->cancel(ec2);
+                    if (ec2)
+                    {
+                        BMCWEB_LOG_ERROR
+                            << "Error while canceling async operations:"
+                            << ec2.message();
+                    }
+                    this->startAsyncWaitForSignal();
+                }
+                else
+                {
+                    stop();
+                }
+            }
+        });
+    }
+
+    void stop()
+    {
+        ioService->stop();
+    }
+
+    void doAccept()
+    {
+        std::optional<Adaptor> adaptorTemp;
+        if constexpr (std::is_same<Adaptor,
+                                   boost::beast::ssl_stream<
+                                       boost::asio::ip::tcp::socket>>::value)
+        {
+            adaptorTemp = Adaptor(*ioService, *adaptorCtx);
+            auto p = std::make_shared<Connection<Adaptor, Handler>>(
+                handler, getCachedDateStr, timerQueue,
+                std::move(adaptorTemp.value()));
+
+            acceptor->async_accept(p->socket().next_layer(),
+                                   [this, p](boost::system::error_code ec) {
+                                       if (!ec)
+                                       {
+                                           boost::asio::post(
+                                               *this->ioService,
+                                               [p] { p->start(); });
+                                       }
+                                       doAccept();
+                                   });
+        }
+        else
+        {
+            adaptorTemp = Adaptor(*ioService);
+            auto p = std::make_shared<Connection<Adaptor, Handler>>(
+                handler, getCachedDateStr, timerQueue,
+                std::move(adaptorTemp.value()));
+
+            acceptor->async_accept(
+                p->socket(), [this, p](boost::system::error_code ec) {
+                    if (!ec)
+                    {
+                        boost::asio::post(*this->ioService,
+                                          [p] { p->start(); });
+                    }
+                    doAccept();
+                });
+        }
+    }
+
+  private:
+    std::shared_ptr<boost::asio::io_context> ioService;
+    detail::TimerQueue timerQueue;
+    std::function<std::string()> getCachedDateStr;
+    std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor;
+    boost::asio::signal_set signals;
+    boost::asio::steady_timer timer;
+
+    std::string dateStr;
+
+    Handler* handler;
+
+    std::function<void(const boost::system::error_code& ec)> timerHandler;
+
+#ifdef BMCWEB_ENABLE_SSL
+    bool useSsl{false};
+#endif
+    std::shared_ptr<boost::asio::ssl::context> adaptorCtx;
+}; // namespace crow
+} // namespace crow