Browse Source

KBF-41 implement SSL support in WebService

Bence Balint 2 years ago
parent
commit
8150b4710c
3 changed files with 48 additions and 16 deletions
  1. 18 6
      include/kbf/web_service.h
  2. 18 4
      src/web_service.cpp
  3. 12 6
      test/test_web_service.cpp

+ 18 - 6
include/kbf/web_service.h

@@ -18,15 +18,13 @@ namespace kbf {
 
         /**
          * @brief Constructor.
-         *
-         * @param port web server port; default is 80
          */
-        explicit WebService(int port = 80);
+        WebService();
 
         /**
          * @brief Destructor.
          *
-         * Will call stop() if #running.
+         * Will call stop() if running.
          */
         ~WebService();
 
@@ -34,8 +32,23 @@ namespace kbf {
          * @brief Starts the service.
          *
          * @note All Controllers must be attached before calling start().
+         *
+         * @param port web server port; default is 80
+         */
+        void start(int port = 80);
+
+        /**
+         * @brief Starts the service in SSL (HTTPS) mode.
+         *
+         * @param cert_start start of the certificate
+         * @param cert_end end of the certificate
+         * @param key_start start of the private key
+         * @param key_end end of the private key
+         * @param port TCP port, default is 443
          */
-        void start();
+        void startSSL(const unsigned char *cert_start, const unsigned char *cert_end,
+                      const unsigned char *key_start, const unsigned char *key_end,
+                      int port = 443);
 
         /**
          * @brief Stops the service.
@@ -168,7 +181,6 @@ namespace kbf {
         http::Server server;
 
         bool running = false;
-        int  port;
 
         struct HandlerArg {
             WebService &webService;

+ 18 - 4
src/web_service.cpp

@@ -8,8 +8,8 @@ using namespace kbf;
 using http::Request;
 using http::Response;
 
-WebService::WebService(int port) : server(), port(port) {
-    ESP_LOGI(TAG, "%s(%d)", __func__, this->port);
+WebService::WebService() : server() {
+    ESP_LOGI(TAG, "%s()", __func__);
 }
 
 WebService::~WebService() {
@@ -19,8 +19,8 @@ WebService::~WebService() {
     }
 }
 
-void WebService::start() {
-    ESP_LOGI(TAG, "%s()", __func__);
+void WebService::start(int port) {
+    ESP_LOGI(TAG, "%s(%d)", __func__, port);
 
     if (running) {
         ABORT("WebService already running");
@@ -30,6 +30,20 @@ void WebService::start() {
     server.start(port);
 }
 
+void WebService::startSSL(const unsigned char *const cert_start, const unsigned char *const cert_end,
+                          const unsigned char *const key_start, const unsigned char *const key_end,
+                          int port) {
+
+    ESP_LOGI(TAG, "%s(%d)", __func__, port);
+
+    if (running) {
+        ABORT("WebService already running");
+    }
+
+    running = true;
+    server.startSSL(cert_start, cert_end, key_start, key_end, port);
+}
+
 void WebService::stop() {
     ESP_LOGI(TAG, "%s()", __func__);
 

+ 12 - 6
test/test_web_service.cpp

@@ -6,6 +6,11 @@
 
 using namespace kbf;
 
+extern const unsigned char cert_pem_start[] asm("_binary_cert_pem_start");
+extern const unsigned char cert_pem_end[]   asm("_binary_cert_pem_end");
+extern const unsigned char key_pem_start[] asm("_binary_key_pem_start");
+extern const unsigned char key_pem_end[]   asm("_binary_key_pem_end");
+
 class CounterController : public WebService::Controller {
 public:
     CounterController() : Controller("/counter") {}
@@ -42,26 +47,27 @@ TEST_CASE("WebService", "[kbf_web_service]") {
     auto webService = WebService();
     webService.controller<CounterController>();
     webService.controller<EchoController>();
-    webService.start();
+    webService.startSSL(cert_pem_start, cert_pem_end, key_pem_start, key_pem_end);
 
+    http::Client::addCert(cert_pem_start, cert_pem_end);
     auto client = http::Client();
 
-    auto response = client.get("http://localhost/counter");
+    auto response = client.get("https://localhost/counter");
     TEST_ASSERT_EQUAL(200, response->status);
     TEST_ASSERT_EQUAL_STRING("0", response->body.c_str());
 
-    response = client.get("http://localhost/counter");
+    response = client.get("https://localhost/counter");
     TEST_ASSERT_EQUAL_STRING("1", response->body.c_str());
 
-    response = client.post("http://localhost/counter", {{"str", "notallowed"}});
+    response = client.post("https://localhost/counter", {{"str", "notallowed"}});
     TEST_ASSERT_EQUAL(405, response->status);
     TEST_ASSERT_EQUAL_STRING("method not allowed", response->body.c_str());
 
-    response = client.get("http://localhost/echo?str=foo");
+    response = client.get("https://localhost/echo?str=foo");
     TEST_ASSERT_EQUAL(200, response->status);
     TEST_ASSERT_EQUAL_STRING("foo", response->body.c_str());
 
-    response = client.post("http://localhost/echo", {{"str", "bar"}});
+    response = client.post("https://localhost/echo", {{"str", "bar"}});
     TEST_ASSERT_EQUAL(200, response->status);
     TEST_ASSERT_EQUAL_STRING("bar", response->body.c_str());