Browse Source

Redirect stderr of CGI process to error log (Step 3/3)

bel2125 9 years ago
parent
commit
c9bb894b84
3 changed files with 69 additions and 16 deletions
  1. 60 16
      src/civetweb.c
  2. 4 0
      test/linux_fail.cgi
  3. 5 0
      test/linux_fail_silent.cgi

+ 60 - 16
src/civetweb.c

@@ -6363,6 +6363,7 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog)
 	(void)mg_snprintf(conn, &truncated, dir, sizeof(dir), "%s", prog);
 	(void)mg_snprintf(conn, &truncated, dir, sizeof(dir), "%s", prog);
 
 
 	if (truncated) {
 	if (truncated) {
+		mg_cry(conn, "Error: CGI program \"%s\": Path too long", prog);
 		send_http_error(conn, 500, "Error: %s", "CGI path too long");
 		send_http_error(conn, 500, "Error: %s", "CGI path too long");
 		goto done;
 		goto done;
 	}
 	}
@@ -6375,19 +6376,29 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog)
 	}
 	}
 
 
 	if (pipe(fdin) != 0 || pipe(fdout) != 0 || pipe(fderr) != 0) {
 	if (pipe(fdin) != 0 || pipe(fdout) != 0 || pipe(fderr) != 0) {
-		send_http_error(
-		    conn, 500, "Error: Cannot create CGI pipe: %s", strerror(ERRNO));
+		status = strerror(ERRNO);
+		mg_cry(conn,
+		       "Error: CGI program \"%s\": Can not create CGI pipes: %s",
+		       prog,
+		       status);
+		send_http_error(conn, 500, "Error: Cannot create CGI pipe: %s", status);
 		goto done;
 		goto done;
 	}
 	}
 
 
 	pid = spawn_process(
 	pid = spawn_process(
 	    conn, p, blk.buf, blk.var, fdin[0], fdout[1], fderr[1], dir);
 	    conn, p, blk.buf, blk.var, fdin[0], fdout[1], fderr[1], dir);
+
 	if (pid == (pid_t)-1) {
 	if (pid == (pid_t)-1) {
+		status = strerror(ERRNO);
+		mg_cry(conn,
+		       "Error: CGI program \"%s\": Can not spawn CGI process: %s",
+		       prog,
+		       status);
 		send_http_error(conn,
 		send_http_error(conn,
 		                500,
 		                500,
 		                "Error: Cannot spawn CGI process [%s]: %s",
 		                "Error: Cannot spawn CGI process [%s]: %s",
 		                prog,
 		                prog,
-		                strerror(ERRNO));
+		                status);
 		goto done;
 		goto done;
 	}
 	}
 
 
@@ -6409,24 +6420,35 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog)
 	fdin[0] = fdout[1] = fderr[1] = -1;
 	fdin[0] = fdout[1] = fderr[1] = -1;
 
 
 	if ((in = fdopen(fdin[1], "wb")) == NULL) {
 	if ((in = fdopen(fdin[1], "wb")) == NULL) {
-		send_http_error(conn,
-		                500,
-		                "Error: CGI can not open fdin\nfopen: %s",
-		                strerror(ERRNO));
+		status = strerror(ERRNO);
+		mg_cry(conn,
+		       "Error: CGI program \"%s\": Can not open stdin: %s",
+		       prog,
+		       status);
+		send_http_error(
+		    conn, 500, "Error: CGI can not open fdin\nfopen: %s", status);
 		goto done;
 		goto done;
 	}
 	}
+
 	if ((out = fdopen(fdout[0], "rb")) == NULL) {
 	if ((out = fdopen(fdout[0], "rb")) == NULL) {
-		send_http_error(conn,
-		                500,
-		                "Error: CGI can not open fdout\nfopen: %s",
-		                strerror(ERRNO));
+		status = strerror(ERRNO);
+		mg_cry(conn,
+		       "Error: CGI program \"%s\": Can not open stdout: %s",
+		       prog,
+		       status);
+		send_http_error(
+		    conn, 500, "Error: CGI can not open fdout\nfopen: %s", status);
 		goto done;
 		goto done;
 	}
 	}
+
 	if ((err = fdopen(fderr[0], "rb")) == NULL) {
 	if ((err = fdopen(fderr[0], "rb")) == NULL) {
-		send_http_error(conn,
-		                500,
-		                "Error: CGI can not open fdout\nfopen: %s",
-		                strerror(ERRNO));
+		status = strerror(ERRNO);
+		mg_cry(conn,
+		       "Error: CGI program \"%s\": Can not open stderr: %s",
+		       prog,
+		       status);
+		send_http_error(
+		    conn, 500, "Error: CGI can not open fdout\nfopen: %s", status);
 		goto done;
 		goto done;
 	}
 	}
 
 
@@ -6442,6 +6464,9 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog)
 		/* This is a POST/PUT request */
 		/* This is a POST/PUT request */
 		if (!forward_body_data(conn, in, INVALID_SOCKET, NULL)) {
 		if (!forward_body_data(conn, in, INVALID_SOCKET, NULL)) {
 			/* Error sending the body data */
 			/* Error sending the body data */
+			mg_cry(conn,
+			       "Error: CGI program \"%s\": Forward body data failed",
+			       prog);
 			goto done;
 			goto done;
 		}
 		}
 	}
 	}
@@ -6462,6 +6487,11 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog)
 		                500,
 		                500,
 		                "Error: Not enough memory for CGI buffer (%u bytes)",
 		                "Error: Not enough memory for CGI buffer (%u bytes)",
 		                (unsigned int)buflen);
 		                (unsigned int)buflen);
+		mg_cry(conn,
+		       "Error: CGI program \"%s\": Not enough memory for buffer (%u "
+		       "bytes)",
+		       prog,
+		       (unsigned int)buflen);
 		goto done;
 		goto done;
 	}
 	}
 	headers_len = read_request(out, conn, buf, (int)buflen, &data_len);
 	headers_len = read_request(out, conn, buf, (int)buflen, &data_len);
@@ -6471,13 +6501,27 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog)
 		 * stderr. */
 		 * stderr. */
 		i = pull_all(err, conn, buf, (int)buflen);
 		i = pull_all(err, conn, buf, (int)buflen);
 		if (i > 0) {
 		if (i > 0) {
+			mg_cry(conn,
+			       "Error: CGI program \"%s\" sent error "
+			       "message: [%.*s]",
+			       prog,
+			       i,
+			       buf);
 			send_http_error(conn,
 			send_http_error(conn,
 			                500,
 			                500,
-			                "Error: CGI program sent error "
+			                "Error: CGI program \"%s\" sent error "
 			                "message: [%.*s]",
 			                "message: [%.*s]",
+			                prog,
 			                i,
 			                i,
 			                buf);
 			                buf);
 		} else {
 		} else {
+			mg_cry(conn,
+			       "Error: CGI program sent malformed or too big "
+			       "(>%u bytes) HTTP headers: [%.*s]",
+			       (unsigned)buflen,
+			       data_len,
+			       buf);
+
 			send_http_error(conn,
 			send_http_error(conn,
 			                500,
 			                500,
 			                "Error: CGI program sent malformed or too big "
 			                "Error: CGI program sent malformed or too big "

+ 4 - 0
test/linux_fail.cgi

@@ -0,0 +1,4 @@
+#!/bin/sh
+
+>&2 echo "Some error sent to stderr"
+

+ 5 - 0
test/linux_fail_silent.cgi

@@ -0,0 +1,5 @@
+#!/bin/sh
+
+echo not a complete header
+echo and nothing sent to stderr
+