def do_POST(self): global _contexts status = 500 try: if self.server.config.dumpHeadersIn: s = 'Incoming HTTP headers' debugHeader(s) print self.raw_requestline.strip() print "\n".join(map (lambda x: x.strip(), self.headers.headers)) debugFooter(s) data = self.rfile.read(int(self.headers["Content-length"])) if self.server.config.dumpSOAPIn: s = 'Incoming SOAP' debugHeader(s) print data, if data[-1] != '\n': print debugFooter(s) (r, header, body, attrs) = \ parseSOAPRPC(data, header = 1, body = 1, attrs = 1) method = r._name args = r._aslist() kw = r._asdict() if Config.simplify_objects: args = simplify(args) kw = simplify(kw) # Handle mixed named and unnamed arguments by assuming # that all arguments with names of the form "v[0-9]+" # are unnamed and should be passed in numeric order, # other arguments are named and should be passed using # this name. # This is a non-standard exension to the SOAP protocol, # but is supported by Apache AXIS. # It is enabled by default. To disable, set # Config.specialArgs to False. if Config.specialArgs: ordered_args = {} named_args = {} for (k,v) in kw.items(): if k[0]=="v": try: i = int(k[1:]) ordered_args[i] = v except ValueError: named_args[str(k)] = v else: named_args[str(k)] = v # We have to decide namespace precedence # I'm happy with the following scenario # if r._ns is specified use it, if not check for # a path, if it's specified convert it and use it as the # namespace. If both are specified, use r._ns. ns = r._ns if len(self.path) > 1 and not ns: ns = self.path.replace("/", ":") if ns[0] == ":": ns = ns[1:] # authorization method a = None keylist = ordered_args.keys() keylist.sort() # create list in proper order w/o names tmp = map( lambda x: ordered_args[x], keylist) ordered_args = tmp #print '<-> Argument Matching Yielded:' #print '<-> Ordered Arguments:' + str(ordered_args) #print '<-> Named Arguments :' + str(named_args) resp = "" # For fault messages if ns: nsmethod = "%s:%s" % (ns, method) else: nsmethod = method try: # First look for registered functions if self.server.funcmap.has_key(ns) and \ self.server.funcmap[ns].has_key(method): f = self.server.funcmap[ns][method] # look for the authorization method if self.server.config.authMethod != None: authmethod = self.server.config.authMethod if self.server.funcmap.has_key(ns) and \ self.server.funcmap[ns].has_key(authmethod): a = self.server.funcmap[ns][authmethod] else: # Now look at registered objects # Check for nested attributes. This works even if # there are none, because the split will return # [method] f = self.server.objmap[ns] # Look for the authorization method if self.server.config.authMethod != None: authmethod = self.server.config.authMethod if hasattr(f, authmethod): a = getattr(f, authmethod) # then continue looking for the method l = method.split(".") for i in l: f = getattr(f, i) except: info = sys.exc_info() try: resp = buildSOAP(faultType("%s:Client" % NS.ENV_T, "Method Not Found", "%s : %s %s %s" % (nsmethod, info[0], info[1], info[2])), encoding = self.server.encoding, config = self.server.config) finally: del info status = 500 else: try: if header: x = HeaderHandler(header, attrs) fr = 1 # call context book keeping # We're stuffing the method into the soapaction if there # isn't one, someday, we'll set that on the client # and it won't be necessary here # for now we're doing both if "SOAPAction".lower() not in self.headers.keys() or \ self.headers["SOAPAction"] == "\"\"": self.headers["SOAPAction"] = method thread_id = thread.get_ident() _contexts[thread_id] = SOAPContext(header, body, attrs, data, self.connection, self.headers, self.headers["SOAPAction"]) # Do an authorization check if a != None: if not apply(a, (), {"_SOAPContext" : _contexts[thread_id] }): raise faultType("%s:Server" % NS.ENV_T, "Authorization failed.", "%s" % nsmethod) # If it's wrapped, some special action may be needed if isinstance(f, MethodSig): c = None if f.context: # retrieve context object c = _contexts[thread_id] if Config.specialArgs: if c: named_args["_SOAPContext"] = c fr = apply(f, ordered_args, named_args) elif f.keywords: # This is lame, but have to de-unicode # keywords strkw = {} for (k, v) in kw.items(): strkw[str(k)] = v if c: strkw["_SOAPContext"] = c fr = apply(f, (), strkw) elif c: fr = apply(f, args, {'_SOAPContext':c}) else: fr = apply(f, args, {}) else: if Config.specialArgs: fr = apply(f, ordered_args, named_args) else: fr = apply(f, args, {}) if type(fr) == type(self) and \ isinstance(fr, voidType): resp = buildSOAP(kw = {'%sResponse' % method: fr}, encoding = self.server.encoding, config = self.server.config) else: resp = buildSOAP(kw = {'%sResponse' % method: {'Result': fr}}, encoding = self.server.encoding, config = self.server.config) # Clean up _contexts if _contexts.has_key(thread_id): del _contexts[thread_id] except Exception, e: import traceback info = sys.exc_info() try: if self.server.config.dumpFaultInfo: s = 'Method %s exception' % nsmethod debugHeader(s) traceback.print_exception(info[0], info[1], info[2]) debugFooter(s) if isinstance(e, faultType): f = e else: f = faultType("%s:Server" % NS.ENV_T, "Method Failed", "%s" % nsmethod) if self.server.config.returnFaultInfo: f._setDetail("".join(traceback.format_exception( info[0], info[1], info[2]))) elif not hasattr(f, 'detail'): f._setDetail("%s %s" % (info[0], info[1])) finally: del info resp = buildSOAP(f, encoding = self.server.encoding, config = self.server.config) status = 500 else: status = 200
resp = buildSOAP(f, encoding = self.server.encoding, config = self.server.config) status = 500 else: status = 200 except faultType, e: import traceback info = sys.exc_info() try: if self.server.config.dumpFaultInfo: s = 'Received fault exception' debugHeader(s) traceback.print_exception(info[0], info[1], info[2]) debugFooter(s) if self.server.config.returnFaultInfo: e._setDetail("".join(traceback.format_exception( info[0], info[1], info[2]))) elif not hasattr(e, 'detail'): e._setDetail("%s %s" % (info[0], info[1])) finally: del info resp = buildSOAP(e, encoding = self.server.encoding, config = self.server.config) status = 500 except Exception, e: # internal error, report as HTTP server error
resp = buildSOAP(f, encoding=self.server.encoding, config=self.server.config) status = 500 else: status = 200 except faultType, e: import traceback info = sys.exc_info() try: if self.server.config.dumpFaultInfo: s = 'Received fault exception' debugHeader(s) traceback.print_exception(info[0], info[1], info[2]) debugFooter(s) if self.server.config.returnFaultInfo: e._setDetail("".join( traceback.format_exception(info[0], info[1], info[2]))) elif not hasattr(e, 'detail'): e._setDetail("%s %s" % (info[0], info[1])) finally: del info resp = buildSOAP(e, encoding=self.server.encoding, config=self.server.config) status = 500 except Exception, e: # internal error, report as HTTP server error
def do_POST(self): global _contexts status = 500 try: if self.server.config.dumpHeadersIn: s = 'Incoming HTTP headers' debugHeader(s) print self.raw_requestline.strip() print "\n".join(map(lambda x: x.strip(), self.headers.headers)) debugFooter(s) data = self.rfile.read(int(self.headers["Content-length"])) if self.server.config.dumpSOAPIn: s = 'Incoming SOAP' debugHeader(s) print data, if data[-1] != '\n': print debugFooter(s) (r, header, body, attrs) = \ parseSOAPRPC(data, header = 1, body = 1, attrs = 1) method = r._name args = r._aslist() kw = r._asdict() if Config.simplify_objects: args = simplify(args) kw = simplify(kw) # Handle mixed named and unnamed arguments by assuming # that all arguments with names of the form "v[0-9]+" # are unnamed and should be passed in numeric order, # other arguments are named and should be passed using # this name. # This is a non-standard exension to the SOAP protocol, # but is supported by Apache AXIS. # It is enabled by default. To disable, set # Config.specialArgs to False. ordered_args = {} named_args = {} if Config.specialArgs: for (k, v) in kw.items(): if k[0] == "v": try: i = int(k[1:]) ordered_args[i] = v except ValueError: named_args[str(k)] = v else: named_args[str(k)] = v # We have to decide namespace precedence # I'm happy with the following scenario # if r._ns is specified use it, if not check for # a path, if it's specified convert it and use it as the # namespace. If both are specified, use r._ns. ns = r._ns if len(self.path) > 1 and not ns: ns = self.path.replace("/", ":") if ns[0] == ":": ns = ns[1:] # authorization method a = None keylist = ordered_args.keys() keylist.sort() # create list in proper order w/o names tmp = map(lambda x: ordered_args[x], keylist) ordered_args = tmp #print '<-> Argument Matching Yielded:' #print '<-> Ordered Arguments:' + str(ordered_args) #print '<-> Named Arguments :' + str(named_args) resp = "" # For fault messages if ns: nsmethod = "%s:%s" % (ns, method) else: nsmethod = method try: # First look for registered functions if self.server.funcmap.has_key(ns) and \ self.server.funcmap[ns].has_key(method): f = self.server.funcmap[ns][method] # look for the authorization method if self.server.config.authMethod != None: authmethod = self.server.config.authMethod if self.server.funcmap.has_key(ns) and \ self.server.funcmap[ns].has_key(authmethod): a = self.server.funcmap[ns][authmethod] else: # Now look at registered objects # Check for nested attributes. This works even if # there are none, because the split will return # [method] f = self.server.objmap[ns] # Look for the authorization method if self.server.config.authMethod != None: authmethod = self.server.config.authMethod if hasattr(f, authmethod): a = getattr(f, authmethod) # then continue looking for the method l = method.split(".") for i in l: f = getattr(f, i) except: info = sys.exc_info() try: resp = buildSOAP(faultType( "%s:Client" % NS.ENV_T, "Method Not Found", "%s : %s %s %s" % (nsmethod, info[0], info[1], info[2])), encoding=self.server.encoding, config=self.server.config) finally: del info status = 500 else: try: if header: x = HeaderHandler(header, attrs) fr = 1 # call context book keeping # We're stuffing the method into the soapaction if there # isn't one, someday, we'll set that on the client # and it won't be necessary here # for now we're doing both if "SOAPAction".lower() not in self.headers.keys() or \ self.headers["SOAPAction"] == "\"\"": self.headers["SOAPAction"] = method thread_id = thread.get_ident() _contexts[thread_id] = SOAPContext( header, body, attrs, data, self.connection, self.headers, self.headers["SOAPAction"]) # Do an authorization check if a != None: if not apply(a, (), {"_SOAPContext": _contexts[thread_id]}): raise faultType("%s:Server" % NS.ENV_T, "Authorization failed.", "%s" % nsmethod) # If it's wrapped, some special action may be needed if isinstance(f, MethodSig): c = None if f.context: # retrieve context object c = _contexts[thread_id] if Config.specialArgs: if c: named_args["_SOAPContext"] = c fr = apply(f, ordered_args, named_args) elif f.keywords: # This is lame, but have to de-unicode # keywords strkw = {} for (k, v) in kw.items(): strkw[str(k)] = v if c: strkw["_SOAPContext"] = c fr = apply(f, (), strkw) elif c: fr = apply(f, args, {'_SOAPContext': c}) else: fr = apply(f, args, {}) else: if Config.specialArgs: fr = apply(f, ordered_args, named_args) else: fr = apply(f, args, {}) if type(fr) == type(self) and \ isinstance(fr, voidType): resp = buildSOAP(kw={'%sResponse' % method: fr}, encoding=self.server.encoding, config=self.server.config) else: resp = buildSOAP( kw={'%sResponse' % method: { 'Result': fr }}, encoding=self.server.encoding, config=self.server.config) # Clean up _contexts if _contexts.has_key(thread_id): del _contexts[thread_id] except Exception, e: import traceback info = sys.exc_info() try: if self.server.config.dumpFaultInfo: s = 'Method %s exception' % nsmethod debugHeader(s) traceback.print_exception(info[0], info[1], info[2]) debugFooter(s) if isinstance(e, faultType): f = e else: f = faultType("%s:Server" % NS.ENV_T, "Method Failed", "%s" % nsmethod) if self.server.config.returnFaultInfo: f._setDetail("".join( traceback.format_exception( info[0], info[1], info[2]))) elif not hasattr(f, 'detail'): f._setDetail("%s %s" % (info[0], info[1])) finally: del info resp = buildSOAP(f, encoding=self.server.encoding, config=self.server.config) status = 500 else: status = 200
def do_POST(self): status = 500 try: if self.server.config.dumpHeadersIn: s = 'Incoming HTTP headers' debugHeader(s) print self.raw_requestline.strip() print "\n".join(map (lambda x: x.strip(), self.headers.headers)) debugFooter(s) data = self.rfile.read(int(self.headers["content-length"])) # data = data.encode('ascii','replace') if self.server.config.dumpSOAPIn: s = 'Incoming SOAP' debugHeader(s) print data, if data[-1] != '\n': print debugFooter(s) (r, header, body, attrs) = \ parseSOAPRPC(data, header = 1, body = 1, attrs = 1) method = r._name args = r._aslist kw = r._asdict # Handle mixed named and unnamed arguments by assuming # that all arguments with names of the form "_[0-9]+" # are unnamed and should be passed in numeric order, # other arguments are named and should be passed using # this name. This is a custom exension to the SOAP # protocol, and is thus disabled by default. To # enable, set Config.specialArgs to a true value. if Config.specialArgs: ordered_args = {} named_args = {} for (k,v) in kw.items(): m = re.match("_([0-9]+)", k) if m is None: named_args[str(k)] = v else: ordered_args[int(m.group(1))] = v keylist = ordered_args.keys() keylist.sort() tmp = map( lambda x: ordered_args[x], keylist) ordered_args = tmp #print '<-> Argument Matching Yielded:' #print '<-> Ordered Arguments:' + str(ordered_args) #print '<-> Named Arguments :' + str(named_args) ns = r._ns resp = "" # For fault messages if ns: nsmethod = "%s:%s" % (ns, method) else: nsmethod = method try: # First look for registered functions if self.server.funcmap.has_key(ns) and \ self.server.funcmap[ns].has_key(method): f = self.server.funcmap[ns][method] else: # Now look at registered objects # Check for nested attributes. This works even if # there are none, because the split will return # [method] f = self.server.objmap[ns] l = method.split(".") for i in l: f = getattr(f, i) except: resp = buildSOAP(faultType("%s:Client" % NS.ENV_T, "No method %s found" % nsmethod, "%s %s" % tuple(sys.exc_info()[0:2])), encoding = self.server.encoding, config = self.server.config) status = 500 else: try: if header: x = HeaderHandler(header, attrs) # If it's wrapped, some special action may be needed if isinstance(f, MethodSig): c = None if f.context: # Build context object c = SOAPContext(header, body, attrs, data, self.connection, self.headers, self.headers["soapaction"]) if Config.specialArgs: if c: named_args["_SOAPContext"] = c fr = apply(f, ordered_args, named_args) elif f.keywords: # This is lame, but have to de-unicode # keywords strkw = {} for (k, v) in kw.items(): strkw[str(k)] = v if c: strkw["_SOAPContext"] = c fr = apply(f, (), strkw) elif c: fr = apply(f, args, {'_SOAPContext':c}) else: fr = apply(f, args, {}) else: if Config.specialArgs: fr = apply(f, ordered_args, named_args) else: fr = apply(f, args, {}) if type(fr) == type(self) and \ isinstance(fr, voidType): resp = buildSOAP(kw = {'%sResponse' % method: fr}, encoding = self.server.encoding, config = self.server.config) else: resp = buildSOAP(kw = {'%sResponse' % method: {'Result': fr}}, encoding = self.server.encoding, config = self.server.config) except Exception, e: import traceback info = sys.exc_info() if self.server.config.dumpFaultInfo: s = 'Method %s exception' % nsmethod debugHeader(s) traceback.print_exception(info[0], info[1], info[2]) debugFooter(s) if isinstance(e, faultType): f = e else: f = faultType("%s:Server" % NS.ENV_T, "Method %s failed." % nsmethod) if self.server.config.returnFaultInfo: f._setDetail("".join(traceback.format_exception( info[0], info[1], info[2]))) elif not hasattr(f, 'detail'): f._setDetail("%s %s" % (info[0], info[1])) resp = buildSOAP(f, encoding = self.server.encoding, config = self.server.config) status = 500 else: status = 200