소스 검색

Timeout for CGI processes (#618)

bel2125 7 년 전
부모
커밋
9db33352d2
2개의 변경된 파일34개의 추가작업 그리고 15개의 파일을 삭제
  1. 5 0
      docs/UserManual.md
  2. 29 15
      src/civetweb.c

+ 5 - 0
docs/UserManual.md

@@ -411,6 +411,11 @@ Currently keep\_alive\_timeout\_ms is ignored if enable\_keep\_alive is no,
 but future versions my drop the enable\_keep\_alive configuration value and
 but future versions my drop the enable\_keep\_alive configuration value and
 automatically use keep-alive if keep\_alive\_timeout\_ms is not 0.
 automatically use keep-alive if keep\_alive\_timeout\_ms is not 0.
 
 
+### cgi\_timeout\_ms
+Maximum allowed runtime for CGI scripts.  CGI processes are terminated by
+the server after this time.  The default is "no timeout", so scripts may
+run or block for undefined time.
+
 ### linger\_timeout\_ms
 ### linger\_timeout\_ms
 Set TCP socket linger timeout before closing sockets (SO\_LINGER option).
 Set TCP socket linger timeout before closing sockets (SO\_LINGER option).
 The configured value is a timeout in milliseconds. Setting the value to 0
 The configured value is a timeout in milliseconds. Setting the value to 0

+ 29 - 15
src/civetweb.c

@@ -2260,6 +2260,7 @@ struct socket {
  * "Private Config Options"
  * "Private Config Options"
  */
  */
 enum {
 enum {
+	/* Once for each server */
 	LISTENING_PORTS,
 	LISTENING_PORTS,
 	NUM_THREADS,
 	NUM_THREADS,
 	RUN_AS_USER,
 	RUN_AS_USER,
@@ -2288,8 +2289,11 @@ enum {
 	LUA_BACKGROUND_SCRIPT,
 	LUA_BACKGROUND_SCRIPT,
 	LUA_BACKGROUND_SCRIPT_PARAMS,
 	LUA_BACKGROUND_SCRIPT_PARAMS,
 #endif
 #endif
+#if defined(USE_TIMERS)
+	CGI_TIMEOUT,
+#endif
 
 
-
+	/* Once for each domain */
 	DOCUMENT_ROOT,
 	DOCUMENT_ROOT,
 	CGI_EXTENSIONS,
 	CGI_EXTENSIONS,
 	CGI_ENVIRONMENT,
 	CGI_ENVIRONMENT,
@@ -2386,7 +2390,9 @@ static const struct mg_option config_options[] = {
     {"lua_background_script", MG_CONFIG_TYPE_FILE, NULL},
     {"lua_background_script", MG_CONFIG_TYPE_FILE, NULL},
     {"lua_background_script_params", MG_CONFIG_TYPE_STRING_LIST, NULL},
     {"lua_background_script_params", MG_CONFIG_TYPE_STRING_LIST, NULL},
 #endif
 #endif
-
+#if defined(USE_TIMERS)
+    {"cgi_timeout_ms", MG_CONFIG_TYPE_NUMBER, NULL},
+#endif
 
 
     /* Once for each domain */
     /* Once for each domain */
     {"document_root", MG_CONFIG_TYPE_DIRECTORY, NULL},
     {"document_root", MG_CONFIG_TYPE_DIRECTORY, NULL},
@@ -10861,6 +10867,14 @@ handle_cgi_request(struct mg_connection *conn, const char *prog)
 	pid_t pid = (pid_t)-1;
 	pid_t pid = (pid_t)-1;
 	struct process_control_data *proc = NULL;
 	struct process_control_data *proc = NULL;
 
 
+#if defined(USE_TIMERS)
+	double cgi_timeout = -1.0;
+	if (conn->dom_ctx->config[CGI_TIMEOUT]) {
+		/* Get timeout in seconds */
+		cgi_timeout = atof(conn->dom_ctx->config[CGI_TIMEOUT]) * 0.001;
+	}
+#endif
+
 	if (conn == NULL) {
 	if (conn == NULL) {
 		return;
 		return;
 	}
 	}
@@ -10937,23 +10951,23 @@ handle_cgi_request(struct mg_connection *conn, const char *prog)
 
 
 	/* Store data in shared process_control_data */
 	/* Store data in shared process_control_data */
 	proc->pid = pid;
 	proc->pid = pid;
+	proc->references = 1;
 
 
 #if defined(USE_TIMERS)
 #if defined(USE_TIMERS)
-	proc->references = 2;
-
-	// Start a timer for CGI
-	timer_add(conn->phys_ctx,
-	          /* one minute. TODO: use config or define */ 60.0,
-	          0.0,
-	          1,
-	          abort_process,
-	          (void *)proc);
-#else
-	proc->references = 1;
+	if (cgi_timeout > 0.0) {
+		proc->references = 2;
+
+		// Start a timer for CGI
+		timer_add(conn->phys_ctx,
+		          cgi_timeout /* in seconds */,
+		          0.0,
+		          1,
+		          abort_process,
+		          (void *)proc);
+	}
 #endif
 #endif
 
 
-	/* Make sure child closes all pipe descriptors. It must dup them to 0,1
-	 */
+	/* Make sure child closes all pipe descriptors. It must dup them to 0,1 */
 	set_close_on_exec((SOCKET)fdin[0], conn);  /* stdin read */
 	set_close_on_exec((SOCKET)fdin[0], conn);  /* stdin read */
 	set_close_on_exec((SOCKET)fdin[1], conn);  /* stdin write */
 	set_close_on_exec((SOCKET)fdin[1], conn);  /* stdin write */
 	set_close_on_exec((SOCKET)fdout[0], conn); /* stdout read */
 	set_close_on_exec((SOCKET)fdout[0], conn); /* stdout read */