[REF] websrv_lib: moved vdirs mangement code to websrv_lib

(from service.http_server). The vdirs list is now a global variable, containing
both secure-only and non-necessarily-secure handlers. This makes it possible
to register handlers without being too tied to the multi http request handler.
The goal is obviously to make it possible to serve those handlers by other
means than the multi handler.

bzr revid: vmt@openerp.com-20110907154217-f30nrzgvw45ga2q8
This commit is contained in:
Vo Minh Thu 2011-09-07 17:42:17 +02:00
parent 14a82cdf9f
commit 1cd7804374
2 changed files with 47 additions and 59 deletions

View File

@ -154,7 +154,6 @@ class BaseHttpDaemon(threading.Thread, netsvc.Server):
try:
self.server = ThreadedHTTPServer((interface, port), handler, proto=self._RealProto)
self.server.vdirs = []
self.server.logRequests = True
self.server.timeout = self._busywait_timeout
logging.getLogger("web-services").info(
@ -191,28 +190,6 @@ class BaseHttpDaemon(threading.Thread, netsvc.Server):
res += ", %d threads" % (self.server.numThreads,)
return res
def append_svc(self, service):
if not isinstance(service, HTTPDir):
raise Exception("Wrong class for http service")
pos = len(self.server.vdirs)
lastpos = pos
while pos > 0:
pos -= 1
if self.server.vdirs[pos].matches(service.path):
lastpos = pos
# we won't break here, but search all way to the top, to
# ensure there is no lesser entry that will shadow the one
# we are inserting.
self.server.vdirs.insert(lastpos, service)
def list_services(self):
ret = []
for svc in self.server.vdirs:
ret.append( ( svc.path, str(svc.handler)) )
return ret
# No need for these two classes: init_server() below can initialize correctly
# directly the BaseHttpDaemon class.
class HttpDaemon(BaseHttpDaemon):
@ -245,31 +222,6 @@ def init_servers():
httpsd = HttpSDaemon(tools.config.get('xmlrpcs_interface', ''),
int(tools.config.get('xmlrpcs_port', 8071)))
def reg_http_service(hts, secure_only = False):
""" Register some handler to httpd.
hts must be an HTTPDir
"""
global httpd, httpsd
if httpd and not secure_only:
httpd.append_svc(hts)
if httpsd:
httpsd.append_svc(hts)
if (not httpd) and (not httpsd):
logging.getLogger('httpd').warning("No httpd available to register service %s" % hts.path)
return
def list_http_services(protocol=None):
global httpd, httpsd
if httpd and (protocol == 'http' or protocol == None):
return httpd.list_services()
elif httpsd and (protocol == 'https' or protocol == None):
return httpsd.list_services()
else:
raise Exception("Incorrect protocol or no http services")
import SimpleXMLRPCServer
class XMLRPCRequestHandler(FixSendError,HttpLogHandler,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
rpc_paths = []
@ -305,7 +257,7 @@ def init_xmlrpc():
if tools.config.get('xmlrpcs', False) \
and not tools.config.get('xmlrpc', False):
# only register at the secure server
reg_http_service(HTTPDir('/xmlrpc/', XMLRPCRequestHandler), True)
reg_http_service(HTTPDir('/xmlrpc/', XMLRPCRequestHandler, secure_only=True))
logging.getLogger("web-services").info("Registered XML-RPC over HTTPS only")
class StaticHTTPHandler(HttpLogHandler, FixSendError, HttpOptions, HTTPHandler):

View File

@ -125,13 +125,17 @@ class HTTPHandler(SimpleHTTPRequestHandler):
def setup(self):
pass
# A list of HTTPDir.
handlers = []
class HTTPDir:
""" A dispatcher class, like a virtual folder in httpd
"""
def __init__(self,path,handler, auth_provider = None):
def __init__(self, path, handler, auth_provider=None, secure_only=False):
self.path = path
self.handler = handler
self.auth_provider = auth_provider
self.secure_only = secure_only
def matches(self, request):
""" Test if some request matches us. If so, return
@ -140,6 +144,42 @@ class HTTPDir:
return self.path
return False
def reg_http_service(service):
""" Register some handler to httpd.
hts must be an HTTPDir
"""
assert isinstance(service, HTTPDir), "Wrong class for http service"
global handlers
pos = len(handlers)
lastpos = pos
while pos > 0:
pos -= 1
if handlers[pos].matches(service.path):
lastpos = pos
# we won't break here, but search all way to the top, to
# ensure there is no lesser entry that will shadow the one
# we are inserting.
handlers.insert(lastpos, service)
def list_http_services(protocol=None):
global handlers
ret = []
for svc in handlers:
if protocol is None or protocol == 'http' or svc.secure_only:
ret.append((svc.path, str(svc.handler)))
return ret
def find_http_service(path, secure=False):
global handlers
for vdir in handlers:
p = vdir.matches(path)
if p == False or (vdir.secure_only and not secure):
continue
return vdir
return None
class noconnection(object):
""" a class to use instead of the real connection
"""
@ -408,11 +448,9 @@ class MultiHTTPHandler(FixSendError, HttpOptions, BaseHTTPRequestHandler):
return
self.do_OPTIONS()
return
for vdir in self.server.vdirs:
p = vdir.matches(self.path)
if p == False:
continue
vdir = find_http_service(self.path, self.server.proto == 'HTTPS')
if vdir:
p = vdir.path
npath = self.path[len(p):]
if not npath.startswith('/'):
npath = '/' + npath
@ -433,10 +471,8 @@ class MultiHTTPHandler(FixSendError, HttpOptions, BaseHTTPRequestHandler):
"client closed connection", self.rlpath.rstrip())
else:
raise
return
# if no match:
self.send_error(404, "Path not found: %s" % self.path)
return
else: # no match:
self.send_error(404, "Path not found: %s" % self.path)
def _get_ignore_body(self,fore):
if not fore.headers.has_key("content-length"):