forked from BOINC/boinc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
svn path=/trunk/boinc/; revision=2162
- Loading branch information
Karl Chen
committed
Aug 21, 2003
1 parent
5a21936
commit d4bfe91
Showing
5 changed files
with
320 additions
and
1,885 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,253 @@ | ||
#!/usr/bin/python | ||
|
||
# $Id$ | ||
# cgi/php web server | ||
|
||
import BaseHTTPServer, CGIHTTPServer | ||
import sys, os, urllib, select | ||
|
||
php_path = None | ||
possible_php_paths = [ '/usr/lib/cgi-bin/php4', | ||
'PROGRAM_PATH/fake_php.py' ] | ||
def setup_php(program_path): | ||
global php_path | ||
for p in possible_php_paths: | ||
p = p.replace('PROGRAM_PATH', program_path) | ||
if os.path.exists(p): | ||
php_path = p | ||
return | ||
raise Exception("No php binary found - not even fake_php.py (program_path=%s) !"%program_path) | ||
|
||
class PHPHTTPRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler): | ||
def is_cgi(self): | ||
if os.path.split(self.path)[1] == '': | ||
index_php = os.path.join(self.path, 'index.php') | ||
if os.path.exists(self.translate_path(index_php)): | ||
self.path = index_php | ||
if self.path.find('.php') != -1: | ||
self.cgi_info = os.path.split(self.path) | ||
return True | ||
# return CGIHTTPServer.CGIHTTPRequestHandler.is_cgi(self) | ||
|
||
for p in self.cgi_directories: | ||
p = os.path.join(p,'/') | ||
if self.path.startswith(p): | ||
self.cgi_info = os.path.split(self.path) | ||
return True | ||
return False | ||
|
||
def run_cgi(self): | ||
"""Execute a CGI script.""" | ||
dir, rest = self.cgi_info | ||
i = rest.rfind('?') | ||
if i >= 0: | ||
rest, query = rest[:i], rest[i+1:] | ||
else: | ||
query = '' | ||
i = rest.find('/') | ||
if i >= 0: | ||
script, rest = rest[:i], rest[i:] | ||
else: | ||
script, rest = rest, '' | ||
scriptname = dir + '/' + script | ||
is_php = script.endswith('.php') | ||
# print "#### cgi_info=%s,dir=%s,rest=%s,script=%s,scriptname=%s,is_php=%s"%(self.cgi_info,dir,rest,script,scriptname,is_php) | ||
if is_php: | ||
if not php_path: raise Exception('php_path not set') | ||
scriptfile = php_path | ||
sourcefile = self.translate_path(scriptname) | ||
else: | ||
scriptfile = self.translate_path(scriptname) | ||
if not os.path.exists(scriptfile): | ||
self.send_error(404, "No such CGI script (%s)" % `scriptname`) | ||
return | ||
if not os.path.isfile(scriptfile): | ||
self.send_error(403, "CGI script is not a plain file (%s)" % | ||
`scriptname`) | ||
return | ||
ispy = self.is_python(scriptname) | ||
if not ispy: | ||
if not (self.have_fork or self.have_popen2 or self.have_popen3): | ||
self.send_error(403, "CGI script is not a Python script (%s)" % | ||
`scriptname`) | ||
return | ||
if not self.is_executable(scriptfile): | ||
self.send_error(403, "CGI script is not executable (%s)" % | ||
`scriptname`) | ||
return | ||
|
||
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html | ||
# XXX Much of the following could be prepared ahead of time! | ||
env = {} | ||
env['DOCUMENT_ROOT'] = os.getcwd() | ||
env['SERVER_SOFTWARE'] = self.version_string() | ||
env['SERVER_NAME'] = self.server.server_name | ||
env['GATEWAY_INTERFACE'] = 'CGI/1.1' | ||
env['SERVER_PROTOCOL'] = self.protocol_version | ||
env['SERVER_PORT'] = str(self.server.server_port) | ||
env['REQUEST_METHOD'] = self.command | ||
uqrest = urllib.unquote(self.cgi_info[1]) | ||
env['REQUEST_URI'] = self.path | ||
# env['PATH_INFO'] = uqrest | ||
# env['PATH_TRANSLATED'] = self.translate_path(uqrest) | ||
env['SCRIPT_NAME'] = scriptname | ||
env['SCRIPT_FILENAME'] = self.translate_path(scriptname) | ||
if query: | ||
env['QUERY_STRING'] = query | ||
host = self.address_string() | ||
if host != self.client_address[0]: | ||
env['REMOTE_HOST'] = host | ||
env['REMOTE_ADDR'] = self.client_address[0] | ||
env['REDIRECT_STATUS'] = '1' # for php | ||
# XXX AUTH_TYPE | ||
# XXX REMOTE_USER | ||
# XXX REMOTE_IDENT | ||
if self.headers.typeheader is None: | ||
env['CONTENT_TYPE'] = self.headers.type | ||
else: | ||
env['CONTENT_TYPE'] = self.headers.typeheader | ||
length = self.headers.getheader('content-length') | ||
if length: | ||
env['CONTENT_LENGTH'] = length | ||
accept = [] | ||
for line in self.headers.getallmatchingheaders('accept'): | ||
if line[:1] in "\t\n\r ": | ||
accept.append(line.strip()) | ||
else: | ||
accept = accept + line[7:].split(',') | ||
env['HTTP_ACCEPT'] = ','.join(accept) | ||
ua = self.headers.getheader('user-agent') | ||
if ua: | ||
env['HTTP_USER_AGENT'] = ua | ||
co = filter(None, self.headers.getheaders('cookie')) | ||
if co: | ||
env['HTTP_COOKIE'] = ', '.join(co) | ||
# XXX Other HTTP_* headers | ||
if not self.have_fork: | ||
# Since we're setting the env in the parent, provide empty | ||
# values to override previously set values | ||
for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH', | ||
'HTTP_USER_AGENT', 'HTTP_COOKIE'): | ||
env.setdefault(k, "") | ||
os.environ.update(env) | ||
|
||
self.send_response(200, "Script output follows") | ||
|
||
decoded_query = query.replace('+', ' ') | ||
|
||
if self.have_fork: | ||
# Unix -- fork as we should | ||
if is_php: | ||
args = [php_path, sourcefile] | ||
else: | ||
args = [script] | ||
if '=' not in decoded_query: | ||
args.append(decoded_query) | ||
nobody = CGIHTTPServer.nobody_uid() | ||
self.wfile.flush() # Always flush before forking | ||
pid = os.fork() | ||
if pid != 0: | ||
# Parent | ||
pid, sts = os.waitpid(pid, 0) | ||
# throw away additional data [see bug #427345] | ||
while select.select([self.rfile], [], [], 0)[0]: | ||
try: | ||
if not self.rfile.read(1): | ||
break | ||
except: | ||
break | ||
if sts: | ||
self.log_error("CGI script exit status %#x", sts) | ||
return | ||
# Child | ||
try: | ||
try: | ||
os.setuid(nobody) | ||
except os.error: | ||
pass | ||
os.dup2(self.rfile.fileno(), 0) | ||
os.dup2(self.wfile.fileno(), 1) | ||
if is_php: | ||
os.chdir(self.translate_path(dir)) | ||
os.execve(scriptfile, args, os.environ) | ||
except: | ||
self.server.handle_error(self.request, self.client_address) | ||
os._exit(127) | ||
|
||
elif self.have_popen2 or self.have_popen3: | ||
# Windows -- use popen2 or popen3 to create a subprocess | ||
import shutil | ||
if self.have_popen3: | ||
popenx = os.popen3 | ||
else: | ||
popenx = os.popen2 | ||
cmdline = scriptfile | ||
if self.is_python(scriptfile): | ||
interp = sys.executable | ||
if interp.lower().endswith("w.exe"): | ||
# On Windows, use python.exe, not pythonw.exe | ||
interp = interp[:-5] + interp[-4:] | ||
cmdline = "%s -u %s" % (interp, cmdline) | ||
if '=' not in query and '"' not in query: | ||
cmdline = '%s "%s"' % (cmdline, query) | ||
self.log_message("command: %s", cmdline) | ||
try: | ||
nbytes = int(length) | ||
except (TypeError, ValueError): | ||
nbytes = 0 | ||
files = popenx(cmdline, 'b') | ||
fi = files[0] | ||
fo = files[1] | ||
if self.have_popen3: | ||
fe = files[2] | ||
if self.command.lower() == "post" and nbytes > 0: | ||
data = self.rfile.read(nbytes) | ||
fi.write(data) | ||
# throw away additional data [see bug #427345] | ||
while select.select([self.rfile._sock], [], [], 0)[0]: | ||
if not self.rfile._sock.recv(1): | ||
break | ||
fi.close() | ||
shutil.copyfileobj(fo, self.wfile) | ||
if self.have_popen3: | ||
errors = fe.read() | ||
fe.close() | ||
if errors: | ||
self.log_error('%s', errors) | ||
sts = fo.close() | ||
if sts: | ||
self.log_error("CGI script exit status %#x", sts) | ||
else: | ||
self.log_message("CGI script exited OK") | ||
|
||
else: | ||
# Other O.S. -- execute script in this process | ||
save_argv = sys.argv | ||
save_stdin = sys.stdin | ||
save_stdout = sys.stdout | ||
save_stderr = sys.stderr | ||
try: | ||
try: | ||
sys.argv = [scriptfile] | ||
if '=' not in decoded_query: | ||
sys.argv.append(decoded_query) | ||
sys.stdout = self.wfile | ||
sys.stdin = self.rfile | ||
execfile(scriptfile, {"__name__": "__main__"}) | ||
finally: | ||
sys.argv = save_argv | ||
sys.stdin = save_stdin | ||
sys.stdout = save_stdout | ||
sys.stderr = save_stderr | ||
except SystemExit, sts: | ||
self.log_error("CGI script exit status %s", str(sts)) | ||
else: | ||
self.log_message("CGI script exited OK") | ||
|
||
def serve(bind='', port=8000, handler=PHPHTTPRequestHandler): | ||
setup_php(os.path.realpath(os.path.dirname(sys.argv[0]))) | ||
httpd = BaseHTTPServer.HTTPServer((bind,port), handler) | ||
httpd.serve_forever() | ||
|
||
if __name__ == '__main__': | ||
serve() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/python | ||
|
||
# $Id$ | ||
|
||
# fake php - all we really need is 'include schedulers.txt' | ||
|
||
import os, sys | ||
|
||
REQUEST_URI = os.environ['REQUEST_URI'] | ||
|
||
print 'Content-Type: text/plain' | ||
|
||
print """--- FAKE PHP --- | ||
[ REQUEST_URI=%s ] | ||
Since I can't find php4 on your system, this stub program fake_php.py just | ||
prints schedulers.txt as necessary. | ||
"""%REQUEST_URI | ||
|
||
if REQUEST_URI.endswith('/index.php'): | ||
sys.stdout.write(open('schedulers.txt').read()) |
Oops, something went wrong.