Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cb0d2d7

Browse files
committed
Issue3113: tests for CGIHTTPRequestHandler failed on windows:
replace the now-invalid popen2 with a call to subprocess.Popen.
1 parent 1afc169 commit cb0d2d7

2 files changed

Lines changed: 20 additions & 58 deletions

File tree

Lib/http/server.py

Lines changed: 18 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
This class implements GET and POST requests to cgi-bin scripts.
1414
1515
If the os.fork() function is not present (e.g. on Windows),
16-
os.popen2() is used as a fallback, with slightly altered semantics; if
17-
that function is not present either (e.g. on Macintosh), only Python
18-
scripts are supported, and they are executed by the current process.
16+
subprocess.Popen() is used as a fallback, with slightly altered semantics.
1917
2018
In all cases, the implementation is intentionally naive -- all
2119
requests are executed synchronously.
@@ -826,8 +824,6 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
826824

827825
# Determine platform specifics
828826
have_fork = hasattr(os, 'fork')
829-
have_popen2 = hasattr(os, 'popen2')
830-
have_popen3 = hasattr(os, 'popen3')
831827

832828
# Make rfile unbuffered -- we need to read one line and then pass
833829
# the rest to a subprocess, so we can't use buffered input.
@@ -929,10 +925,6 @@ def run_cgi(self):
929925
return
930926
ispy = self.is_python(scriptname)
931927
if not ispy:
932-
if not (self.have_fork or self.have_popen2 or self.have_popen3):
933-
self.send_error(403, "CGI script is not a Python script (%r)" %
934-
scriptname)
935-
return
936928
if not self.is_executable(scriptfile):
937929
self.send_error(403, "CGI script is not executable (%r)" %
938930
scriptname)
@@ -1041,13 +1033,9 @@ def run_cgi(self):
10411033
self.server.handle_error(self.request, self.client_address)
10421034
os._exit(127)
10431035

1044-
elif self.have_popen2 or self.have_popen3:
1045-
# Windows -- use popen2 or popen3 to create a subprocess
1046-
import shutil
1047-
if self.have_popen3:
1048-
popenx = os.popen3
1049-
else:
1050-
popenx = os.popen2
1036+
else:
1037+
# Non-Unix -- use subprocess
1038+
import subprocess
10511039
cmdline = scriptfile
10521040
if self.is_python(scriptfile):
10531041
interp = sys.executable
@@ -1062,54 +1050,26 @@ def run_cgi(self):
10621050
nbytes = int(length)
10631051
except (TypeError, ValueError):
10641052
nbytes = 0
1065-
files = popenx(cmdline, 'b')
1066-
fi = files[0]
1067-
fo = files[1]
1068-
if self.have_popen3:
1069-
fe = files[2]
1053+
p = subprocess.Popen(cmdline,
1054+
stdin=subprocess.PIPE,
1055+
stdout=subprocess.PIPE,
1056+
stderr=subprocess.PIPE,
1057+
)
10701058
if self.command.lower() == "post" and nbytes > 0:
10711059
data = self.rfile.read(nbytes)
1072-
fi.write(data)
1060+
else:
1061+
data = None
10731062
# throw away additional data [see bug #427345]
10741063
while select.select([self.rfile._sock], [], [], 0)[0]:
10751064
if not self.rfile._sock.recv(1):
10761065
break
1077-
fi.close()
1078-
shutil.copyfileobj(fo, self.wfile)
1079-
if self.have_popen3:
1080-
errors = fe.read()
1081-
fe.close()
1082-
if errors:
1083-
self.log_error('%s', errors)
1084-
sts = fo.close()
1085-
if sts:
1086-
self.log_error("CGI script exit status %#x", sts)
1087-
else:
1088-
self.log_message("CGI script exited OK")
1089-
1090-
else:
1091-
# Other O.S. -- execute script in this process
1092-
save_argv = sys.argv
1093-
save_stdin = sys.stdin
1094-
save_stdout = sys.stdout
1095-
save_stderr = sys.stderr
1096-
try:
1097-
save_cwd = os.getcwd()
1098-
try:
1099-
sys.argv = [scriptfile]
1100-
if '=' not in decoded_query:
1101-
sys.argv.append(decoded_query)
1102-
sys.stdout = self.wfile
1103-
sys.stdin = self.rfile
1104-
exec(open(scriptfile).read(), {"__name__": "__main__"})
1105-
finally:
1106-
sys.argv = save_argv
1107-
sys.stdin = save_stdin
1108-
sys.stdout = save_stdout
1109-
sys.stderr = save_stderr
1110-
os.chdir(save_cwd)
1111-
except SystemExit as sts:
1112-
self.log_error("CGI script exit status %s", str(sts))
1066+
stdout, stderr = p.communicate(data)
1067+
self.wfile.write(stdout)
1068+
if stderr:
1069+
self.log_error('%s', stderr)
1070+
status = p.returncode
1071+
if status:
1072+
self.log_error("CGI script exit status %#x", status)
11131073
else:
11141074
self.log_message("CGI script exited OK")
11151075

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ Extension Modules
8181
Library
8282
-------
8383

84+
- Patch #3133: http.server.CGIHTTPRequestHandler did not work on windows.
85+
8486
- a new ``urllib`` package was created. It consists of code from
8587
``urllib``, ``urllib2``, ``urlparse``, and ``robotparser``. The old
8688
modules have all been removed. The new package has five submodules:

0 commit comments

Comments
 (0)