1313This class implements GET and POST requests to cgi-bin scripts.
1414
1515If 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
2018In all cases, the implementation is intentionally naive -- all
2119requests 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
0 commit comments