我是cherrypy的新手,我尝试使用这个框架开发一个小应用程序。我的问题是,这个应用程序可以很好地服务,浏览器可以在umbemonizer模式下工作时访问。但是当我使用cherrypy.process.plugins.Daemonizer()编写代码时,cherrypy在后台启动,并且它在特定端口上侦听,但是浏览器将拒绝连接(iptables或ufw已经关闭但仍然无法访问)。令人难以置信的是,当我以守护进程模式启动它时,我仍然可以启动一个未经授权的进程,并且它们在同一个端口上进行侦听。我想知道为什么会这样,以及如何解决它?
简单地说:随着Daemonizer启动,cherrypy听了指定端口,但浏览器连接被拒绝;没有Daemonizer,cherrypy的效果非常好。
非常感谢
使用我的代码
from optparse import OptionParser
from cherrypy.process.plugins import Daemonizer
from cherrypy.process.plugins import PIDFile
import cherrypy
import json
import urllib
import datetime
try:
import cPickle as pickle
except:
import pickle
import time
import base64
import os
import sys
'''
cherrypy class
'''
class Index(object):
@cherrypy.expose
def index(self):
return "Say hello to the yellow elephant"
class System(object):
@cherrypy.expose
def env(self, token):
local_token = Token()
if local_token.AuthToken(token) is True:
env = get_env()
return json.dumps(env)
return '{"errcode", "Invalid token"}'
class Jmx(object):
@cherrypy.expose
def get(self, token, host, port, qry):
local_token = Token()
if local_token.AuthToken(token) is True:
url = 'http://' + host + ':' + port + '/jmx?qry=' + qry
jmx = urllib.urlopen(url)
jmx_data = jmx.read().replace('\n', '')
jmx.close()
return jmx_data
return '{"errcode", "Invalid token"}'
"""
command uses base64 encode by using http post method
"""
class Command(object):
def __init__(self):
self.fname = datetime.datetime.now().strftime('%Y-%m-%d_%M-%M-%S') + '.log'
@cherrypy.expose
def run(self, token, command):
local_token = Token()
command = base64.b64decode(command)
if local_token.AuthToken(token) is True:
os.popen(command + ' 2>&1 > /usr/lib/agent/output/' + self.fname)
return '{"errcode", "Invalid token"}'
@cherrypy.expose
def readlog(self, token):
local_token = Token()
if local_token.AuthToken(token) is True:
log = open('/usr/lib/agent/output/' + self.fname)
lines = log.readlines()
log.close()
return json.dumps(lines, ensure_ascii=False)
return '{"errcode", "Invalid token"}'
"""
First time access from central, it will create a new token on slave node, the token is pickle.dump(cacl_mysql_passwd(conf['agent']['secret']))
By token created , if central makes change to secret, the slave node will be inaccessible!!!
"""
class Token(object):
def AuthToken(self, token):
if(os.path.isfile('/usr/lib/agent/key/authenticate.key')) is False:
return self.CreateToken(token)
else:
try:
k = open('/usr/lib/agent/key/authenticate.key', 'rb')
tokenizer = pickle.load(k)
k.close()
if token == tokenizer:
return True
else:
return False
except IOError, e:
return '{"errcode":"' + str(e).replace('\n', '<br/>') + '"}'
@cherrypy.expose
def CreateToken(self, token):
if(os.path.isfile('/usr/lib/agent/key/authenticate.key')) is False:
try:
k = open('/usr/lib/agent/key/authenticate.key', 'wb')
pickle.dump(token, k)
k.close()
return True
except IOError, e:
return '{"Exception":"' + str(e).replace('\n', '<br/>') + '"}'
else:
return '{"errcode":"token exists"}'
class Controller:
def __init__(self, pidfile='/var/run/agent/agent.pid', host='0.0.0.0', port=30050):
self.port = port
self.host = host
self.pidfile = pidfile
self.settings = {
'global': {
'server.socket_port': port,
'server.socket_host': host,
'server.socket_file': '',
'server.socket_queue_size': 5,
'server.protocol_version': 'HTTP/1.1',
'server.log_to_screen': True,
'server.log_file': '',
'server.reverse_dns': False,
'server.thread_pool': 10,
'server.environment': 'production',
'engine.timeout_monitor.on': False
}
}
def start(self):
if os.path.exists(self.pidfile):
sys.stderr.write('PID file exists, server running?\n')
sys.exit(1)
else:
Daemonizer(cherrypy.engine, stdin='/dev/stdin', stdout='/dev/stdout', stderr='/dev/stderr').subscribe()
PIDFile(cherrypy.engine, self.pidfile).subscribe()
cherrypy.tree.mount(Index(), '/')
cherrypy.tree.mount(System(), '/system')
cherrypy.tree.mount(Command(), '/command')
cherrypy.tree.mount(Jmx(), '/jmx')
cherrypy.config.update(self.settings)
cherrypy.engine.start()
cherrypy.engine.block()
def stop(self):
cherrypy.config.update(self.settings)
if os.path.exists(self.pidfile):
cherrypy.engine.stop()
cherrypy.engine.exit()
try:
process = open(self.pidfile).read().strip()
if process != 0:
os.popen('kill -9 %s' % process)
os.remove(self.pidfile)
except IOError, e:
sys.stderr.write(str(e))
else:
sys.stderr.write('PID file does not exist, server gone?\n')
sys.exit(1)
if '__main__' == __name__:
cherrypy.engine.autoreload.stop()
cherrypy.engine.autoreload.unsubscribe()
syntax = 'Syntax: %prog -b 192.168.1.1 -s start'
parser = OptionParser(usage=syntax)
ip = os.popen('hostname -i').read().strip()
hostname = os.popen('hostname --fqdn').read().strip()
parser.add_option('-b', '--bind', action='store', type='string', dest='bind', default=ip, help='Inner network IP address, default value is hostname -i')
parser.add_option('-s', '--signal', action='store', type='string', dest='signal', help='Valid signal is {start|stop|restart}')
options, args = parser.parse_args()
if len(sys.argv) == 1:
print 'Use %s -h or --help for help.' % sys.argv[0]
else:
if options.signal == '':
print 'Must give -s option\'s value'
else:
daemon = Controller(pidfile='/var/run/agent/agent.pid', host=options.bind)
if 'start' == options.signal:
daemon.start()
elif 'stop' == options.signal:
daemon.stop()
else:
print 'Invalid signal'
sys.exit(1)
&#13;