Browse Source

Add argument for CGI interpreter (#854)

bel2125 5 years ago
parent
commit
7a206f4143
1 changed files with 50 additions and 14 deletions
  1. 50 14
      src/civetweb.c

+ 50 - 14
src/civetweb.c

@@ -2433,6 +2433,7 @@ enum {
 	CGI_ENVIRONMENT,
 	PUT_DELETE_PASSWORDS_FILE,
 	CGI_INTERPRETER,
+	CGI_INTERPRETER_ARGS,
 	PROTECT_URI,
 	AUTHENTICATION_DOMAIN,
 	ENABLE_AUTH_DOMAIN_CHECK,
@@ -2540,6 +2541,7 @@ static const struct mg_option config_options[] = {
     {"cgi_environment", MG_CONFIG_TYPE_STRING_LIST, NULL},
     {"put_delete_auth_file", MG_CONFIG_TYPE_FILE, NULL},
     {"cgi_interpreter", MG_CONFIG_TYPE_FILE, NULL},
+    {"cgi_interpreter_args", MG_CONFIG_TYPE_STRING, NULL},
     {"protect_uri", MG_CONFIG_TYPE_STRING_LIST, NULL},
     {"authentication_domain", MG_CONFIG_TYPE_STRING, "mydomain.com"},
     {"enable_auth_domain_check", MG_CONFIG_TYPE_BOOLEAN, "yes"},
@@ -5789,8 +5791,10 @@ spawn_process(struct mg_connection *conn,
               const char *dir)
 {
 	HANDLE me;
-	char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
-	    cmdline[PATH_MAX], buf[PATH_MAX];
+	char *p, *interp;
+	char *interp_arg = 0;
+	char full_interp[PATH_MAX], full_dir[PATH_MAX], cmdline[PATH_MAX],
+	    buf[PATH_MAX];
 	int truncated;
 	struct mg_file file = STRUCT_FILE_INITIALIZER;
 	STARTUPINFOA si;
@@ -5840,12 +5844,19 @@ spawn_process(struct mg_connection *conn,
 	                     HANDLE_FLAG_INHERIT,
 	                     0);
 
-	/* If CGI file is a script, try to read the interpreter line */
+	/* First check, if there is a CGI interpreter configured for all CGI
+	 * scripts. */
 	interp = conn->dom_ctx->config[CGI_INTERPRETER];
-	if (interp == NULL) {
+	if (interp != NULL) {
+		/* If there is a configured interpreter, check for additional arguments
+		 */
+		interp_arg = conn->domm_ctx->config[CGI_INTERPRETER_ARGS];
+	} else {
+		/* Otherwise, the interpreter must be stated in the first line of the
+		 * CGI script file, after a #! (shebang) mark. */
 		buf[0] = buf[1] = '\0';
 
-		/* Read the first line of the script into the buffer */
+		/* Get the full script path */
 		mg_snprintf(
 		    conn, &truncated, cmdline, sizeof(cmdline), "%s/%s", dir, prog);
 
@@ -5854,12 +5865,14 @@ spawn_process(struct mg_connection *conn,
 			goto spawn_cleanup;
 		}
 
+		/* Open the script file, to read the first line */
 		if (mg_fopen(conn, cmdline, MG_FOPEN_MODE_READ, &file)) {
 #if defined(MG_USE_OPEN_FILE)
 			p = (char *)file.access.membuf;
 #else
 			p = (char *)NULL;
 #endif
+			/* Read the first line of the script into the buffer */
 			mg_fgets(buf, sizeof(buf), &file, &p);
 			(void)mg_fclose(&file.access); /* ignore error on read only file */
 			buf[sizeof(buf) - 1] = '\0';
@@ -5880,15 +5893,29 @@ spawn_process(struct mg_connection *conn,
 	GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
 
 	if (interp[0] != '\0') {
-		mg_snprintf(conn,
-		            &truncated,
-		            cmdline,
-		            sizeof(cmdline),
-		            "\"%s\" \"%s\\%s\"",
-		            interp,
-		            full_dir,
-		            prog);
+		/* This is an interpreted script file. We must call the interpreter. */
+		if ((interp_arg != 0) && (interp_arg[0] != 0)) {
+			mg_snprintf(conn,
+			            &truncated,
+			            cmdline,
+			            sizeof(cmdline),
+			            "\"%s\" %s \"%s\\%s\"",
+			            interp,
+			            interp_arg,
+			            full_dir,
+			            prog);
+		} else {
+			mg_snprintf(conn,
+			            &truncated,
+			            cmdline,
+			            sizeof(cmdline),
+			            "\"%s\" \"%s\\%s\"",
+			            interp,
+			            full_dir,
+			            prog);
+		}
 	} else {
+		/* This is (probably) a compiled program. We call it directly. */
 		mg_snprintf(conn,
 		            &truncated,
 		            cmdline,
@@ -6152,6 +6179,7 @@ spawn_process(struct mg_connection *conn,
 
 			interp = conn->dom_ctx->config[CGI_INTERPRETER];
 			if (interp == NULL) {
+				/* no interpreter configured, call the programm directly */
 				(void)execle(prog, prog, NULL, envp);
 				mg_cry_internal(conn,
 				                "%s: execle(%s): %s",
@@ -6159,7 +6187,15 @@ spawn_process(struct mg_connection *conn,
 				                prog,
 				                strerror(ERRNO));
 			} else {
-				(void)execle(interp, interp, prog, NULL, envp);
+				/* call the configured interpreter */
+				const char *interp_args =
+				    conn->dom_ctx->config[CGI_INTERPRETER_ARGS];
+
+				if ((interp_args != NULL) && (interp_args[0] != 0)) {
+					(void)execle(interp, interp, interp_args, prog, NULL, envp);
+				} else {
+					(void)execle(interp, interp, prog, NULL, envp);
+				}
 				mg_cry_internal(conn,
 				                "%s: execle(%s %s): %s",
 				                __func__,