Browse Source

http server support both http and https

hewei.it 4 years ago
parent
commit
7b2bdb200d
8 changed files with 73 additions and 24 deletions
  1. 2 3
      BUILD.md
  2. 10 0
      base/hssl.c
  3. 14 0
      base/hssl.h
  4. 2 2
      etc/httpd.conf
  5. 8 6
      examples/httpd/httpd.cpp
  6. 10 0
      http/Http1Parser.h
  7. 19 7
      http/server/HttpServer.cpp
  8. 8 6
      http/server/HttpServer.h

+ 2 - 3
BUILD.md

@@ -105,10 +105,9 @@ https is the best example.
 sudo apt install openssl libssl-dev # ubuntu
 make clean
 make WITH_OPENSSL=yes
-# editor etc/httpd.conf => ssl = on
 bin/httpd -s restart -d
-bin/curl -v https://localhost:8080
-curl -v https://localhost:8080 --insecure
+bin/curl -v https://localhost:8443
+curl -v https://localhost:8443 --insecure
 ```
 
 ### compile WITH_CURL

+ 10 - 0
base/hssl.c

@@ -4,6 +4,16 @@
 
 static hssl_ctx_t s_ssl_ctx = NULL;
 
+const char* hssl_backend() {
+#ifdef WITH_OPENSSL
+    return "openssl";
+#elif defined(WITH_MBEDTLS)
+    return "mbedtls";
+#else
+    return "null";
+#endif
+}
+
 hssl_ctx_t hssl_ctx_instance() {
     if (s_ssl_ctx == NULL) {
         s_ssl_ctx = hssl_ctx_init(NULL);

+ 14 - 0
base/hssl.h

@@ -22,6 +22,20 @@ typedef struct {
 
 BEGIN_EXTERN_C
 
+/*
+const char* hssl_backend() {
+#ifdef WITH_OPENSSL
+    return "openssl";
+#elif defined(WITH_MBEDTLS)
+    return "mbedtls";
+#else
+    return "null";
+#endif
+}
+*/
+HV_EXPORT const char* hssl_backend();
+#define HV_WITH_SSL (strcmp(hssl_backend(), "null") != 0)
+
 HV_EXPORT hssl_ctx_t hssl_ctx_init(hssl_ctx_init_param_t* param);
 HV_EXPORT void hssl_ctx_cleanup(hssl_ctx_t ssl_ctx);
 HV_EXPORT hssl_ctx_t hssl_ctx_instance();

+ 2 - 2
etc/httpd.conf

@@ -10,7 +10,8 @@ log_filesize = 64M
 worker_processes = 4
 
 # http server
-port = 8080
+http_port = 8080
+https_port = 8443
 #base_url = /v1/api
 document_root = html
 home_page = index.html
@@ -18,7 +19,6 @@ home_page = index.html
 index_of = /downloads/
 
 # SSL/TLS
-ssl = off
 ssl_certificate = cert/server.crt
 ssl_privatekey = cert/server.key
 ssl_ca_certificate = cert/cacert.pem

+ 8 - 6
examples/httpd/httpd.cpp

@@ -100,7 +100,7 @@ int parse_confile(const char* confile) {
     int worker_threads = ini.Get<int>("worker_threads");
     g_http_server.worker_threads = LIMIT(0, worker_threads, 16);
 
-    // port
+    // http_port
     int port = 0;
     const char* szPort = get_arg("p");
     if (szPort) {
@@ -110,12 +110,16 @@ int parse_confile(const char* confile) {
         port = ini.Get<int>("port");
     }
     if (port == 0) {
+        port = ini.Get<int>("http_port");
+    }
+    g_http_server.port = port;
+    // https_port
+    g_http_server.https_port = ini.Get<int>("https_port");
+    if (g_http_server.port == 0 && g_http_server.https_port == 0) {
         printf("Please config listen port!\n");
         exit(-10);
     }
-    g_http_server.port = port;
 
-    // http server
     // base_url
     str = ini.GetValue("base_url");
     if (str.size() != 0) {
@@ -142,9 +146,7 @@ int parse_confile(const char* confile) {
         g_http_service.index_of = str;
     }
     // ssl
-    str = ini.GetValue("ssl");
-    if (getboolean(str.c_str())) {
-        g_http_server.ssl = 1;
+    if (g_http_server.https_port > 0 && HV_WITH_SSL) {
         std::string crt_file = ini.GetValue("ssl_certificate");
         std::string key_file = ini.GetValue("ssl_privatekey");
         std::string ca_file = ini.GetValue("ssl_ca_certificate");

+ 10 - 0
http/Http1Parser.h

@@ -35,6 +35,16 @@ public:
 
     void handle_header() {
         if (header_field.size() != 0 && header_value.size() != 0) {
+#if 0
+            if (stricmp(header_field.c_str(), "Set-CooKie") == 0) {
+                // combine multiple Set-Cookie
+                std::string cookie = parsed->GetHeader("Set-Cookie");
+                if (!cookie.empty()) {
+                    header_value += "; ";
+                    header_value += cookie;
+                }
+            }
+#endif
             parsed->headers[header_field] = header_value;
             header_field.clear();
             header_value.clear();

+ 19 - 7
http/server/HttpServer.cpp

@@ -312,13 +312,18 @@ static void on_accept(hio_t* io) {
 
 static void loop_thread(void* userdata) {
     http_server_t* server = (http_server_t*)userdata;
-    int listenfd = server->listenfd;
 
     EventLoopPtr loop(new EventLoop);
     hloop_t* hloop = loop->loop();
-    hio_t* listenio = haccept(hloop, listenfd, on_accept);
-    hevent_set_userdata(listenio, server);
-    if (server->ssl) {
+    // http
+    if (server->listenfd[0] >= 0) {
+        hio_t* listenio = haccept(hloop, server->listenfd[0], on_accept);
+        hevent_set_userdata(listenio, server);
+    }
+    // https
+    if (server->listenfd[1] >= 0) {
+        hio_t* listenio = haccept(hloop, server->listenfd[1], on_accept);
+        hevent_set_userdata(listenio, server);
         hio_enable_ssl(listenio);
     }
 
@@ -343,9 +348,16 @@ static void loop_thread(void* userdata) {
 }
 
 int http_server_run(http_server_t* server, int wait) {
-    // port
-    server->listenfd = Listen(server->port, server->host);
-    if (server->listenfd < 0) return server->listenfd;
+    // http_port
+    if (server->port > 0) {
+        server->listenfd[0] = Listen(server->port, server->host);
+        if (server->listenfd[0] < 0) return server->listenfd[0];
+    }
+    // https_port
+    if (server->https_port > 0 && hssl_ctx_instance() != NULL) {
+        server->listenfd[1] = Listen(server->https_port, server->host);
+        if (server->listenfd[1] < 0) return server->listenfd[1];
+    }
     // service
     if (server->service == NULL) {
         server->service = default_http_service();

+ 8 - 6
http/server/HttpServer.h

@@ -7,8 +7,8 @@
 struct WebSocketServerCallbacks;
 typedef struct http_server_s {
     char host[64];
-    int port;
-    int ssl;
+    int port; // http_port
+    int https_port;
     int http_version;
     int worker_processes;
     int worker_threads;
@@ -16,20 +16,22 @@ typedef struct http_server_s {
     WebSocketServerCallbacks* ws;
     void* userdata;
 //private:
-    int listenfd;
+    int listenfd[2]; // 0: http, 1: https
     void* privdata;
 
 #ifdef __cplusplus
     http_server_s() {
         strcpy(host, "0.0.0.0");
-        port = DEFAULT_HTTP_PORT;
-        ssl = 0;
+        // port = DEFAULT_HTTP_PORT;
+        // https_port = DEFAULT_HTTPS_PORT;
+        port = 8080;
+        https_port = 8443;
         http_version = 1;
         worker_processes = 0;
         worker_threads = 0;
         service = NULL;
         ws = NULL;
-        listenfd = -1;
+        listenfd[0] = listenfd[1] = -1;
         userdata = NULL;
         privdata = NULL;
     }