# -*- Mode: Python; tab-width: 4 -*- # ================ # WORK IN PROGRESS # ================ # # the cgi extension has been left behind a bit - passed over # during the last couple of major rewrites. import os import regex if os.name == 'nt': os.sep = '/' import process import syncsock import windll # set SO_OPENTYPE to SYNCHRONOUS_ALERT syncsock.sync_on() kernel32 = windll.module ('kernel32') class cgi_extension: def __init__ (self, regexp, *dirs): self.regexp = regex.compile (regexp) self.dirs = dirs def match (self, path_part): if self.regexp.match (path_part) == len(path_part): return 1 else: return 0 # TODO: this is only half-assed right now... def handle_request (self, channel): [path, params, query, fragment] = channel.uri base, script = os.path.split (path) script_path = os.path.join (channel.root, path[1:]) self.do_cgi_bin (channel, script, script_path) def do_cgi_bin (self, channel, script, script_path): if not os.path.exists (script_path): channel.send_reply ( 404, channel.request, message="No such CGI script (%s)" % repr(script) ) return if not os.path.isfile (script_path): channel.send_reply ( 404, channel.request, message="CGI script is not a plain file (%s)" % repr(script) ) return s = channel.server s.cgi_bin_hits = s.cgi_bin_hits + 1 handle = channel.fileno() env = {} env['SERVER_SOFTWARE'] = 'Medusa/%s' % s.VERSION_STRING env['SERVER_NAME'] = s.server_name env['GATEWAY_INTERFACE'] = 'CGI/1.1' env['SERVER_PROTOCOL'] = 'HTTP/1.0' env['SERVER_PORT'] = str(s.server_port) env['REQUEST_METHOD'] = channel.command stdout = process.get_std_handles()[1] print 'create_process', process.create_process ( script_path, script_path, inherit_handles = 1, # creation_flags = process.DETACHED_PROCESS, environment=env, flags=process.STARTF_USESTDHANDLES, std_input=handle, std_output=stdout, std_error=stdout, ) ## if os.name == 'posix': ## # this is the unix version. ## def do_cgi_bin (self, script, script_path): ## if not os.path.exists (script_path): ## self.send_reply (404, "No such CGI script (%s)" % repr(script)) ## return ## if not os.path.isfile (script_path): ## self.send_reply ( ## 404, ## "CGI script is not a plain file (%s)" % repr(script) ## ) ## return ## nobody = nobody_uid() ## self.send (self.response (200)) ## # hmmm.. can't flush, probably need to use continuation ## # stuff. ## self.server.cgi_bin_hits = self.server.cgi_bin_hits + 1 ## pid = os.fork() ## if pid == 0: ## import fcntl ## import FCNTL ## env = {} ## env['SERVER_SOFTWARE'] = 'Medusa/%s' % VERSION_STRING ## env['SERVER_NAME'] = self.server.server_name ## env['GATEWAY_INTERFACE'] = 'CGI/1.1' ## env['SERVER_PROTOCOL'] = 'HTTP/1.0' ## env['SERVER_PORT'] = str(self.server.server_port) ## env['REQUEST_METHOD'] = self.command ## #uqrest = urllib.unquote(rest) ## #env['PATH_INFO'] = uqrest ## # doesn't seem like a good idea.. ## # PATH_TRANSLATED ## env['SCRIPT_NAME'] = script ## #if query: ## # env['QUERY_STRING'] = query ## #host = self.address_string() ## #if host != self.client_address[0]: ## # env['REMOTE_HOST'] = host ## env['REMOTE_ADDR'] = self.addr[0] ## # AUTH_TYPE ## # REMOTE_USER ## # REMOTE_IDENT ## #env['CONTENT_TYPE'] = self.headers.type ## #length = self.headers.getheader('content-length') ## #if length: ## # env['CONTENT_LENGTH'] = length ## #accept = [] ## #for line in self.headers.getallmatchingheaders('accept'): ## # if line[:1] in string.whitespace: ## # accept.append(string.strip(line)) ## # else: ## # accept = accept + string.split(line[7:]) ## #env['HTTP_ACCEPT'] = string.joinfields(accept, ',') ## ua = get_header (USER_AGENT, current_headera) ## if ua: ## env['HTTP_USER_AGENT'] = ua ## rfile = self.socket.makefile ('r') ## wfile = self.socket.makefile ('w', 0) ## os.dup2 (rfile.fileno(), 0) ## os.dup2 (wfile.fileno(), 1) ## # we need to undo the non-blocking mode set on the socket ## flags = fcntl.fcntl (0, FCNTL.F_GETFL, 0) ## fcntl.fcntl (0, FCNTL.F_SETFL, flags & (~FCNTL.O_NDELAY)) ## flags = fcntl.fcntl (1, FCNTL.F_GETFL, 0) ## fcntl.fcntl (1, FCNTL.F_SETFL, flags & (~FCNTL.O_NDELAY)) ## os.execve (script_path, [script], env) ## else: ## pass ## else: