*** empty log message ***

svn path=/trunk/boinc/; revision=2162
This commit is contained in:
Karl Chen 2003-08-21 09:27:43 +00:00
parent 5a219364ae
commit d4bfe91523
5 changed files with 320 additions and 1885 deletions

253
test/cgiserver.py Executable file
View File

@ -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()

24
test/fake_php.py Executable file
View File

@ -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
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())

File diff suppressed because it is too large Load Diff

View File

@ -27,11 +27,10 @@ or you are running from the wrong directory.""")
from boinc import *
import atexit, traceback, signal
# raise SystemExit('hi')
# raise Exception('Hi')
import cgiserver
options.have_init_t = False
options.echo_overwrite = False
def test_init():
if options.have_init_t: return
@ -42,7 +41,9 @@ def test_init():
if not os.path.exists('test_uc.py'):
raise SystemExit('Could not find boinc_db.py anywhere')
options.auto_setup = int(get_env_var("BOINC_TEST_AUTO_SETUP",0)) ####
options.program_path = os.path.realpath(os.path.dirname(sys.argv[0]))
options.auto_setup = int(get_env_var("BOINC_TEST_AUTO_SETUP",0))#######
options.user_name = get_env_var("BOINC_TEST_USER_NAME", '') or get_env_var("USER")
options.delete_testbed = get_env_var("BOINC_TEST_DELETE", 'if-successful').lower()
options.install_method = get_env_var("BOINC_TEST_INSTALL_METHOD", 'symlink').lower()
@ -51,6 +52,8 @@ def test_init():
options.drop_db_first = True
if options.auto_setup:
cgiserver.setup_php(program_path = options.program_path)
options.auto_setup_basedir = 'run-%d'%os.getpid()
verbose_echo(0, "Creating testbed in %s"%options.auto_setup_basedir)
os.mkdir(options.auto_setup_basedir)
@ -62,18 +65,18 @@ def test_init():
os.symlink(options.auto_setup_basedir, 'run')
except OSError:
pass
options.miniserv_basedir = os.path.join(os.getcwd(), options.auto_setup_basedir)
options.miniserv_port = 15000 + (os.getpid() % 1000)
options.miniserv_baseurl = 'http://localhost:%d/' % options.miniserv_port
miniserver = MiniServer(options.miniserv_port, options.miniserv_basedir)
miniserver.run()
options.projects_dir = os.path.join(options.miniserv_basedir, 'projects')
options.cgi_dir = os.path.join(options.miniserv_basedir, 'cgi-bin')
options.html_dir = os.path.join(options.miniserv_basedir, 'html')
options.hosts_dir = os.path.join(options.miniserv_basedir, 'hosts')
options.cgi_url = os.path.join(options.miniserv_baseurl, 'cgi-bin')
options.html_url = os.path.join(options.miniserv_baseurl, 'html')
options.port = options.miniserv_port
options.cgiserver_basedir = os.path.join(os.getcwd(), options.auto_setup_basedir)
options.cgiserver_port = 15000 + (os.getpid() % 1000)
options.cgiserver_baseurl = 'http://localhost:%d/' % options.cgiserver_port
CgiServer = AsynchCGIServer()
CgiServer.serve(base_dir=options.auto_setup_basedir, port=options.cgiserver_port)
options.projects_dir = os.path.join(options.cgiserver_basedir, 'projects')
options.cgi_dir = os.path.join(options.cgiserver_basedir, 'cgi-bin')
options.html_dir = os.path.join(options.cgiserver_basedir, 'html')
options.hosts_dir = os.path.join(options.cgiserver_basedir, 'hosts')
options.cgi_url = os.path.join(options.cgiserver_baseurl, 'cgi-bin')
options.html_url = os.path.join(options.cgiserver_baseurl, 'html')
options.port = options.cgiserver_port
map(os.mkdir, [options.projects_dir, options.cgi_dir, options.html_dir, options.hosts_dir])
else:
options.key_dir = get_env_var("BOINC_TEST_KEY_DIR")
@ -628,7 +631,7 @@ def run_check_all():
def delete_test():
'''Delete all test data'''
if options.auto_setup:
if options.auto_setup and hasattr(options,'auto_setup_basedir'):
verbose_echo(1, "Deleting testbed %s."%options.auto_setup_basedir)
shutil.rmtree(options.auto_setup_basedir)
@ -664,54 +667,29 @@ class Proxy:
self.pid = 0
class MiniServer:
def __init__(self, port, doc_root, miniserv_root=None):
self.port = port
self.doc_root = doc_root
self.miniserv_root = miniserv_root or os.path.join(doc_root,'miniserv')
if not os.path.isdir(self.miniserv_root):
os.mkdir(self.miniserv_root)
self.config_file = os.path.join(self.miniserv_root, 'miniserv.conf')
self.log_file = os.path.join(self.miniserv_root, 'miniserv.log')
self.pid_file = os.path.join(self.miniserv_root, 'miniserv.pid')
print >>open(self.config_file,'w'), '''
root=%(doc_root)s
mimetypes=/etc/mime.types
port=%(port)d
addtype_cgi=internal/cgi
addtype_php=internal/cgi
index_docs=index.html index.htm index.cgi index.php
logfile=%(log_file)s
pidfile=%(pid_file)s
logtime=168
ssl=0
#logout=/etc/webmin/logout-flag
#libwrap=1
#alwaysresolve=1
#allow=127.0.0.1
blockhost_time=300
no_pam=0
logouttime=5
passdelay=1
blockhost_failures=3
log=1
logclear=
loghost=1
''' %self.__dict__
def run(self):
verbose_echo(0,"Running miniserv on localhost:%d"%self.port)
if os.spawnl(os.P_WAIT, srcdir('test/miniserv.pl'), 'miniserv', self.config_file):
raise SystemExit("Couldn't spawn miniserv")
atexit.register(self.stop)
def stop(self):
verbose_echo(1,"Killing miniserv")
try:
pid = int(open(self.pid_file).readline())
os.kill(pid, signal.SIGINT)
except Exception, e:
print >>sys.stderr, "Couldn't stop miniserv:", e
class AsynchCGIServer:
def __init__(self):
self.pid = None
def serve(self, port, base_dir):
verbose_echo(0,"Running CGI server on localhost:%d"%port)
self.pid = os.fork()
if self.pid:
atexit.register(self.kill)
return
## child
os.chdir(base_dir)
sys.stderr = open('cgiserver.log', 'w')
cgiserver.serve(port=port)
os._exit(1)
def kill(self):
if self.pid:
verbose_echo(1,"Killing cgiserver")
try:
os.kill(self.pid, 9)
except Exception:
verbose_echo(0, "Couldn't kill cgiserver pid %d" %self.pid)
self.pid = None
def test_msg(msg):
print

View File

@ -36,6 +36,7 @@ reqeval_log()
if [ -z "$USER" ]; then
USER=$LOGNAME
export USER
fi
reqeval "rm -rf $TMPDIR"