Bug 52795 - mod_fcgid fails to spawn process in C:\Program Files
Summary: mod_fcgid fails to spawn process in C:\Program Files
Status: REOPENED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_fcgid (show other bugs)
Version: 2.2.17
Hardware: PC All
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-02-29 12:50 UTC by Florian Winter
Modified: 2014-06-18 12:07 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Florian Winter 2012-02-29 12:50:53 UTC
If ScriptAlias contains spaces (such as "C:\Program Files\..."), then mod_fcgid fails to spawn the process.

In error.log, I see something similar to:

"Can't run C:\Program"

The problem seems to be in fcgid_proc_win.c:proc_spawn_process, which seems to tokenize the command-line without distinguishing between spaces in the executable path and spaces between command-line arguments. The following code is responsible:

    /* Build wrapper args */
    argc = 0;
    tmp = cmdline;
    while (1) {
        word = ap_getword_white(procnode->proc_pool, &tmp);
        if (word == NULL || *word == '\0')
            break;
        if (argc >= APACHE_ARG_MAX)
            break;
        wargv[argc++] = word;
    }
    wargv[argc] = NULL;

The following workaround solves the problem for me. However, it makes it impossible to pass any additional arguments to the FastCGI process (which is probably not an issue for most people):

        // HACK(flw): Strip all command-line arguments and make the CGI path the first.
	// This works around a problem of the code above which splits the command name at every whitespace.
	argc = 1;
	wargv[0] = procinfo->cgipath;


Please note: I am aware of bug#52436. However, I think that is a different problem, because it occurs on Ubuntu, where fcgid_proc_win.c is not used.

Perhaps, a proper solution is to make it possible to escape spaces or use quotes in ScriptAlias. The documentation does not state that this is possible, and the implementation in fcgid_proc_win.c clearly does not support that.
Comment 1 William A. Rowe Jr. 2012-02-29 18:22:14 UTC
This is either duplicating 52436 or shares the same root issue as 51194

*** This bug has been marked as a duplicate of bug 51194 ***
Comment 2 William A. Rowe Jr. 2012-10-29 19:15:20 UTC
Verified that this was the same root issue as 51194, see the patch attached to that ticket.  Verified that php script paths and names containing spaces work correctly with that patch applied.
Comment 3 Florian Winter 2014-06-18 09:29:13 UTC
This has not been resolved. After upgrading to Apache 2.4.9 and the latest modules without our own patch applied, the same problem still occurs. 

Snippet from httpd.conf:

	ScriptAlias /fcgid-bin/ "C:/Program Files (x86)/FotoWare/My Application/"
	<Location /fcgid-bin/>
		SetHandler fcgid-script
	</Location>

Is it necessary to use any special syntax so that ScriptAlias respects the spaces?
Comment 4 Florian Winter 2014-06-18 12:07:25 UTC
The problem is still the same. Tokenization of the command-line causes the executable path to be split. This happens in proc_spawn_process in fcgid_proc_win.c, except a different tokenization function is used now.

A workaround (which only works if the FCGI script does not take any arguments) is as follows:

/* Build wrapper args */
	// HACK(flw): Whitespace handling is still broken when using ScriptAlias, so skip tokenization of the command-line
    //apr_tokenize_to_argv(cmdline, (char ***)&wargv, procnode->proc_pool);
	wargv = apr_palloc(procnode->proc_pool, 2 * sizeof(char*));
	wargv[0] = cmdline;
	wargv[1] = NULL;


I tried escaping spaces as "\ " in the ScriptAlias and Directory directives in httpd.conf. This only causes requests to fail with 403 Forbidden. Can it be that the paths in Directory and ScriptAlias are parsed differently?

There is no official documentation anywhere about how paths with spaces must be escaped. I tried to learn about it in the code of apr_tokenize_to_argv, but it is C code cluttered with preprocessor macros and memory allocations, so I gave up (working with strings in C is hard. I guess that's why it's broken.../rant)