diff --git a/openerp/service/http_server.py b/openerp/service/http_server.py index 3e76c3810ef..8bf40024282 100644 --- a/openerp/service/http_server.py +++ b/openerp/service/http_server.py @@ -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): diff --git a/openerp/service/websrv_lib.py b/openerp/service/websrv_lib.py index 2e098169bae..5b98714e80e 100644 --- a/openerp/service/websrv_lib.py +++ b/openerp/service/websrv_lib.py @@ -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"):