From 1b324510ccc86d340f7a3e678a0f8419a2bb7fd7 Mon Sep 17 00:00:00 2001
From: Deomid Ryabkov <rojer@cesanta.com>
Date: Mon, 22 Aug 2016 23:04:44 +0100
Subject: [PATCH] Add simplest_web_server_ssl example

PUBLISHED_FROM=8945dc72ce22d48c582e7cdd01348494677ac5bb
---
 examples/restful_server/restful_server.c      | 22 +++---
 .../simplest_web_server/simplest_web_server.c |  9 ++-
 examples/simplest_web_server_ssl/Makefile     |  3 +
 examples/simplest_web_server_ssl/server.key   | 28 +++++++
 examples/simplest_web_server_ssl/server.pem   | 73 +++++++++++++++++++
 .../simplest_web_server_ssl.c                 | 61 ++++++++++++++++
 6 files changed, 182 insertions(+), 14 deletions(-)
 create mode 100644 examples/simplest_web_server_ssl/Makefile
 create mode 100644 examples/simplest_web_server_ssl/server.key
 create mode 100644 examples/simplest_web_server_ssl/server.pem
 create mode 100644 examples/simplest_web_server_ssl/simplest_web_server_ssl.c

diff --git a/examples/restful_server/restful_server.c b/examples/restful_server/restful_server.c
index 73a8c9048..b3d6fd638 100644
--- a/examples/restful_server/restful_server.c
+++ b/examples/restful_server/restful_server.c
@@ -49,8 +49,10 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
 int main(int argc, char *argv[]) {
   struct mg_mgr mgr;
   struct mg_connection *nc;
+  struct mg_bind_opts bind_opts;
   int i;
   char *cp;
+  const char *err_str;
 #ifdef MG_ENABLE_SSL
   const char *ssl_cert = NULL;
 #endif
@@ -99,21 +101,19 @@ int main(int argc, char *argv[]) {
   }
 
   /* Set HTTP server options */
-  nc = mg_bind(&mgr, s_http_port, ev_handler);
-  if (nc == NULL) {
-    fprintf(stderr, "Error starting server on port %s\n", s_http_port);
-    exit(1);
-  }
-
+  memset(&bind_opts, 0, sizeof(bind_opts));
+  bind_opts.error_string = &err_str;
 #ifdef MG_ENABLE_SSL
   if (ssl_cert != NULL) {
-    const char *err_str = mg_set_ssl(nc, ssl_cert, NULL);
-    if (err_str != NULL) {
-      fprintf(stderr, "Error loading SSL cert: %s\n", err_str);
-      exit(1);
-    }
+    bind_opts.ssl_cert = ssl_cert;
   }
 #endif
+  nc = mg_bind_opt(&mgr, s_http_port, ev_handler, bind_opts);
+  if (nc == NULL) {
+    fprintf(stderr, "Error starting server on port %s: %s\n", s_http_port,
+            *bind_opts.error_string);
+    exit(1);
+  }
 
   mg_set_protocol_http_websocket(nc);
   s_http_server_opts.enable_directory_listing = "yes";
diff --git a/examples/simplest_web_server/simplest_web_server.c b/examples/simplest_web_server/simplest_web_server.c
index 3a29d1b6d..94d593398 100644
--- a/examples/simplest_web_server/simplest_web_server.c
+++ b/examples/simplest_web_server/simplest_web_server.c
@@ -17,15 +17,18 @@ int main(void) {
   struct mg_connection *nc;
 
   mg_mgr_init(&mgr, NULL);
+  printf("Starting web server on port %s\n", s_http_port);
   nc = mg_bind(&mgr, s_http_port, ev_handler);
+  if (nc == NULL) {
+    printf("Failed to create listener\n");
+    return 1;
+  }
 
   // Set up HTTP server parameters
   mg_set_protocol_http_websocket(nc);
-  s_http_server_opts.document_root = ".";      // Serve current directory
-  s_http_server_opts.dav_document_root = ".";  // Allow access via WebDav
+  s_http_server_opts.document_root = ".";  // Serve current directory
   s_http_server_opts.enable_directory_listing = "yes";
 
-  printf("Starting web server on port %s\n", s_http_port);
   for (;;) {
     mg_mgr_poll(&mgr, 1000);
   }
diff --git a/examples/simplest_web_server_ssl/Makefile b/examples/simplest_web_server_ssl/Makefile
new file mode 100644
index 000000000..ce0d64458
--- /dev/null
+++ b/examples/simplest_web_server_ssl/Makefile
@@ -0,0 +1,3 @@
+PROG = simplest_web_server_ssl
+SSL_LIB ?= openssl
+include ../examples.mk
diff --git a/examples/simplest_web_server_ssl/server.key b/examples/simplest_web_server_ssl/server.key
new file mode 100644
index 000000000..1cf2c96ab
--- /dev/null
+++ b/examples/simplest_web_server_ssl/server.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDMGfTLWMxdjFNY
+KkOZfg4izFILsOSLT3c/UQ6YtwEnmKKNENPFezh8swPlo5kolpEUs9KDyVOTinbj
+i52Y8M3gRef3DSK3pcIaV70oVHVszBYoOYzMqxq2hKSTWhT/zqZF6CyZ7DKwbIAT
+kDEIMHr8Fkdze5uER4n/perXlM7N9f7+0ya2w+g5Iw4cR08E6M9onH5ToSByUT+G
+F12VxmaAA2LtrWVl7VeEFeN50ucYhVDCZMYDzKtzcWv9L9w9syXZ7LlS80XFs9Ac
+niGN6fagTQZVZnNwsZEz/1yVT6uIuPfOlskcl3lVFTrw55yDazzF0acczJADJduW
+HVVVW0g9AgMBAAECggEAcyalzOBRlOnpz9EwiHXtJcbe90ea+dogrjFeKdz+Isfj
+1fDLehx2Fyysoy/05khknCiEOeQpahFx2BlaFgKuNL1cDS91CeXUKCaeSxWzlmli
+itlFTeevT5Bwhc4KEPUXLFO8bi8rvgvJCsCMWVF44ab0MvxnFm+CNSD36R9Euj/v
+R58INAEIfIck3w7vWhP+W/RghrPBTLEYGc84872b1bL+LRf4H+wzD8P0UILAFoyN
+WS4ojv8MK3Sx8tbNBHN49niegNE9djsq0HTZ6FQ6ycffHfE/SnOu8oJIkgIojI3P
+gKekNqKO10pE2bW3lKAimXQevsD89jMQGguQOppVoQKBgQD/1l36HcG4wnklBT1z
+58rtYB80BnsizVSpyv0WKMzOMRhaC9jOp1nmELYT2J70MiE/u9hAiXSgJnjvtUrG
+G+B9XLFIhXtTNl8Iii4YwKIZ6EaXDHoTe+cyYfR3t9Cx1uE7ywQysQMElqNefH1x
+gxySGPJQ3pqCv06qHz/oQdQYRQKBgQDMOyuHdK+KvYd/WfacxglIPyAWn4Jy0Pu/
+ohXgk26Cfy8GeN4gx+up63bE5t4iNPLRZIT2b3El4HqTujSHX2syLBcszY2r/AGr
+HJmvKSt0L7HnvGgK4ZIezba1ndeilYB/KMPibrfG5Ll94OkVGXg4d2rRe92ntx5K
+IBuQPzubmQKBgQCkJKWnE/B22k9fsTz8YHuSUVmzx3S5n4PybIp07Th6EoXNQEya
+SkUjlxU7JoDVrFQo0ByvS4HIPubY5ThUYw5lYFNedEXr3babhAyPVQisFpszzo2E
+crqjWLXBGe6MK5HXCypmW6vUBdJLjRPvAHAUTG0r9aasvJF8FRCrs5ChAQKBgGYv
+iOUaniaGFEDFK55ffA94/j4zi1qVdBD7MYUPX3DN4CKV4VZ3kVOQq/lzJlvpMEFS
+0TBYrD1uZwZ5WYUOWh1dcC8LnkIaMl+CTOcWa1aT8qjnXQtst+bPuQaANn9z3DpD
+lFc8XJmYobL5EMZs2vktzvWHy2z6M56VGBWBffqpAoGAECL5PvYtq6fRXghdRGCj
+Kzy3/8WLFAv512MxhqxILeGA00nk8y9BVj1eY799id3XQJi+dPWOGyct4/QE+vav
+lPlgm6grDnZoKzWFfdLZaz/63mSHJPQ4erOTAzPc+ND7+fLcpAEffBjfQfd9YVje
+ermo4i8kEejajwsfwqyW5qM=
+-----END PRIVATE KEY-----
diff --git a/examples/simplest_web_server_ssl/server.pem b/examples/simplest_web_server_ssl/server.pem
new file mode 100644
index 000000000..e52f17316
--- /dev/null
+++ b/examples/simplest_web_server_ssl/server.pem
@@ -0,0 +1,73 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=localhost, O=Cesanta, OU=Testing
+        Validity
+            Not Before: Aug 22 12:34:04 2016 GMT
+            Not After : Aug 22 12:34:04 2026 GMT
+        Subject: CN=localhost, O=Cesanta, OU=Testing
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:cc:19:f4:cb:58:cc:5d:8c:53:58:2a:43:99:7e:
+                    0e:22:cc:52:0b:b0:e4:8b:4f:77:3f:51:0e:98:b7:
+                    01:27:98:a2:8d:10:d3:c5:7b:38:7c:b3:03:e5:a3:
+                    99:28:96:91:14:b3:d2:83:c9:53:93:8a:76:e3:8b:
+                    9d:98:f0:cd:e0:45:e7:f7:0d:22:b7:a5:c2:1a:57:
+                    bd:28:54:75:6c:cc:16:28:39:8c:cc:ab:1a:b6:84:
+                    a4:93:5a:14:ff:ce:a6:45:e8:2c:99:ec:32:b0:6c:
+                    80:13:90:31:08:30:7a:fc:16:47:73:7b:9b:84:47:
+                    89:ff:a5:ea:d7:94:ce:cd:f5:fe:fe:d3:26:b6:c3:
+                    e8:39:23:0e:1c:47:4f:04:e8:cf:68:9c:7e:53:a1:
+                    20:72:51:3f:86:17:5d:95:c6:66:80:03:62:ed:ad:
+                    65:65:ed:57:84:15:e3:79:d2:e7:18:85:50:c2:64:
+                    c6:03:cc:ab:73:71:6b:fd:2f:dc:3d:b3:25:d9:ec:
+                    b9:52:f3:45:c5:b3:d0:1c:9e:21:8d:e9:f6:a0:4d:
+                    06:55:66:73:70:b1:91:33:ff:5c:95:4f:ab:88:b8:
+                    f7:ce:96:c9:1c:97:79:55:15:3a:f0:e7:9c:83:6b:
+                    3c:c5:d1:a7:1c:cc:90:03:25:db:96:1d:55:55:5b:
+                    48:3d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Key Usage: 
+                Key Encipherment, Key Agreement
+            X509v3 Subject Alternative Name: 
+                IP Address:127.0.0.1
+    Signature Algorithm: sha256WithRSAEncryption
+         17:13:f8:8a:b5:ff:5a:73:de:5c:e7:a4:8c:b0:df:75:13:82:
+         92:69:61:17:c5:d5:83:35:cc:5b:8f:8f:97:e0:ee:1f:6e:1a:
+         96:59:a2:66:7b:50:c1:23:f0:72:89:c9:8f:b7:ab:34:62:fb:
+         5e:c2:8a:00:d6:29:99:f3:91:0f:18:e3:64:da:c2:f9:de:5a:
+         a0:08:a9:81:df:6c:05:61:5d:0c:84:0a:4c:f5:f7:0b:e0:81:
+         56:7b:46:a1:b5:d6:9b:72:70:83:75:74:06:97:6c:ce:77:a6:
+         96:98:f3:d4:99:41:53:74:be:65:3a:16:5f:bf:0e:10:0c:2b:
+         88:a8:b2:f0:15:5a:84:05:23:bf:c9:0a:c3:56:1c:5a:1f:8d:
+         4b:bc:14:67:05:6d:0e:2b:51:82:03:8c:18:41:93:5e:84:5f:
+         2c:05:11:c2:5c:0a:c3:3f:9d:b1:6e:3a:f2:d9:05:54:97:fc:
+         cf:cd:55:14:19:42:f7:29:67:5d:8e:ac:c2:7a:ff:b7:08:3b:
+         eb:68:39:37:d3:2b:e5:b8:08:05:88:e7:b6:30:94:7e:0a:87:
+         46:0c:90:d2:40:18:0c:41:5d:f2:85:a7:f4:be:2a:d4:c5:c5:
+         93:a8:89:c7:0e:87:8b:1c:04:e0:ae:ab:25:70:f2:c9:28:a9:
+         59:f6:32:78
+-----BEGIN CERTIFICATE-----
+MIIDCzCCAfOgAwIBAgIBATANBgkqhkiG9w0BAQsFADA4MRIwEAYDVQQDDAlsb2Nh
+bGhvc3QxEDAOBgNVBAoMB0Nlc2FudGExEDAOBgNVBAsMB1Rlc3RpbmcwHhcNMTYw
+ODIyMTIzNDA0WhcNMjYwODIyMTIzNDA0WjA4MRIwEAYDVQQDDAlsb2NhbGhvc3Qx
+EDAOBgNVBAoMB0Nlc2FudGExEDAOBgNVBAsMB1Rlc3RpbmcwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDMGfTLWMxdjFNYKkOZfg4izFILsOSLT3c/UQ6Y
+twEnmKKNENPFezh8swPlo5kolpEUs9KDyVOTinbji52Y8M3gRef3DSK3pcIaV70o
+VHVszBYoOYzMqxq2hKSTWhT/zqZF6CyZ7DKwbIATkDEIMHr8Fkdze5uER4n/perX
+lM7N9f7+0ya2w+g5Iw4cR08E6M9onH5ToSByUT+GF12VxmaAA2LtrWVl7VeEFeN5
+0ucYhVDCZMYDzKtzcWv9L9w9syXZ7LlS80XFs9AcniGN6fagTQZVZnNwsZEz/1yV
+T6uIuPfOlskcl3lVFTrw55yDazzF0acczJADJduWHVVVW0g9AgMBAAGjIDAeMAsG
+A1UdDwQEAwIDKDAPBgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQAX
+E/iKtf9ac95c56SMsN91E4KSaWEXxdWDNcxbj4+X4O4fbhqWWaJme1DBI/ByicmP
+t6s0YvtewooA1imZ85EPGONk2sL53lqgCKmB32wFYV0MhApM9fcL4IFWe0ahtdab
+cnCDdXQGl2zOd6aWmPPUmUFTdL5lOhZfvw4QDCuIqLLwFVqEBSO/yQrDVhxaH41L
+vBRnBW0OK1GCA4wYQZNehF8sBRHCXArDP52xbjry2QVUl/zPzVUUGUL3KWddjqzC
+ev+3CDvraDk30yvluAgFiOe2MJR+CodGDJDSQBgMQV3yhaf0virUxcWTqInHDoeL
+HATgrqslcPLJKKlZ9jJ4
+-----END CERTIFICATE-----
diff --git a/examples/simplest_web_server_ssl/simplest_web_server_ssl.c b/examples/simplest_web_server_ssl/simplest_web_server_ssl.c
new file mode 100644
index 000000000..c7846dcbe
--- /dev/null
+++ b/examples/simplest_web_server_ssl/simplest_web_server_ssl.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Cesanta Software Limited
+ * All rights reserved
+ */
+
+#ifdef MG_ENABLE_SSL
+/*
+ * This example starts an SSL web server on https://localhost:8443/
+ *
+ * Please note that the certificate used is a self-signed one and will not be
+ * recognised as valid. You should expect an SSL error and will need to
+ * explicitly allow the browser to proceed.
+ */
+
+#include "mongoose.h"
+
+static const char *s_http_port = "8443";
+static const char *s_ssl_cert = "server.pem";
+static const char *s_ssl_key = "server.key";
+static struct mg_serve_http_opts s_http_server_opts;
+
+static void ev_handler(struct mg_connection *nc, int ev, void *p) {
+  if (ev == MG_EV_HTTP_REQUEST) {
+    mg_serve_http(nc, (struct http_message *) p, s_http_server_opts);
+  }
+}
+
+int main(void) {
+  struct mg_mgr mgr;
+  struct mg_connection *nc;
+  struct mg_bind_opts bind_opts;
+
+  mg_mgr_init(&mgr, NULL);
+  memset(&bind_opts, 0, sizeof(bind_opts));
+  bind_opts.ssl_cert = s_ssl_cert;
+  bind_opts.ssl_key = s_ssl_key;
+  printf("Starting SSL server on port %s, cert from %s, key from %s\n",
+         s_http_port, bind_opts.ssl_cert, bind_opts.ssl_key);
+  nc = mg_bind_opt(&mgr, s_http_port, ev_handler, bind_opts);
+  if (nc == NULL) {
+    printf("Failed to create listener\n");
+    return 1;
+  }
+
+  // Set up HTTP server parameters
+  mg_set_protocol_http_websocket(nc);
+  s_http_server_opts.document_root = ".";  // Serve current directory
+  s_http_server_opts.enable_directory_listing = "yes";
+
+  for (;;) {
+    mg_mgr_poll(&mgr, 1000);
+  }
+  mg_mgr_free(&mgr);
+
+  return 0;
+}
+#else
+int main(void) {
+  return 0;
+}
+#endif /* MG_ENABLE_SSL */
-- 
GitLab