Browse Source

Merge branch 'civetweb:master' into fix-debug-flag

Hansi P 1 năm trước cách đây
mục cha
commit
ea392d7a7a
6 tập tin đã thay đổi với 55 bổ sung16 xóa
  1. 2 0
      .travis.yml
  2. 1 1
      CMakeLists.txt
  3. 3 0
      Makefile
  4. 3 0
      appveyor.yml
  5. 1 1
      docs/Building.md
  6. 45 14
      src/civetweb.c

+ 2 - 0
.travis.yml

@@ -82,6 +82,7 @@ before_script:
     -DCIVETWEB_ENABLE_SSL_DYNAMIC_LOADING=${ENABLE_SSL_DYNAMIC_LOADING}
     -DCIVETWEB_ENABLE_SSL_DYNAMIC_LOADING=${ENABLE_SSL_DYNAMIC_LOADING}
     -DCIVETWEB_SSL_OPENSSL_API_1_0=${OPENSSL_1_0}
     -DCIVETWEB_SSL_OPENSSL_API_1_0=${OPENSSL_1_0}
     -DCIVETWEB_SSL_OPENSSL_API_1_1=${OPENSSL_1_1}
     -DCIVETWEB_SSL_OPENSSL_API_1_1=${OPENSSL_1_1}
+    -DCIVETWEB_SSL_OPENSSL_API_3_0=${OPENSSL_3_0}
     -DCIVETWEB_ENABLE_WEBSOCKETS=${ENABLE_WEBSOCKETS}
     -DCIVETWEB_ENABLE_WEBSOCKETS=${ENABLE_WEBSOCKETS}
     -DCIVETWEB_ENABLE_CXX=${ENABLE_CXX}
     -DCIVETWEB_ENABLE_CXX=${ENABLE_CXX}
     -DCIVETWEB_ENABLE_SERVER_STATS=${ENABLE_SERVER_STATS}
     -DCIVETWEB_ENABLE_SERVER_STATS=${ENABLE_SERVER_STATS}
@@ -107,6 +108,7 @@ before_script:
     -DCIVETWEB_ENABLE_SSL_DYNAMIC_LOADING=${ENABLE_SSL_DYNAMIC_LOADING}
     -DCIVETWEB_ENABLE_SSL_DYNAMIC_LOADING=${ENABLE_SSL_DYNAMIC_LOADING}
     -DCIVETWEB_SSL_OPENSSL_API_1_0=${OPENSSL_1_0}
     -DCIVETWEB_SSL_OPENSSL_API_1_0=${OPENSSL_1_0}
     -DCIVETWEB_SSL_OPENSSL_API_1_1=${OPENSSL_1_1}
     -DCIVETWEB_SSL_OPENSSL_API_1_1=${OPENSSL_1_1}
+    -DCIVETWEB_SSL_OPENSSL_API_3_0=${OPENSSL_3_0}
     -DCIVETWEB_ENABLE_WEBSOCKETS=${ENABLE_WEBSOCKETS}
     -DCIVETWEB_ENABLE_WEBSOCKETS=${ENABLE_WEBSOCKETS}
     -DCIVETWEB_ENABLE_CXX=${ENABLE_CXX}
     -DCIVETWEB_ENABLE_CXX=${ENABLE_CXX}
     -DCIVETWEB_ENABLE_SERVER_STATS=${ENABLE_SERVER_STATS}
     -DCIVETWEB_ENABLE_SERVER_STATS=${ENABLE_SERVER_STATS}

+ 1 - 1
CMakeLists.txt

@@ -227,7 +227,7 @@ message(STATUS "Compile for OpenSSL 1.0 API - ${CIVETWEB_SSL_OPENSSL_API_1_0}")
 option(CIVETWEB_SSL_OPENSSL_API_1_1 "Use the OpenSSL 1.1 API" ON)
 option(CIVETWEB_SSL_OPENSSL_API_1_1 "Use the OpenSSL 1.1 API" ON)
 message(STATUS "Compile for OpenSSL 1.1 API - ${CIVETWEB_SSL_OPENSSL_API_1_1}")
 message(STATUS "Compile for OpenSSL 1.1 API - ${CIVETWEB_SSL_OPENSSL_API_1_1}")
 
 
-# OpenSSL 1.1 API
+# OpenSSL 3.0 API
 option(CIVETWEB_SSL_OPENSSL_API_3_0 "Use the OpenSSL 3.0 API" OFF)
 option(CIVETWEB_SSL_OPENSSL_API_3_0 "Use the OpenSSL 3.0 API" OFF)
 message(STATUS "Compile for OpenSSL 3.0 API - ${CIVETWEB_SSL_OPENSSL_API_3_0}")
 message(STATUS "Compile for OpenSSL 3.0 API - ${CIVETWEB_SSL_OPENSSL_API_3_0}")
 
 

+ 3 - 0
Makefile

@@ -100,6 +100,8 @@ else ifdef WITH_OPENSSL_API_1_0
   CFLAGS += -DOPENSSL_API_1_0
   CFLAGS += -DOPENSSL_API_1_0
 else ifdef WITH_OPENSSL_API_1_1
 else ifdef WITH_OPENSSL_API_1_1
   CFLAGS += -DOPENSSL_API_1_1
   CFLAGS += -DOPENSSL_API_1_1
+else ifdef WITH_OPENSSL_API_3_0
+  CFLAGS += -DOPENSSL_API_3_0
 else
 else
   #Use OpenSSL 1.1 API version as default
   #Use OpenSSL 1.1 API version as default
   CFLAGS += -DOPENSSL_API_1_1
   CFLAGS += -DOPENSSL_API_1_1
@@ -298,6 +300,7 @@ help:
 	@echo "   WITH_MBEDTLS=1        build with mbedTLS support."
 	@echo "   WITH_MBEDTLS=1        build with mbedTLS support."
 	@echo "   WITH_OPENSSL_API_1_0=1  build with OpenSSL 1.0.x support."
 	@echo "   WITH_OPENSSL_API_1_0=1  build with OpenSSL 1.0.x support."
 	@echo "   WITH_OPENSSL_API_1_1=1  build with OpenSSL 1.1.x support."
 	@echo "   WITH_OPENSSL_API_1_1=1  build with OpenSSL 1.1.x support."
+	@echo "   WITH_OPENSSL_API_3_0=1  build with OpenSSL 3.0.x support."
 	@echo "   NO_SSL=1              build without SSL support. Build will not need libcrypto/libssl."
 	@echo "   NO_SSL=1              build without SSL support. Build will not need libcrypto/libssl."
 	@echo "   NO_CGI=1              build without CGI support."
 	@echo "   NO_CGI=1              build without CGI support."
 	@echo "   NO_CACHING=1          disable caching. Send no-cache/no-store headers."
 	@echo "   NO_CACHING=1          disable caching. Send no-cache/no-store headers."

+ 3 - 0
appveyor.yml

@@ -440,6 +440,7 @@ before_build:
     -DCIVETWEB_CXX_STANDARD=%cxx_standard%
     -DCIVETWEB_CXX_STANDARD=%cxx_standard%
     -DCIVETWEB_SSL_OPENSSL_API_1_0=NO
     -DCIVETWEB_SSL_OPENSSL_API_1_0=NO
     -DCIVETWEB_SSL_OPENSSL_API_1_1=YES
     -DCIVETWEB_SSL_OPENSSL_API_1_1=YES
+    -DCIVETWEB_SSL_OPENSSL_API_3_0=NO
     "%source_path%"
     "%source_path%"
   - cmake
   - cmake
     -G "%generator%" %arch_arg%
     -G "%generator%" %arch_arg%
@@ -461,6 +462,8 @@ before_build:
     -DCIVETWEB_CXX_STANDARD=%cxx_standard%
     -DCIVETWEB_CXX_STANDARD=%cxx_standard%
     -DCIVETWEB_SSL_OPENSSL_API_1_0=NO
     -DCIVETWEB_SSL_OPENSSL_API_1_0=NO
     -DCIVETWEB_SSL_OPENSSL_API_1_1=YES
     -DCIVETWEB_SSL_OPENSSL_API_1_1=YES
+    -DCIVETWEB_SSL_OPENSSL_API_3_0=NO
+
     "%source_path%"
     "%source_path%"
   - powershell Push-AppveyorArtifact CMakeCache.txt
   - powershell Push-AppveyorArtifact CMakeCache.txt
   - cd "%source_path%"
   - cd "%source_path%"

+ 1 - 1
docs/Building.md

@@ -179,7 +179,7 @@ make build COPT="-DNDEBUG -DNO_CGI"
 | `SSL_ALREADY_INITIALIZED`    | do not initialize libcrypto                                         |
 | `SSL_ALREADY_INITIALIZED`    | do not initialize libcrypto                                         |
 | `OPENSSL_API_1_0`            | Use OpenSSL V1.0.x interface                                        |
 | `OPENSSL_API_1_0`            | Use OpenSSL V1.0.x interface                                        |
 | `OPENSSL_API_1_1`            | Use OpenSSL V1.1.x interface                                        |
 | `OPENSSL_API_1_1`            | Use OpenSSL V1.1.x interface                                        |
-| `OPENSSL_API_3_0`            | Use OpenSSL V3.x interface                                          |
+| `OPENSSL_API_3_0`            | Use OpenSSL V3.0.x interface                                          |
 | `USE_MBEDTLS`                | Use MbedTLS (cannot be combined with OPENSSL_API_*)                 |
 | `USE_MBEDTLS`                | Use MbedTLS (cannot be combined with OPENSSL_API_*)                 |
 |                              |                                                                     |
 |                              |                                                                     |
 | `BUILD_DATE`                 | define as a string to be used as build id instead of __DATE__       |
 | `BUILD_DATE`                 | define as a string to be used as build id instead of __DATE__       |

+ 45 - 14
src/civetweb.c

@@ -1929,6 +1929,7 @@ struct socket {
 	unsigned char is_ssl;    /* Is port SSL-ed */
 	unsigned char is_ssl;    /* Is port SSL-ed */
 	unsigned char ssl_redir; /* Is port supposed to redirect everything to SSL
 	unsigned char ssl_redir; /* Is port supposed to redirect everything to SSL
 	                          * port */
 	                          * port */
+	unsigned char is_optional; /* Shouldn't cause us to exit if we can't bind to it */
 	unsigned char in_use;    /* 0: invalid, 1: valid, 2: free */
 	unsigned char in_use;    /* 0: invalid, 1: valid, 2: free */
 };
 };
 
 
@@ -11336,11 +11337,11 @@ read_message(FILE *fp,
 			request_len = get_http_header_len(buf, *nread);
 			request_len = get_http_header_len(buf, *nread);
 		}
 		}
 
 
-		if ((request_len == 0) && (request_timeout >= 0)) {
+		if ((n <= 0) && (request_timeout >= 0)) {
 			if (mg_difftimespec(&last_action_time, &(conn->req_time))
 			if (mg_difftimespec(&last_action_time, &(conn->req_time))
 			    > request_timeout) {
 			    > request_timeout) {
 				/* Timeout */
 				/* Timeout */
-				return -1;
+				return -3;
 			}
 			}
 		}
 		}
 	}
 	}
@@ -15697,7 +15698,7 @@ parse_port_string(const struct vec *vec, struct socket *so, int *ip_version)
 	unsigned int a, b, c, d;
 	unsigned int a, b, c, d;
 	unsigned port;
 	unsigned port;
 	unsigned long portUL;
 	unsigned long portUL;
-	int ch, len;
+	int len;
 	const char *cb;
 	const char *cb;
 	char *endptr;
 	char *endptr;
 #if defined(USE_IPV6)
 #if defined(USE_IPV6)
@@ -15850,14 +15851,31 @@ parse_port_string(const struct vec *vec, struct socket *so, int *ip_version)
 	}
 	}
 
 
 	/* sscanf and the option splitting code ensure the following condition
 	/* sscanf and the option splitting code ensure the following condition
-	 * Make sure the port is valid and vector ends with the port, 's' or 'r' */
-	if ((len > 0) && is_valid_port(port)
-	    && (((size_t)len == vec->len) || (((size_t)len + 1) == vec->len))) {
-		/* Next character after the port number */
-		ch = ((size_t)len < vec->len) ? vec->ptr[len] : '\0';
-		so->is_ssl = (ch == 's');
-		so->ssl_redir = (ch == 'r');
-		if ((ch == '\0') || (ch == 's') || (ch == 'r')) {
+	 * Make sure the port is valid and vector ends with the port, 'o', 's', or 'r' */
+	if ((len > 0) && (is_valid_port(port))) {
+		int bad_suffix = 0;
+
+		/* Parse any suffix character(s) after the port number */
+		for (size_t i=len; i<vec->len; i++)
+		{
+			unsigned char * opt = NULL;
+			switch(vec->ptr[i])
+			{
+				case 'o': opt = &so->is_optional; break;
+				case 'r': opt = &so->ssl_redir;   break;
+				case 's': opt = &so->is_ssl;      break;
+				default:  /* empty */             break;
+			}
+
+			if ((opt)&&(*opt == 0)) *opt = 1;
+			else
+			{
+				bad_suffix = 1;
+				break;
+			}
+		}
+
+		if ((bad_suffix == 0)&&((so->is_ssl == 0)||(so->ssl_redir == 0))) {
 			return 1;
 			return 1;
 		}
 		}
 	}
 	}
@@ -15912,8 +15930,11 @@ is_ssl_port_used(const char *ports)
 		char prevIsNumber = 0;
 		char prevIsNumber = 0;
 
 
 		for (i = 0; i < portslen; i++) {
 		for (i = 0; i < portslen; i++) {
-			if (prevIsNumber && (ports[i] == 's' || ports[i] == 'r')) {
-				return 1;
+			if (prevIsNumber) {
+				int suffixCharIdx = (ports[i] == 'o') ? (i+1) : i;  /* allow "os" and "or" suffixes */
+				if (ports[suffixCharIdx] == 's' || ports[suffixCharIdx] == 'r') {
+					return 1;
+				}
 			}
 			}
 			if (ports[i] >= '0' && ports[i] <= '9') {
 			if (ports[i] >= '0' && ports[i] <= '9') {
 				prevIsNumber = 1;
 				prevIsNumber = 1;
@@ -16096,6 +16117,9 @@ set_ports_option(struct mg_context *phys_ctx)
 				                    strerror(errno));
 				                    strerror(errno));
 				closesocket(so.sock);
 				closesocket(so.sock);
 				so.sock = INVALID_SOCKET;
 				so.sock = INVALID_SOCKET;
+				if (so.is_optional) {
+					portsOk++; /* it's okay if we couldn't bind, this port is optional anyway */
+				}
 				continue;
 				continue;
 			}
 			}
 		}
 		}
@@ -16112,6 +16136,9 @@ set_ports_option(struct mg_context *phys_ctx)
 				                    strerror(errno));
 				                    strerror(errno));
 				closesocket(so.sock);
 				closesocket(so.sock);
 				so.sock = INVALID_SOCKET;
 				so.sock = INVALID_SOCKET;
+				if (so.is_optional) {
+					portsOk++; /* it's okay if we couldn't bind, this port is optional anyway */
+				}
 				continue;
 				continue;
 			}
 			}
 		}
 		}
@@ -16128,6 +16155,9 @@ set_ports_option(struct mg_context *phys_ctx)
 				                    strerror(errno));
 				                    strerror(errno));
 				closesocket(so.sock);
 				closesocket(so.sock);
 				so.sock = INVALID_SOCKET;
 				so.sock = INVALID_SOCKET;
+				if (so.is_optional) {
+					portsOk++; /* it's okay if we couldn't bind, this port is optional anyway */
+				}
 				continue;
 				continue;
 			}
 			}
 		}
 		}
@@ -18824,7 +18854,7 @@ get_message(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
 			            ebuf,
 			            ebuf,
 			            ebuf_len,
 			            ebuf_len,
 			            "%s",
 			            "%s",
-			            "Malformed message");
+			            conn->request_len == -3 ? "Request timeout" : "Malformed message");
 			*err = 400;
 			*err = 400;
 		} else {
 		} else {
 			/* Server did not recv anything -> just close the connection */
 			/* Server did not recv anything -> just close the connection */
@@ -20198,6 +20228,7 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 		set_close_on_exec(so.sock, NULL, ctx);
 		set_close_on_exec(so.sock, NULL, ctx);
 		so.is_ssl = listener->is_ssl;
 		so.is_ssl = listener->is_ssl;
 		so.ssl_redir = listener->ssl_redir;
 		so.ssl_redir = listener->ssl_redir;
+		so.is_optional = listener->is_optional;
 		if (getsockname(so.sock, &so.lsa.sa, &len) != 0) {
 		if (getsockname(so.sock, &so.lsa.sa, &len) != 0) {
 			mg_cry_ctx_internal(ctx,
 			mg_cry_ctx_internal(ctx,
 			                    "%s: getsockname() failed: %s",
 			                    "%s: getsockname() failed: %s",