mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=2162
This commit is contained in:
parent
5a219364ae
commit
d4bfe91523
|
@ -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()
|
|
@ -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())
|
1821
test/miniserv.pl
1821
test/miniserv.pl
File diff suppressed because it is too large
Load Diff
106
test/testbase.py
106
test/testbase.py
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue