Execute a CGI script.
(self)
| 1122 | return tail.lower() in (".py", ".pyw") |
| 1123 | |
| 1124 | def run_cgi(self): |
| 1125 | """Execute a CGI script.""" |
| 1126 | dir, rest = self.cgi_info |
| 1127 | path = dir + '/' + rest |
| 1128 | i = path.find('/', len(dir)+1) |
| 1129 | while i >= 0: |
| 1130 | nextdir = path[:i] |
| 1131 | nextrest = path[i+1:] |
| 1132 | |
| 1133 | scriptdir = self.translate_path(nextdir) |
| 1134 | if os.path.isdir(scriptdir): |
| 1135 | dir, rest = nextdir, nextrest |
| 1136 | i = path.find('/', len(dir)+1) |
| 1137 | else: |
| 1138 | break |
| 1139 | |
| 1140 | # find an explicit query string, if present. |
| 1141 | rest, _, query = rest.partition('?') |
| 1142 | |
| 1143 | # dissect the part after the directory name into a script name & |
| 1144 | # a possible additional path, to be stored in PATH_INFO. |
| 1145 | i = rest.find('/') |
| 1146 | if i >= 0: |
| 1147 | script, rest = rest[:i], rest[i:] |
| 1148 | else: |
| 1149 | script, rest = rest, '' |
| 1150 | |
| 1151 | scriptname = dir + '/' + script |
| 1152 | scriptfile = self.translate_path(scriptname) |
| 1153 | if not os.path.exists(scriptfile): |
| 1154 | self.send_error( |
| 1155 | HTTPStatus.NOT_FOUND, |
| 1156 | "No such CGI script (%r)" % scriptname) |
| 1157 | return |
| 1158 | if not os.path.isfile(scriptfile): |
| 1159 | self.send_error( |
| 1160 | HTTPStatus.FORBIDDEN, |
| 1161 | "CGI script is not a plain file (%r)" % scriptname) |
| 1162 | return |
| 1163 | ispy = self.is_python(scriptname) |
| 1164 | if self.have_fork or not ispy: |
| 1165 | if not self.is_executable(scriptfile): |
| 1166 | self.send_error( |
| 1167 | HTTPStatus.FORBIDDEN, |
| 1168 | "CGI script is not executable (%r)" % scriptname) |
| 1169 | return |
| 1170 | |
| 1171 | # Reference: https://www6.uniovi.es/~antonio/ncsa_httpd/cgi/env.html |
| 1172 | # XXX Much of the following could be prepared ahead of time! |
| 1173 | env = copy.deepcopy(os.environ) |
| 1174 | env['SERVER_SOFTWARE'] = self.version_string() |
| 1175 | env['SERVER_NAME'] = self.server.server_name |
| 1176 | env['GATEWAY_INTERFACE'] = 'CGI/1.1' |
| 1177 | env['SERVER_PROTOCOL'] = self.protocol_version |
| 1178 | env['SERVER_PORT'] = str(self.server.server_port) |
| 1179 | env['REQUEST_METHOD'] = self.command |
| 1180 | uqrest = urllib.parse.unquote(rest) |
| 1181 | env['PATH_INFO'] = uqrest |
no test coverage detected