소스 검색

Add configuration parameter to activate resource handling by index.cgi/lua scripts

Serving sub-resources from index.cgi is a new feature that may confusion.
See #519, in particular: see 4. from https://github.com/civetweb/civetweb/issues/519#issuecomment-329590388

Not this feature is inactive by default and must be explicitly activated
bel2125 7 년 전
부모
커밋
03c825176c
3개의 변경된 파일78개의 추가작업 그리고 44개의 파일을 삭제
  1. 1 0
      RELEASE_NOTES.md
  2. 23 0
      docs/UserManual.md
  3. 54 44
      src/civetweb.c

+ 1 - 0
RELEASE_NOTES.md

@@ -37,6 +37,7 @@ Changes
 - Allow to compile civetweb.c wih a C++ compiler
 - Allow to compile civetweb.c wih a C++ compiler
 - Lua: Remove internal length limits of encode/decode functions
 - Lua: Remove internal length limits of encode/decode functions
 - Allow sub-resources of index script files
 - Allow sub-resources of index script files
+- Add config parameter allow\_index\_script\_resource the aforementioned feature
 - Remove deprecated "uri" member of the request from the interface
 - Remove deprecated "uri" member of the request from the interface
 - Improve documentation
 - Improve documentation
 - Make auth domain check optional (configuration)
 - Make auth domain check optional (configuration)

+ 23 - 0
docs/UserManual.md

@@ -602,6 +602,29 @@ This option can be used to enable or disable the use of the Linux `sendfile` sys
 ### case\_sensitive `no`
 ### case\_sensitive `no`
 This option can be uset to enable case URLs for Windows servers. It is only available for Windows systems. Windows file systems are not case sensitive, but they still store the file name including case. If this option is set to `yes`, the comparison for URIs and Windows file names will be case sensitive.
 This option can be uset to enable case URLs for Windows servers. It is only available for Windows systems. Windows file systems are not case sensitive, but they still store the file name including case. If this option is set to `yes`, the comparison for URIs and Windows file names will be case sensitive.
 
 
+### allow\_index\_script\_resource `no`
+Index scripts (like `index.cgi` or `index.lua`) may have script handled resources.
+
+It this feature is activated, that /some/path/file.ext might be handled by:
+  1. /some/path/file.ext (with PATH\_INFO='/', if ext = cgi)
+  2. /some/path/index.lua with mg.request\_info.path\_info='/file.ext'
+  3. /some/path/index.cgi with PATH\_INFO='/file.ext'
+  4. /some/path/index.php with PATH\_INFO='/file.ext'
+  5. /some/index.lua with mg.request\_info.path\_info=='/path/file.ext'
+  6. /some/index.cgi with PATH\_INFO='/path/file.ext'
+  7. /some/index.php with PATH\_INFO='/path/file.ext'
+  8. /index.lua with mg.request\_info.path\_info=='/some/path/file.ext'
+  9. /index.cgi with PATH\_INFO='/some/path/file.ext'
+  10. /index.php with PATH\_INFO='/some/path/file.ext'
+
+Note: This example is valid, if the default configuration values for `index_files`, `cgi_pattern` and `lua_script_pattern` are used, and the server is built with CGI and Lua support enabled.
+
+If this feature is not activated, only the first file (/some/path/file.cgi) will be accepted.
+
+Note: This parameter affects only index scripts. A path like /here/script.cgi/handle/this.ext will call /here/script.cgi with PATH\_INFO='/handle/this.ext', no matter if this option is set to `yes` or `no`. 
+
+This feature can be used to completely hide the script extension from the URL.
+
 ### additional\_header
 ### additional\_header
 Send additional HTTP response header line for every request.
 Send additional HTTP response header line for every request.
 The full header line including key and value must be specified, excluding the carriage return line feed.
 The full header line including key and value must be specified, excluding the carriage return line feed.

+ 54 - 44
src/civetweb.c

@@ -2124,6 +2124,7 @@ enum {
 #endif
 #endif
 	ADDITIONAL_HEADER,
 	ADDITIONAL_HEADER,
 	MAX_REQUEST_SIZE,
 	MAX_REQUEST_SIZE,
+	ALLOW_INDEX_SCRIPT_SUB_RES,
 
 
 	NUM_OPTIONS
 	NUM_OPTIONS
 };
 };
@@ -2147,8 +2148,8 @@ static struct mg_option config_options[] = {
     {"index_files",
     {"index_files",
      CONFIG_TYPE_STRING_LIST,
      CONFIG_TYPE_STRING_LIST,
 #ifdef USE_LUA
 #ifdef USE_LUA
-     "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index."
-     "cgi,"
+     "index.xhtml,index.html,index.htm,"
+     "index.lp,index.lsp,index.lua,index.cgi,"
      "index.shtml,index.php"},
      "index.shtml,index.php"},
 #else
 #else
      "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
      "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
@@ -2223,6 +2224,7 @@ static struct mg_option config_options[] = {
 #endif
 #endif
     {"additional_header", CONFIG_TYPE_STRING_MULTILINE, NULL},
     {"additional_header", CONFIG_TYPE_STRING_MULTILINE, NULL},
     {"max_request_size", CONFIG_TYPE_NUMBER, "16384"},
     {"max_request_size", CONFIG_TYPE_NUMBER, "16384"},
+    {"allow_index_script_resource", CONFIG_TYPE_BOOLEAN, "no"},
 
 
     {NULL, CONFIG_TYPE_UNKNOWN, NULL}};
     {NULL, CONFIG_TYPE_UNKNOWN, NULL}};
 
 
@@ -3460,8 +3462,8 @@ mg_get_request_link(const struct mg_connection *conn, char *buf, size_t buflen)
 			int def_port = ri->is_ssl ? 443 : 80;
 			int def_port = ri->is_ssl ? 443 : 80;
 			int auth_domain_check_enabled =
 			int auth_domain_check_enabled =
 			    conn->ctx->config[ENABLE_AUTH_DOMAIN_CHECK]
 			    conn->ctx->config[ENABLE_AUTH_DOMAIN_CHECK]
-			    && (!strcmp(conn->ctx->config[ENABLE_AUTH_DOMAIN_CHECK],
-			                "yes"));
+			    && (!mg_strcasecmp(conn->ctx->config[ENABLE_AUTH_DOMAIN_CHECK],
+			                       "yes"));
 			const char *server_domain =
 			const char *server_domain =
 			    conn->ctx->config[AUTHENTICATION_DOMAIN];
 			    conn->ctx->config[AUTHENTICATION_DOMAIN];
 
 
@@ -6713,6 +6715,7 @@ interpret_uri(struct mg_connection *conn, /* in/out: request (must be valid) */
 #if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE)
 #if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE)
 	char *tmp_str;
 	char *tmp_str;
 	size_t tmp_str_len, sep_pos;
 	size_t tmp_str_len, sep_pos;
+	int allow_substitute_script_subresources;
 #endif
 #endif
 #else
 #else
 	(void)filename_buf_len; /* unused if NO_FILES is defined */
 	(void)filename_buf_len; /* unused if NO_FILES is defined */
@@ -6879,6 +6882,10 @@ interpret_uri(struct mg_connection *conn, /* in/out: request (must be valid) */
 	}
 	}
 	memcpy(tmp_str, filename, tmp_str_len + 1);
 	memcpy(tmp_str, filename, tmp_str_len + 1);
 
 
+	/* Check config, if index scripts may have sub-resources */
+	allow_substitute_script_subresources =
+	    !mg_strcasecmp(conn->ctx->config[ALLOW_INDEX_SCRIPT_SUB_RES], "yes");
+
 	sep_pos = tmp_str_len;
 	sep_pos = tmp_str_len;
 	while (sep_pos > 0) {
 	while (sep_pos > 0) {
 		sep_pos--;
 		sep_pos--;
@@ -6902,52 +6909,55 @@ interpret_uri(struct mg_connection *conn, /* in/out: request (must be valid) */
 				*is_found = 1;
 				*is_found = 1;
 				break;
 				break;
 			}
 			}
-			if (substitute_index_file(
-			        conn, tmp_str, tmp_str_len + PATH_MAX, filestat)) {
 
 
-				/* some intermediate directory has an index file */
-				if (extention_matches_script(conn, tmp_str)) {
+			if (allow_substitute_script_subresources) {
+				if (substitute_index_file(
+				        conn, tmp_str, tmp_str_len + PATH_MAX, filestat)) {
 
 
-					char *tmp_str2;
+					/* some intermediate directory has an index file */
+					if (extention_matches_script(conn, tmp_str)) {
 
 
-					DEBUG_TRACE("Substitute script %s serving path %s",
-					            tmp_str,
-					            filename);
+						char *tmp_str2;
 
 
-					/* this index file is a script */
-					tmp_str2 = mg_strdup(filename + sep_pos + 1);
-					mg_snprintf(conn,
-					            &truncated,
-					            filename,
-					            filename_buf_len,
-					            "%s//%s",
-					            tmp_str,
-					            tmp_str2);
-					mg_free(tmp_str2);
+						DEBUG_TRACE("Substitute script %s serving path %s",
+						            tmp_str,
+						            filename);
 
 
-					if (truncated) {
-						mg_free(tmp_str);
-						goto interpret_cleanup;
-					}
-					sep_pos = strlen(tmp_str);
-					filename[sep_pos] = 0;
-					conn->path_info = filename + sep_pos + 1;
-					*is_script_resource = 1;
-					*is_found = 1;
-					break;
+						/* this index file is a script */
+						tmp_str2 = mg_strdup(filename + sep_pos + 1);
+						mg_snprintf(conn,
+						            &truncated,
+						            filename,
+						            filename_buf_len,
+						            "%s//%s",
+						            tmp_str,
+						            tmp_str2);
+						mg_free(tmp_str2);
+
+						if (truncated) {
+							mg_free(tmp_str);
+							goto interpret_cleanup;
+						}
+						sep_pos = strlen(tmp_str);
+						filename[sep_pos] = 0;
+						conn->path_info = filename + sep_pos + 1;
+						*is_script_resource = 1;
+						*is_found = 1;
+						break;
 
 
-				} else {
+					} else {
 
 
-					DEBUG_TRACE("Substitute file %s serving path %s",
-					            tmp_str,
-					            filename);
+						DEBUG_TRACE("Substitute file %s serving path %s",
+						            tmp_str,
+						            filename);
 
 
-					/* non-script files will not have sub-resources */
-					filename[sep_pos] = 0;
-					conn->path_info = 0;
-					*is_script_resource = 0;
-					*is_found = 0;
-					break;
+						/* non-script files will not have sub-resources */
+						filename[sep_pos] = 0;
+						conn->path_info = 0;
+						*is_script_resource = 0;
+						*is_found = 0;
+						break;
+					}
 				}
 				}
 			}
 			}
 
 
@@ -15126,7 +15136,7 @@ get_rel_url_at_current_server(const char *uri, const struct mg_connection *conn)
 	char *portend;
 	char *portend;
 
 
 	auth_domain_check_enabled =
 	auth_domain_check_enabled =
-	    !strcmp(conn->ctx->config[ENABLE_AUTH_DOMAIN_CHECK], "yes");
+	    !mg_strcasecmp(conn->ctx->config[ENABLE_AUTH_DOMAIN_CHECK], "yes");
 
 
 	if (!auth_domain_check_enabled) {
 	if (!auth_domain_check_enabled) {
 		return 0;
 		return 0;
@@ -15733,7 +15743,7 @@ init_connection(struct mg_connection *conn)
 {
 {
 	/* Is keep alive allowed by the server */
 	/* Is keep alive allowed by the server */
 	int keep_alive_enabled =
 	int keep_alive_enabled =
-	    !strcmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes");
+	    !mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes");
 
 
 	if (!keep_alive_enabled) {
 	if (!keep_alive_enabled) {
 		conn->must_close = 1;
 		conn->must_close = 1;