diff --git a/mongoose.c b/mongoose.c index 5458b365..4efc7308 100644 --- a/mongoose.c +++ b/mongoose.c @@ -7529,7 +7529,7 @@ static void read_conn(struct mg_connection *c) { if (!ioalloc(c, &c->rtls)) return; n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], c->rtls.size - c->rtls.len); - if (n == MG_IO_ERR && c->rtls.len == 0) { + if (n == MG_IO_ERR && mg_tls_pending(c) == 0) { // Close only if we have fully drained both raw (rtls) and TLS buffers c->is_closing = 1; } else { @@ -7760,15 +7760,15 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { n = 0; for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) { c->is_readable = c->is_writable = 0; + if (c->is_closing) ms = 1; if (skip_iotest(c)) { // Socket not valid, ignore - } else if (c->rtls.len > 0 || mg_tls_pending(c) > 0) { - ms = 1; // Don't wait if TLS is ready } else { + // Don't wait if TLS is ready + if (c->rtls.len > 0 || mg_tls_pending(c) > 0) ms = 1; fds[n].fd = FD(c); if (can_read(c)) fds[n].events |= POLLIN; if (can_write(c)) fds[n].events |= POLLOUT; - if (c->is_closing) ms = 1; n++; } } @@ -7784,8 +7784,6 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) { if (skip_iotest(c)) { // Socket not valid, ignore - } else if (c->rtls.len > 0 || mg_tls_pending(c) > 0) { - c->is_readable = 1; } else { if (fds[n].revents & POLLERR) { mg_error(c, "socket error"); @@ -7817,7 +7815,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { if (can_write(c)) FD_SET(FD(c), &wset); if (c->rtls.len > 0 || mg_tls_pending(c) > 0) tvp = &tv_zero; if (FD(c) > maxfd) maxfd = FD(c); - if (c->is_closing) ms = 1; + if (c->is_closing) tvp = &tv_zero; } if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, tvp)) < 0) { diff --git a/src/sock.c b/src/sock.c index fd9ea15c..3b503d75 100644 --- a/src/sock.c +++ b/src/sock.c @@ -282,7 +282,7 @@ static void read_conn(struct mg_connection *c) { if (!ioalloc(c, &c->rtls)) return; n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], c->rtls.size - c->rtls.len); - if (n == MG_IO_ERR && c->rtls.len == 0) { + if (n == MG_IO_ERR && mg_tls_pending(c) == 0) { // Close only if we have fully drained both raw (rtls) and TLS buffers c->is_closing = 1; } else { @@ -513,15 +513,15 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { n = 0; for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) { c->is_readable = c->is_writable = 0; + if (c->is_closing) ms = 1; if (skip_iotest(c)) { // Socket not valid, ignore - } else if (c->rtls.len > 0 || mg_tls_pending(c) > 0) { - ms = 1; // Don't wait if TLS is ready } else { + // Don't wait if TLS is ready + if (c->rtls.len > 0 || mg_tls_pending(c) > 0) ms = 1; fds[n].fd = FD(c); if (can_read(c)) fds[n].events |= POLLIN; if (can_write(c)) fds[n].events |= POLLOUT; - if (c->is_closing) ms = 1; n++; } } @@ -537,8 +537,6 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) { if (skip_iotest(c)) { // Socket not valid, ignore - } else if (c->rtls.len > 0 || mg_tls_pending(c) > 0) { - c->is_readable = 1; } else { if (fds[n].revents & POLLERR) { mg_error(c, "socket error"); @@ -570,7 +568,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { if (can_write(c)) FD_SET(FD(c), &wset); if (c->rtls.len > 0 || mg_tls_pending(c) > 0) tvp = &tv_zero; if (FD(c) > maxfd) maxfd = FD(c); - if (c->is_closing) ms = 1; + if (c->is_closing) tvp = &tv_zero; } if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, tvp)) < 0) { diff --git a/tutorials/http/http-restful-server/Makefile b/tutorials/http/http-restful-server/Makefile index bbdb7b6d..92c7fe18 100644 --- a/tutorials/http/http-restful-server/Makefile +++ b/tutorials/http/http-restful-server/Makefile @@ -5,7 +5,7 @@ SOURCES = main.c mongoose.c # Source code files CFLAGS = -W -Wall -Wextra -g -I. # Build options # Mongoose build options. See https://mongoose.ws/documentation/#build-options -CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1 +CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1 -DMG_TLS=MG_TLS_BUILTIN ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe PROG ?= example.exe # Use .exe suffix for the binary @@ -13,20 +13,13 @@ ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: CFLAGS += -lws2_32 # Link against Winsock library DELETE = cmd /C del /Q /F /S # Command prompt command to delete files OUT ?= -o $(PROG) # Build output - MAKE += WINDOWS=1 CC=$(CC) endif -all: $(PROG) # Default target. Build and run program +all: $(PROG) $(RUN) ./$(PROG) $(ARGS) -$(PROG): $(SOURCES) # Build program from sources +$(PROG): $(SOURCES) Makefile $(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT) -clean: # Cleanup. Delete built program and all build artifacts - $(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls - -# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options - -mbedtls: # Pull and build mbedTLS library - git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@ - $(MAKE) -C mbedtls/library +clean: + $(DELETE) $(PROG) *.o *.obj *.exe *.dSYM diff --git a/tutorials/http/http-restful-server/main.c b/tutorials/http/http-restful-server/main.c index 36470bd1..5b68b329 100644 --- a/tutorials/http/http-restful-server/main.c +++ b/tutorials/http/http-restful-server/main.c @@ -18,41 +18,36 @@ static const char *s_http_addr = "http://0.0.0.0:8000"; // HTTP port static const char *s_https_addr = "https://0.0.0.0:8443"; // HTTPS port static const char *s_root_dir = "."; -// Self signed certificates -// https://mongoose.ws/documentation/tutorials/tls/#self-signed-certificates +// Self signed certificates, see +// https://github.com/cesanta/mongoose/blob/master/test/certs/generate.sh #ifdef TLS_TWOWAY static const char *s_tls_ca = "-----BEGIN CERTIFICATE-----\n" - "MIIBqjCCAU+gAwIBAgIUESoOPGqMhf9uarzblVFwzrQweMcwCgYIKoZIzj0EAwIw\n" - "RDELMAkGA1UEBhMCSUUxDzANBgNVBAcMBkR1YmxpbjEQMA4GA1UECgwHQ2VzYW50\n" - "YTESMBAGA1UEAwwJVGVzdCBSb290MCAXDTIwMDUwOTIxNTE0NFoYDzIwNTAwNTA5\n" - "MjE1MTQ0WjBEMQswCQYDVQQGEwJJRTEPMA0GA1UEBwwGRHVibGluMRAwDgYDVQQK\n" - "DAdDZXNhbnRhMRIwEAYDVQQDDAlUZXN0IFJvb3QwWTATBgcqhkjOPQIBBggqhkjO\n" - "PQMBBwNCAAQsq9ECZiSW1xI+CVBP8VDuUehVA166sR2YsnJ5J6gbMQ1dUCH/QvLa\n" - "dBdeU7JlQcH8hN5KEbmM9BnZxMor6ussox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud\n" - "DwQEAwIBrjAKBggqhkjOPQQDAgNJADBGAiEAnHFsAIwGQQyRL81B04dH6d86Iq0l\n" - "fL8OKzndegxOaB0CIQCPwSIwEGFdURDqCC0CY2dnMrUGY5ZXu3hHCojZGS7zvg==\n" + "MIIBFTCBvAIJAMNTFtpfcq8NMAoGCCqGSM49BAMCMBMxETAPBgNVBAMMCE1vbmdv\n" + "b3NlMB4XDTI0MDUwNzE0MzczNloXDTM0MDUwNTE0MzczNlowEzERMA8GA1UEAwwI\n" + "TW9uZ29vc2UwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASuP+86T/rOWnGpEVhl\n" + "fxYZ+pjMbCmDZ+vdnP0rjoxudwRMRQCv5slRlDK7Lxue761sdvqxWr0Ma6TFGTNg\n" + "epsRMAoGCCqGSM49BAMCA0gAMEUCIQCwb2CxuAKm51s81S6BIoy1IcandXSohnqs\n" + "us64BAA7QgIgGGtUrpkgFSS0oPBlCUG6YPHFVw42vTfpTC0ySwAS0M4=\n" "-----END CERTIFICATE-----\n"; #endif static const char *s_tls_cert = "-----BEGIN CERTIFICATE-----\n" - "MIIBhzCCASygAwIBAgIUbnMoVd8TtWH1T09dANkK2LU6IUswCgYIKoZIzj0EAwIw\n" - "RDELMAkGA1UEBhMCSUUxDzANBgNVBAcMBkR1YmxpbjEQMA4GA1UECgwHQ2VzYW50\n" - "YTESMBAGA1UEAwwJVGVzdCBSb290MB4XDTIwMDUwOTIxNTE0OVoXDTMwMDUwOTIx\n" - "NTE0OVowETEPMA0GA1UEAwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" - "QgAEkuBGnInDN6l06zVVQ1VcrOvH5FDu9MC6FwJc2e201P8hEpq0Q/SJS2nkbSuW\n" - "H/wBTTBaeXN2uhlBzMUWK790KKMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gw\n" - "EwYDVR0lBAwwCgYIKwYBBQUHAwEwCgYIKoZIzj0EAwIDSQAwRgIhAPo6xx7LjCdZ\n" - "QY133XvLjAgVFrlucOZHONFVQuDXZsjwAiEAzHBNligA08c5U3SySYcnkhurGg50\n" - "BllCI0eYQ9ggp/o=\n" + "MIIBMTCB2aADAgECAgkAluqkgeuV/zUwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwI\n" + "TW9uZ29vc2UwHhcNMjQwNTA3MTQzNzM2WhcNMzQwNTA1MTQzNzM2WjARMQ8wDQYD\n" + "VQQDDAZzZXJ2ZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASo3oEiG+BuTt5y\n" + "ZRyfwNr0C+SP+4M0RG2pYkb2v+ivbpfi72NHkmXiF/kbHXtgmSrn/PeTqiA8M+mg\n" + "BhYjDX+zoxgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwCgYIKoZIzj0EAwIDRwAw\n" + "RAIgTXW9MITQSwzqbNTxUUdt9DcB+8pPUTbWZpiXcA26GMYCIBiYw+DSFMLHmkHF\n" + "+5U3NXW3gVCLN9ntD5DAx8LTG8sB\n" "-----END CERTIFICATE-----\n"; static const char *s_tls_key = - "-----BEGIN PRIVATE KEY-----\n" - "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQglNni0t9Dg9icgG8w\n" - "kbfxWSS+TuNgbtNybIQXcm3NHpmhRANCAASS4EacicM3qXTrNVVDVVys68fkUO70\n" - "wLoXAlzZ7bTU/yESmrRD9IlLaeRtK5Yf/AFNMFp5c3a6GUHMxRYrv3Qo\n" - "-----END PRIVATE KEY-----\n"; + "-----BEGIN EC PRIVATE KEY-----\n" + "MHcCAQEEIAVdo8UAScxG7jiuNY2UZESNX/KPH8qJ0u0gOMMsAzYWoAoGCCqGSM49\n" + "AwEHoUQDQgAEqN6BIhvgbk7ecmUcn8Da9Avkj/uDNERtqWJG9r/or26X4u9jR5Jl\n" + "4hf5Gx17YJkq5/z3k6ogPDPpoAYWIw1/sw==\n" + "-----END EC PRIVATE KEY-----\n"; // We use the same event handler function for HTTP and HTTPS connections // fn_data is NULL for plain HTTP, and non-NULL for HTTPS