This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: CGIHTTPServer does not chdir prior to executing the CGI script
Type: enhancement Stage: test needed
Components: Library (Lib) Versions: Python 3.4
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Thomas Fenzl, christian.heimes, gregory.p.smith, jafo, loewis, majid, neologix, terry.reedy
Priority: normal Keywords: patch

Created on 2007-12-21 21:57 by majid, last changed 2022-04-11 14:56 by admin.

Messages (11)
msg58955 - (view) Author: Fazal Majid (majid) Date: 2007-12-21 21:57
The CGI specification does not specify the working directory the CGI is
invoked in, but the usual behavior is to use the directory containing
the script.

CGIHTTPServer should either change working directory by default (see
patch below), or offer a hook to be called before the exec() call to the
CGI.


*** /usr/local/lib/python2.4/CGIHTTPServer.py   Tue Apr  4 11:13:23 2006
--- kCGIHTTPServer.py   Fri Dec 21 13:31:40 2007
***************
*** 227,232 ****
--- 227,233 ----
                      pass
                  os.dup2(self.rfile.fileno(), 0)
                  os.dup2(self.wfile.fileno(), 1)
+                 os.chdir(os.path.dirname(scriptfile))
                  os.execve(scriptfile, args, os.environ)
              except:
                  self.server.handle_error(self.request,
self.client_address)
msg58956 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2007-12-21 23:08
Can you give some reference to demonstrate that this is the usual behavior?
msg58957 - (view) Author: Fazal Majid (majid) Date: 2007-12-22 01:05
There isn't any normative reference that I know of, in fact the default
behavior is different on Unix and Windows.

Apache 2.2 (and most certainly older versions as well) implements this
in mod_cgi.c. The relevant lines:

    /* Transmute ourselves into the script.
     * NB only ISINDEX scripts get decoded arguments.
     */
    if (((rc = apr_procattr_create(&procattr, p)) != APR_SUCCESS) ||
        ((rc = apr_procattr_io_set(procattr,
                                   e_info->in_pipe,
                                   e_info->out_pipe,
                                   e_info->err_pipe)) != APR_SUCCESS) ||
        ((rc = apr_procattr_dir_set(procattr,
                        ap_make_dirstr_parent(r->pool,
                                              r->filename))) !=
APR_SUCCESS) ||



apr_procattr_dir_set sets the cwd for the child subprocess
ap_make_dirstr_parent is equivalent to os.path.dirname.

As the default behavior is system-dependent, it should not be hardcoded
but some sort of hook should provided to allow implementing either the
UNIX or Windows semantics.
msg58971 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2007-12-23 11:05
A small note from me:

Your proposed patch is no good and is going to lead to strange, hard to
debug bugs in your app. os.chdir() isn't safe in a threaded environment.
You must protect the entire section with a global lock.
msg58972 - (view) Author: Fazal Majid (majid) Date: 2007-12-23 17:03
MT-safety has nothing to do with this. The os.chdir() is invoked from
the new child process that is forked just prior to calling execve() to
run the CGI script, after which it exits. The parent CGIHTTPServer may
be multithreaded, but invoking the CGI script is not a concurrent affair.
msg63847 - (view) Author: Sean Reifschneider (jafo) * (Python committer) Date: 2008-03-18 02:19
Is the reporter correct that it is not thread impacting?
msg87067 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-05-03 20:32
yes the reporter is correct.

the suggested chdir happens in the subprocess.

however, that only works on posix systems:

windows currently uses popen2/3.  (see issue1535504 for another issue
with that).  switching to subprocess and passing in cwd would fix it.

and non-posix non-windows (what is that?) uses execfile to run the
script in process.  we can't fix that one, nor should be bother.  what
is a non-posix non-windows system that needs to run a cgi http server??
msg87075 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-05-03 22:00
fyi - non-posix / non-windows platforms could include alternate python
VMs that don't support fork, popen2 or subprocess.
msg87102 - (view) Author: Fazal Majid (majid) Date: 2009-05-04 07:44
The problem is that in the current implementation there is no hook to
allow overriding any setup prior to exec, so the only way to produce the
standard UNIX behavior assumed by many scripts is to copy-paste the code
and patch it manually, which is very crude and defeats the whole idea of
including it in the standard library.

Part of the problem is that the CGI spec isn't properly documented. A
great many early Internet standards were slapdashedly written up by
Netscape on web sites that were dropped by AOL eventually.
msg112669 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-08-03 20:37
In the absence of the local docs claiming that cgiHTTPServer changes directory, this is a feature request that could only go into 3.2 or later. If I understand http.server.py, the successor does use subprocess, so G.P.Smith's suggestion in msg87067 might be implemented. However, it is not clear to me from the comments if the idea is accepted in principle or not.
msg113035 - (view) Author: Fazal Majid (majid) Date: 2010-08-05 19:56
Well, CGI/1.1 was formally documented by RFC 3875 in October 2004 (a full 11 years after CGI was introduced...).
http://www.rfc-editor.org/rfc/rfc3875.txt

The RFC is classified as "informative", but it's as close to a definitive spec for CGI as we will ever get. Section 7 described the system-specific implementation notes, and 7.2 specifies UNIX in particular:

The current working directory
      The current working directory for the script SHOULD be set to the
      directory containing the script.

This is also the specified behavior for AmugaDOS and EBCDIC POSIX systems. Oddly enough, the RFC editor did not find it worthwhile to specify the behavior on Windows...
History
Date User Action Args
2022-04-11 14:56:29adminsetgithub: 46025
2014-04-16 21:13:35Thomas Fenzlsetnosy: + Thomas Fenzl
2013-11-17 18:58:09pitrousetnosy: + neologix
2013-11-17 15:25:30christian.heimessetversions: + Python 3.4, - Python 3.2
2010-08-05 19:56:40majidsetmessages: + msg113035
2010-08-03 20:37:31terry.reedysetversions: + Python 3.2, - Python 2.5
nosy: + terry.reedy

messages: + msg112669

type: behavior -> enhancement
stage: test needed
2009-05-04 07:45:00majidsetmessages: + msg87102
2009-05-03 22:00:40gregory.p.smithsetassignee: gregory.p.smith ->
messages: + msg87075
2009-05-03 20:32:29gregory.p.smithsetassignee: christian.heimes -> gregory.p.smith

messages: + msg87067
nosy: + gregory.p.smith
2008-03-18 02:19:43jafosetkeywords: + patch
2008-03-18 02:19:27jafosetpriority: normal
assignee: christian.heimes
messages: + msg63847
nosy: + jafo
2007-12-23 17:03:38majidsetmessages: + msg58972
2007-12-23 11:05:58christian.heimessetnosy: + christian.heimes
messages: + msg58971
2007-12-22 01:05:27majidsetmessages: + msg58957
2007-12-21 23:08:28loewissetnosy: + loewis
messages: + msg58956
2007-12-21 21:57:22majidcreate