Changeset 388 for python/vendor/current/Lib/CGIHTTPServer.py
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Lib/CGIHTTPServer.py
r2 r388 30 30 import SimpleHTTPServer 31 31 import select 32 import copy 32 33 33 34 … … 71 72 72 73 def is_cgi(self): 73 """Test whether self.path corresponds to a CGI script ,74 and return a boolean. 75 76 This function sets self.cgi_info to a tuple (dir, rest)77 when it returns True, where dir is the directory part before78 the CGI script name. Note that rest begins with a 79 slash if it is not empty.80 81 The default implementation tests whether the path 82 begins with one of the strings in the list83 self.cgi_directories (and the next character is a '/'84 or the end of the string).74 """Test whether self.path corresponds to a CGI script. 75 76 Returns True and updates the cgi_info attribute to the tuple 77 (dir, rest) if self.path requires running a CGI script. 78 Returns False otherwise. 79 80 If any exception is raised, the caller should assume that 81 self.path was rejected as invalid and act accordingly. 82 83 The default implementation tests whether the normalized url 84 path begins with one of the strings in self.cgi_directories 85 (and the next character is a '/' or the end of the string). 85 86 """ 86 87 path = self.path 88 89 for x in self.cgi_directories: 90 i = len(x) 91 if path[:i] == x and (not path[i:] or path[i] == '/'): 92 self.cgi_info = path[:i], path[i+1:] 93 return True 87 collapsed_path = _url_collapse_path(self.path) 88 dir_sep = collapsed_path.find('/', 1) 89 head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:] 90 if head in self.cgi_directories: 91 self.cgi_info = head, tail 92 return True 94 93 return False 95 94 … … 107 106 def run_cgi(self): 108 107 """Execute a CGI script.""" 109 path = self.path110 108 dir, rest = self.cgi_info 111 109 112 i = path.find('/', len(dir) + 1)110 i = rest.find('/') 113 111 while i >= 0: 114 nextdir = path[:i]115 nextrest = path[i+1:]112 nextdir = rest[:i] 113 nextrest = rest[i+1:] 116 114 117 115 scriptdir = self.translate_path(nextdir) 118 116 if os.path.isdir(scriptdir): 119 117 dir, rest = nextdir, nextrest 120 i = path.find('/', len(dir) + 1)118 i = rest.find('/') 121 119 else: 122 120 break … … 159 157 # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html 160 158 # XXX Much of the following could be prepared ahead of time! 161 env = {}159 env = copy.deepcopy(os.environ) 162 160 env['SERVER_SOFTWARE'] = self.version_string() 163 161 env['SERVER_NAME'] = self.server.server_name … … 221 219 'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'): 222 220 env.setdefault(k, "") 223 os.environ.update(env)224 221 225 222 self.send_response(200, "Script output follows") … … 253 250 os.dup2(self.rfile.fileno(), 0) 254 251 os.dup2(self.wfile.fileno(), 1) 255 os.execve(scriptfile, args, os.environ)252 os.execve(scriptfile, args, env) 256 253 except: 257 254 self.server.handle_error(self.request, self.client_address) … … 279 276 stdin = subprocess.PIPE, 280 277 stdout = subprocess.PIPE, 281 stderr = subprocess.PIPE 278 stderr = subprocess.PIPE, 279 env = env 282 280 ) 283 281 if self.command.lower() == "post" and nbytes > 0: … … 293 291 if stderr: 294 292 self.log_error('%s', stderr) 293 p.stderr.close() 294 p.stdout.close() 295 295 status = p.returncode 296 296 if status: … … 298 298 else: 299 299 self.log_message("CGI script exited OK") 300 301 302 def _url_collapse_path(path): 303 """ 304 Given a URL path, remove extra '/'s and '.' path elements and collapse 305 any '..' references and returns a colllapsed path. 306 307 Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. 308 The utility of this function is limited to is_cgi method and helps 309 preventing some security attacks. 310 311 Returns: A tuple of (head, tail) where tail is everything after the final / 312 and head is everything before it. Head will always start with a '/' and, 313 if it contains anything else, never have a trailing '/'. 314 315 Raises: IndexError if too many '..' occur within the path. 316 317 """ 318 # Similar to os.path.split(os.path.normpath(path)) but specific to URL 319 # path semantics rather than local operating system semantics. 320 path_parts = path.split('/') 321 head_parts = [] 322 for part in path_parts[:-1]: 323 if part == '..': 324 head_parts.pop() # IndexError if more '..' than prior parts 325 elif part and part != '.': 326 head_parts.append( part ) 327 if path_parts: 328 tail_part = path_parts.pop() 329 if tail_part: 330 if tail_part == '..': 331 head_parts.pop() 332 tail_part = '' 333 elif tail_part == '.': 334 tail_part = '' 335 else: 336 tail_part = '' 337 338 splitpath = ('/' + '/'.join(head_parts), tail_part) 339 collapsed_path = "/".join(splitpath) 340 341 return collapsed_path 300 342 301 343
Note:
See TracChangeset
for help on using the changeset viewer.