Exemple #1
0
    def __init__(self, header, attrs):
        for i in header.__dict__.keys():
            if i[0] == "_":
                continue

            d = getattr(header, i)

            try:
                fault = int(attrs[id(d)][(NS.ENV, 'mustUnderstand')])
            except Exception:
                fault = 0

            if fault:
                raise faultType("%s:MustUnderstand" % NS.ENV_T,
                                "Required Header Misunderstood", "%s" % i)
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #4
0
    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
Exemple #5
0
    def endElementNS(self, name, qname):
        # Workaround two sax bugs
        if name[0] is None and name[1][0] == ' ':
            ns, name = None, name[1][1:]
        else:
            ns, name = tuple(name)

        name = fromXMLname(name)  # convert to SOAP 1.2 XML name encoding

        if self._next == "E":
            raise Error("didn't get SOAP-ENV:Envelope")
        if self._next in ("HorB", "B"):
            raise Error("didn't get SOAP-ENV:Body")

        cur = self.popFrame()
        attrs = cur.attrs

        idval = None

        if (None, 'id') in attrs:
            idval = attrs[(None, 'id')]

            if idval in self._ids:
                raise Error("duplicate id `%s'" % idval)

            del attrs[(None, 'id')]

        root = 1

        if len(self._stack) == 3:
            if (NS.ENC, 'root') in attrs:
                root = int(attrs[(NS.ENC, 'root')])

                # Do some preliminary checks. First, if root="0" is present,
                # the element must have an id. Next, if root="n" is present,
                # n something other than 0 or 1, raise an exception.

                if root == 0:
                    if idval is None:
                        raise Error("non-root element must have an id")
                elif root != 1:
                    raise Error("SOAP-ENC:root must be `0' or `1'")

                del attrs[(NS.ENC, 'root')]

        while 1:
            href = attrs.get((None, 'href'))
            if href:
                if href[0] != '#':
                    raise Error("Non-local hrefs are not yet suppported.")
                if self._data is not None and \
                   string.join(self._data, "").strip() != '':
                    raise Error("hrefs can't have data")

                href = href[1:]

                if href in self._ids:
                    data = self._ids[href]
                else:
                    data = RefHolder(name, self._stack[-1])

                    if href in self._refs:
                        self._refs[href].append(data)
                    else:
                        self._refs[href] = [data]

                del attrs[(None, 'href')]

                break

            kind = None

            if attrs:
                for i in NS.XSI_L:
                    if (i, 'type') in attrs:
                        kind = attrs[(i, 'type')]
                        del attrs[(i, 'type')]

                if kind is not None:
                    i = kind.find(':')
                    if i >= 0:
                        try:
                            kind = (self._prem[kind[:i]], kind[i + 1:])
                        except Exception:
                            kind = (None, kind)
                    else:
                        # XXX What to do here? (None, kind) is just
                        # going to fail in convertType print "Kind with
                        # no NS:", kind
                        kind = (None, kind)

            null = 0

            if attrs:
                for i in (NS.XSI, NS.XSI2):
                    if (i, 'null') in attrs:
                        null = attrs[(i, 'null')]
                        del attrs[(i, 'null')]

                if (NS.XSI3, 'nil') in attrs:
                    null = attrs[(NS.XSI3, 'nil')]
                    del attrs[(NS.XSI3, 'nil')]

                # Check for nil

                # check for nil='true'
                if type(null) in (StringType, UnicodeType):
                    if null.lower() == 'true':
                        null = 1

                # check for nil=1, but watch out for string values
                try:
                    null = int(null)
                except ValueError, e:
                    if not e[0].startswith("invalid literal for int()"):
                        raise e
                    null = 0

                if null:
                    if len(cur) \
                       or (self._data is not None
                           and string.join(self._data, "").strip() != ''):
                        raise Error("nils can't have data")

                    data = None

                    break

            if len(self._stack) == 2:
                if (ns, name) == (NS.ENV, "Header"):
                    self.header = data = headerType(attrs=attrs)
                    self._next = "B"
                    break
                elif (ns, name) == (NS.ENV, "Body"):
                    self.body = data = bodyType(attrs=attrs)
                    self._next = ""
                    break
            elif len(self._stack) == 3 and self._next is None:
                if (ns, name) == (NS.ENV, "Fault"):
                    data = faultType()
                    self._next = None  # allow followons
                    break

            # print "\n"
            # print "data=", self._data
            # print "kind=", kind
            # print "cur.kind=", cur.kind
            # print "cur.rules=", cur.rules
            # print "\n"

            if cur.rules is not None:
                rule = cur.rules

                if type(rule) in (StringType, UnicodeType):
                    rule = (None, rule)  # none flags special handling
                elif type(rule) == ListType:
                    rule = tuple(rule)

                # print "kind=",kind
                # print "rule=",rule

                # XXX What if rule != kind?
                if callable(rule):
                    data = rule(string.join(self._data, ""))
                elif type(rule) == DictType:
                    data = structType(name=(ns, name), attrs=attrs)
                elif rule[1][:9] == 'arrayType':
                    data = self.convertType(cur.contents, rule, attrs)
                else:
                    data = self.convertType(string.join(self._data, ""), rule,
                                            attrs)

                break

            # print "No rules, using kind or cur.kind..."

            if (kind is None and cur.kind is not None) or \
                    (kind == (NS.ENC, 'Array')):
                kind = cur.kind

                if kind is None:
                    kind = 'ur-type[%d]' % len(cur)
                else:
                    kind = kind[1]

                if len(cur.namecounts) == 1:
                    elemsname = cur.names[0]
                else:
                    elemsname = None

                data = self.startArray((ns, name), kind, attrs, elemsname)

                break

            if len(self._stack) == 3 and kind is None and \
                    len(cur) == 0 and \
                    (self._data is None
                     or string.join(self._data, "").strip() == ''):
                data = structType(name=(ns, name), attrs=attrs)
                break

            if len(cur) == 0 and ns != NS.URN:
                # Nothing's been added to the current frame so it must be a
                # simple type.

                #                 print "cur:", cur
                #                 print "ns:", ns
                #                 print "attrs:", attrs
                #                 print "kind:", kind

                if kind is None:
                    # If the current item's container is an array, it will
                    # have a kind. If so, get the bit before the first [,
                    # which is the type of the array, therefore the type of
                    # the current item.

                    kind = self._stack[-1].kind

                    if kind is not None:
                        i = kind[1].find('[')
                        if i >= 0:
                            kind = (kind[0], kind[1][:i])
                    elif ns is not None:
                        kind = (ns, name)

                if kind is not None:
                    try:
                        data = self.convertType(string.join(self._data, ""),
                                                kind, attrs)
                    except UnknownTypeError:
                        data = None
                else:
                    data = None

                if data is None:
                    if self._data is None:
                        data = ''
                    else:
                        data = string.join(self._data, "")

                    if len(attrs) == 0:
                        try:
                            data = str(data)
                        except Exception:
                            pass

                break

            data = structType(name=(ns, name), attrs=attrs)

            break
Exemple #6
0
    def startElementNS(self, name, qname, attrs):
        def toStr(name):
            prefix = name[0]
            tag = name[1]
            if prefix in self._prem_r:
                tag = self._prem_r[name[0]] + ':' + name[1]
            elif prefix:
                tag = prefix + ":" + tag
            return tag

        # Workaround two sax bugs
        if name[0] is None and name[1][0] == ' ':
            name = (None, name[1][1:])
        else:
            name = tuple(name)

        # First some checking of the layout of the message

        if self._next == "E":
            if name[1] != 'Envelope':
                raise Error("expected `SOAP-ENV:Envelope', "
                            "got `%s'" % toStr(name))
            if name[0] != NS.ENV:
                raise faultType(
                    "%s:VersionMismatch" % NS.ENV_T,
                    "Don't understand version `%s' Envelope" % name[0])
            else:
                self._next = "HorB"
        elif self._next == "HorB":
            if name[0] == NS.ENV and name[1] in ("Header", "Body"):
                self._next = None
            else:
                raise Error("expected `SOAP-ENV:Header' or `SOAP-ENV:Body', "
                            "got `%s'" % toStr(name))
        elif self._next == "B":
            if name == (NS.ENV, "Body"):
                self._next = None
            else:
                raise Error("expected `SOAP-ENV:Body', "
                            "got `%s'" % toStr(name))
        elif self._next == "":
            raise Error("expected nothing, " "got `%s'" % toStr(name))

        if len(self._stack) == 2:
            rules = self._rules
        else:
            try:
                rules = self._stack[-1].rules[name[1]]
            except Exception:
                rules = None

        if type(rules) not in (NoneType, DictType):
            kind = rules
        else:
            kind = attrs.get((NS.ENC, 'arrayType'))

            if kind is not None:
                del attrs._attrs[(NS.ENC, 'arrayType')]

                i = kind.find(':')
                if i >= 0:
                    try:
                        kind = (self._prem[kind[:i]], kind[i + 1:])
                    except Exception:
                        kind = None
                else:
                    kind = None

        self.pushFrame(self.Frame(name[1], kind, attrs._attrs, rules))
        self._data = []  # Start accumulating