فهرست منبع

CGI handling on windows: constructing full path to the interpreter. enabling SO_REUSEADDR on listening socket.

Sergey Lyubka 12 سال پیش
والد
کامیت
5642dfcf38
1فایلهای تغییر یافته به همراه28 افزوده شده و 24 حذف شده
  1. 28 24
      mongoose.c

+ 28 - 24
mongoose.c

@@ -1216,7 +1216,7 @@ static pid_t spawn_process(struct mg_connection *conn, const char *prog,
                            char *envblk, char *envp[], int fd_stdin,
                            char *envblk, char *envp[], int fd_stdin,
                            int fd_stdout, const char *dir) {
                            int fd_stdout, const char *dir) {
   HANDLE me;
   HANDLE me;
-  char *p, *interp, cmdline[PATH_MAX], buf[PATH_MAX];
+  char *p, *interp, full_interp[PATH_MAX], cmdline[PATH_MAX], buf[PATH_MAX];
   FILE *fp;
   FILE *fp;
   STARTUPINFOA si = { sizeof(si) };
   STARTUPINFOA si = { sizeof(si) };
   PROCESS_INFORMATION pi = { 0 };
   PROCESS_INFORMATION pi = { 0 };
@@ -1228,34 +1228,40 @@ static pid_t spawn_process(struct mg_connection *conn, const char *prog,
   si.wShowWindow = SW_HIDE;
   si.wShowWindow = SW_HIDE;
 
 
   me = GetCurrentProcess();
   me = GetCurrentProcess();
-  (void) DuplicateHandle(me, (HANDLE) _get_osfhandle(fd_stdin), me,
-      &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
-  (void) DuplicateHandle(me, (HANDLE) _get_osfhandle(fd_stdout), me,
-      &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+  DuplicateHandle(me, (HANDLE) _get_osfhandle(fd_stdin), me,
+                  &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+  DuplicateHandle(me, (HANDLE) _get_osfhandle(fd_stdout), me,
+                  &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
 
 
   // If CGI file is a script, try to read the interpreter line
   // If CGI file is a script, try to read the interpreter line
   interp = conn->ctx->config[CGI_INTERPRETER];
   interp = conn->ctx->config[CGI_INTERPRETER];
   if (interp == NULL) {
   if (interp == NULL) {
-    buf[2] = '\0';
-    mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
-    if ((fp = fopen(cmdline, "r")) != NULL) {
-      (void) fgets(buf, sizeof(buf), fp);
-      if (buf[0] != '#' || buf[1] != '!') {
-        // First line does not start with "#!". Do not set interpreter.
-        buf[2] = '\0';
-      } else {
-        // Trim whitespace in interpreter name
-        for (p = &buf[strlen(buf) - 1]; p > buf && isspace(*p); p--) {
-          *p = '\0';
-        }
-      }
-      (void) fclose(fp);
+    buf[0] = buf[2] = '\0';
+
+    // Read the first line of the script into the buffer
+    snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
+    if ((fp = mg_fopen(cmdline, "r")) != NULL) {
+      fgets(buf, sizeof(buf), fp);
+      fclose(fp);
+      buf[sizeof(buf) - 1] = '\0';
+    }
+
+    if (buf[0] == '#' && buf[1] == '!') {
+      // Trim whitespace in interpreter name
+      for (p = buf + 2; *p != '\0' && isspace(* (unsigned char *) p); )
+        p++;
+      *p = '\0';
     }
     }
     interp = buf + 2;
     interp = buf + 2;
   }
   }
 
 
-  (void) mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s%s%c%s",
-                     interp, interp[0] == '\0' ? "" : " ", dir, '\\', prog);
+  if (interp[0] != '\0') {
+    GetFullPathName(interp, sizeof(full_interp), full_interp, NULL);
+    interp = full_interp;
+  }
+
+  mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s%s",
+              interp, interp[0] == '\0' ? "" : " ", prog);
 
 
   DEBUG_TRACE(("Running [%s]", cmdline));
   DEBUG_TRACE(("Running [%s]", cmdline));
   if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
   if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
@@ -3872,12 +3878,10 @@ static int set_ports_option(struct mg_context *ctx) {
       success = 0;
       success = 0;
     } else if ((sock = socket(so.lsa.sa.sa_family, SOCK_STREAM, 6)) ==
     } else if ((sock = socket(so.lsa.sa.sa_family, SOCK_STREAM, 6)) ==
                INVALID_SOCKET ||
                INVALID_SOCKET ||
-#if !defined(_WIN32)
                // On Windows, SO_REUSEADDR is recommended only for
                // On Windows, SO_REUSEADDR is recommended only for
                // broadcast UDP sockets
                // broadcast UDP sockets
-               setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
+               setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &on,
                           sizeof(on)) != 0 ||
                           sizeof(on)) != 0 ||
-#endif // !_WIN32
                // Set TCP keep-alive. This is needed because if HTTP-level
                // Set TCP keep-alive. This is needed because if HTTP-level
                // keep-alive is enabled, and client resets the connection,
                // keep-alive is enabled, and client resets the connection,
                // server won't get TCP FIN or RST and will keep the connection
                // server won't get TCP FIN or RST and will keep the connection