| @@ -1,10 +0,0 @@ | |||
| Metadata-Version: 1.0 | |||
| Name: SOAPpy | |||
| Version: 0.12.0 | |||
| Summary: SOAP Services for Python | |||
| Home-page: http://pywebsvcs.sf.net/ | |||
| Author: Gregory Warnes | |||
| Author-email: Gregory.R.Warnes@Pfizer.com | |||
| License: UNKNOWN | |||
| Description: SOAPpy provides tools for building SOAP clients and servers. For more information see http://pywebsvcs.sf.net/ | |||
| Platform: UNKNOWN | |||
| @@ -1,3 +1,22 @@ | |||
| Release 0.12.1 of SOAPpy | |||
| ------------------------ | |||
| - Forked intially from https://github.com/pelletier/SOAPpy | |||
| - main interresting enhancements grabbed: | |||
| - from __future__ imports must occur at the beginning of the file | |||
| - try install requires | |||
| - Grabbed others changeset from | |||
| - Depend directly on wstools not to bundle a duplicated version. | |||
| - Grabbed from original svn: | |||
| - rpm spec file | |||
| - tools/ | |||
| - zope/ | |||
| - bid/ | |||
| - .cvsignore files | |||
| - | |||
| - Make it proper packaged, specially toward setuptools. | |||
| Release 0.12.0 of SOAPpy | |||
| ------------------------ | |||
| @@ -0,0 +1,91 @@ | |||
| Summary: SOAPpy | |||
| Name: SOAPpy | |||
| Version: 0.9.7 | |||
| Release: 2 | |||
| License: Copyright (c) 2001, Cayce Ullman. | |||
| Group: Productivity/Networking/Web/Applications | |||
| Source: SOAPpy-%{version}.tgz | |||
| Requires: python >= 2.2 | |||
| BuildArch: noarch | |||
| AutoReq: no | |||
| Packager: Antonio Beamud Montero <antonio.beamud@wanadoo.es> | |||
| %description | |||
| SOAP implementation by Cayce Ullman and Brian Matthews. | |||
| %prep | |||
| %setup SOAPpy-%{version} | |||
| %build | |||
| %install | |||
| mkdir -p /usr/share/doc/SOAPpy/bid | |||
| cp -a bid/* /usr/share/doc/SOAPpy/bid | |||
| mkdir -p /usr/share/doc/SOAPpy/tests | |||
| cp -a tests/* /usr/share/doc/SOAPpy/tests | |||
| cp -a TCtest.py /usr/share/doc/SOAPpy/tests | |||
| mkdir -p /usr/share/doc/SOAPpy/contrib | |||
| cp contrib/* /usr/share/doc/SOAPpy/contrib/ | |||
| cp docs/* /usr/share/doc/SOAPpy/ | |||
| mkdir -p /usr/share/doc/SOAPpy/tools | |||
| cp -a tools/* /usr/share/doc/SOAPpy/tools | |||
| cp README /usr/share/doc/SOAPpy/ | |||
| cp echoServer.py /usr/share/doc/SOAPpy/ | |||
| cp speedTest.py /usr/share/doc/SOAPpy/ | |||
| cp CHANGELOG /usr/share/doc/SOAPpy/ | |||
| cp SOAPtest.py /usr/share/doc/SOAPpy/tests | |||
| cp excelTest.py /usr/share/doc/SOAPpy/ | |||
| cp echoClient.py /usr/share/doc/SOAPpy/ | |||
| mkdir -p /usr/share/doc/SOAPpy/validate | |||
| cp -a validate/* /usr/share/doc/SOAPpy/validate | |||
| cp SOAP.py /usr/lib/python/site-packages/ | |||
| %clean | |||
| %pre | |||
| %post | |||
| %preun | |||
| %postun | |||
| %files | |||
| %defattr(-,root,root) | |||
| /usr/share/doc/SOAPpy/bid/monitorClient.py | |||
| /usr/share/doc/SOAPpy/bid/inventoryServer.py | |||
| /usr/share/doc/SOAPpy/bid/inventory.servers | |||
| /usr/share/doc/SOAPpy/bid/inventoryClient.py | |||
| /usr/share/doc/SOAPpy/tests/TCtest.py | |||
| /usr/share/doc/SOAPpy/simpleTypes.txt | |||
| /usr/share/doc/SOAPpy/attrs.txt | |||
| /usr/share/doc/SOAPpy/quickstart.txt | |||
| /usr/share/doc/SOAPpy/complexTypes.txt | |||
| /usr/share/doc/SOAPpy/contrib/soap_cli.py | |||
| /usr/share/doc/SOAPpy/contrib/soap_handler.py | |||
| /usr/share/doc/SOAPpy/tests/cardServer.py | |||
| /usr/share/doc/SOAPpy/tests/guidTest.py | |||
| /usr/share/doc/SOAPpy/tests/alanbushTest.py | |||
| /usr/share/doc/SOAPpy/tests/newsTest.py | |||
| /usr/share/doc/SOAPpy/tests/weatherTest.py | |||
| /usr/share/doc/SOAPpy/tests/fortuneTest.py | |||
| /usr/share/doc/SOAPpy/tests/cardClient.py | |||
| /usr/share/doc/SOAPpy/tests/quoteTest.py | |||
| /usr/share/doc/SOAPpy/tests/storageTest.py | |||
| /usr/share/doc/SOAPpy/tests/wordFindTest.py | |||
| /usr/share/doc/SOAPpy/tests/itimeTest.py | |||
| /usr/share/doc/SOAPpy/tests/whoisTest.py | |||
| /usr/share/doc/SOAPpy/tests/translateTest.py | |||
| /usr/share/doc/SOAPpy/tools/interop2html.py | |||
| /usr/share/doc/SOAPpy/README | |||
| /usr/share/doc/SOAPpy/echoServer.py | |||
| /usr/share/doc/SOAPpy/speedTest.py | |||
| /usr/share/doc/SOAPpy/CHANGELOG | |||
| /usr/share/doc/SOAPpy/tests/SOAPtest.py | |||
| /usr/share/doc/SOAPpy/excelTest.py | |||
| /usr/share/doc/SOAPpy/echoClient.py | |||
| /usr/share/doc/SOAPpy/validate/silab.servers | |||
| /usr/share/doc/SOAPpy/validate/silabserver.py | |||
| /usr/share/doc/SOAPpy/validate/server.pem | |||
| /usr/share/doc/SOAPpy/validate/silabclient.py | |||
| /usr/share/doc/SOAPpy/validate/soapware.py | |||
| /usr/lib/python2.2/site-packages/SOAP.py | |||
| @@ -1,125 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """Namespace module, so you don't need PyXML | |||
| """ | |||
| try: | |||
| from xml.ns import SOAP, SCHEMA, WSDL, XMLNS, DSIG, ENCRYPTION | |||
| DSIG.C14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" | |||
| except: | |||
| class SOAP: | |||
| ENV = "http://schemas.xmlsoap.org/soap/envelope/" | |||
| ENC = "http://schemas.xmlsoap.org/soap/encoding/" | |||
| ACTOR_NEXT = "http://schemas.xmlsoap.org/soap/actor/next" | |||
| class SCHEMA: | |||
| XSD1 = "http://www.w3.org/1999/XMLSchema" | |||
| XSD2 = "http://www.w3.org/2000/10/XMLSchema" | |||
| XSD3 = "http://www.w3.org/2001/XMLSchema" | |||
| XSD_LIST = [ XSD1, XSD2, XSD3 ] | |||
| XSI1 = "http://www.w3.org/1999/XMLSchema-instance" | |||
| XSI2 = "http://www.w3.org/2000/10/XMLSchema-instance" | |||
| XSI3 = "http://www.w3.org/2001/XMLSchema-instance" | |||
| XSI_LIST = [ XSI1, XSI2, XSI3 ] | |||
| BASE = XSD3 | |||
| class WSDL: | |||
| BASE = "http://schemas.xmlsoap.org/wsdl/" | |||
| BIND_HTTP = "http://schemas.xmlsoap.org/wsdl/http/" | |||
| BIND_MIME = "http://schemas.xmlsoap.org/wsdl/mime/" | |||
| BIND_SOAP = "http://schemas.xmlsoap.org/wsdl/soap/" | |||
| BIND_SOAP12 = "http://schemas.xmlsoap.org/wsdl/soap12/" | |||
| class XMLNS: | |||
| BASE = "http://www.w3.org/2000/xmlns/" | |||
| XML = "http://www.w3.org/XML/1998/namespace" | |||
| HTML = "http://www.w3.org/TR/REC-html40" | |||
| class DSIG: | |||
| BASE = "http://www.w3.org/2000/09/xmldsig#" | |||
| C14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" | |||
| C14N_COMM = "http://www.w3.org/TR/2000/CR-xml-c14n-20010315#WithComments" | |||
| C14N_EXCL = "http://www.w3.org/2001/10/xml-exc-c14n#" | |||
| DIGEST_MD2 = "http://www.w3.org/2000/09/xmldsig#md2" | |||
| DIGEST_MD5 = "http://www.w3.org/2000/09/xmldsig#md5" | |||
| DIGEST_SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1" | |||
| ENC_BASE64 = "http://www.w3.org/2000/09/xmldsig#base64" | |||
| ENVELOPED = "http://www.w3.org/2000/09/xmldsig#enveloped-signature" | |||
| HMAC_SHA1 = "http://www.w3.org/2000/09/xmldsig#hmac-sha1" | |||
| SIG_DSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#dsa-sha1" | |||
| SIG_RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1" | |||
| XPATH = "http://www.w3.org/TR/1999/REC-xpath-19991116" | |||
| XSLT = "http://www.w3.org/TR/1999/REC-xslt-19991116" | |||
| class ENCRYPTION: | |||
| BASE = "http://www.w3.org/2001/04/xmlenc#" | |||
| BLOCK_3DES = "http://www.w3.org/2001/04/xmlenc#des-cbc" | |||
| BLOCK_AES128 = "http://www.w3.org/2001/04/xmlenc#aes128-cbc" | |||
| BLOCK_AES192 = "http://www.w3.org/2001/04/xmlenc#aes192-cbc" | |||
| BLOCK_AES256 = "http://www.w3.org/2001/04/xmlenc#aes256-cbc" | |||
| DIGEST_RIPEMD160 = "http://www.w3.org/2001/04/xmlenc#ripemd160" | |||
| DIGEST_SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256" | |||
| DIGEST_SHA512 = "http://www.w3.org/2001/04/xmlenc#sha512" | |||
| KA_DH = "http://www.w3.org/2001/04/xmlenc#dh" | |||
| KT_RSA_1_5 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5" | |||
| KT_RSA_OAEP = "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" | |||
| STREAM_ARCFOUR = "http://www.w3.org/2001/04/xmlenc#arcfour" | |||
| WRAP_3DES = "http://www.w3.org/2001/04/xmlenc#kw-3des" | |||
| WRAP_AES128 = "http://www.w3.org/2001/04/xmlenc#kw-aes128" | |||
| WRAP_AES192 = "http://www.w3.org/2001/04/xmlenc#kw-aes192" | |||
| WRAP_AES256 = "http://www.w3.org/2001/04/xmlenc#kw-aes256" | |||
| class OASIS: | |||
| '''URLs for Oasis specifications | |||
| ''' | |||
| WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" | |||
| UTILITY = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" | |||
| LIFETIME = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.xsd" | |||
| PROPERTIES = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd" | |||
| BASENOTIFICATION = "http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.xsd" | |||
| BASEFAULTS = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-BaseFaults-1.2-draft-01.xsd" | |||
| class WSSE: | |||
| BASE = "http://schemas.xmlsoap.org/ws/2002/04/secext" | |||
| TRUST = "http://schemas.xmlsoap.org/ws/2004/04/trust" | |||
| class WSU: | |||
| BASE = "http://schemas.xmlsoap.org/ws/2002/04/utility" | |||
| UTILITY = "http://schemas.xmlsoap.org/ws/2002/07/utility" | |||
| class WSR: | |||
| PROPERTIES = "http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties" | |||
| LIFETIME = "http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceLifetime" | |||
| class WSA200408: | |||
| ADDRESS = "http://schemas.xmlsoap.org/ws/2004/08/addressing" | |||
| ANONYMOUS = "%s/role/anonymous" %ADDRESS | |||
| FAULT = "%s/fault" %ADDRESS | |||
| WSA = WSA200408 | |||
| class WSA200403: | |||
| ADDRESS = "http://schemas.xmlsoap.org/ws/2004/03/addressing" | |||
| ANONYMOUS = "%s/role/anonymous" %ADDRESS | |||
| FAULT = "%s/fault" %ADDRESS | |||
| class WSA200303: | |||
| ADDRESS = "http://schemas.xmlsoap.org/ws/2003/03/addressing" | |||
| ANONYMOUS = "%s/role/anonymous" %ADDRESS | |||
| FAULT = None | |||
| class WSP: | |||
| POLICY = "http://schemas.xmlsoap.org/ws/2002/12/policy" | |||
| class BEA: | |||
| SECCONV = "http://schemas.xmlsoap.org/ws/2004/04/sc" | |||
| class GLOBUS: | |||
| SECCONV = "http://wsrf.globus.org/core/2004/07/security/secconv" | |||
| CORE = "http://www.globus.org/namespaces/2004/06/core" | |||
| SIG = "http://www.globus.org/2002/04/xmlenc#gssapi-sign" | |||
| ZSI_SCHEMA_URI = 'http://www.zolera.com/schemas/ZSI/' | |||
| @@ -1,179 +0,0 @@ | |||
| """Based on code from timeout_socket.py, with some tweaks for compatibility. | |||
| These tweaks should really be rolled back into timeout_socket, but it's | |||
| not totally clear who is maintaining it at this point. In the meantime, | |||
| we'll use a different module name for our tweaked version to avoid any | |||
| confusion. | |||
| The original timeout_socket is by: | |||
| Scott Cotton <scott@chronis.pobox.com> | |||
| Lloyd Zusman <ljz@asfast.com> | |||
| Phil Mayes <pmayes@olivebr.com> | |||
| Piers Lauder <piers@cs.su.oz.au> | |||
| Radovan Garabik <garabik@melkor.dnp.fmph.uniba.sk> | |||
| """ | |||
| ident = "$Id: TimeoutSocket.py,v 1.2 2003/05/20 21:10:12 warnes Exp $" | |||
| import string, socket, select, errno | |||
| WSAEINVAL = getattr(errno, 'WSAEINVAL', 10022) | |||
| class TimeoutSocket: | |||
| """A socket imposter that supports timeout limits.""" | |||
| def __init__(self, timeout=20, sock=None): | |||
| self.timeout = float(timeout) | |||
| self.inbuf = '' | |||
| if sock is None: | |||
| sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||
| self.sock = sock | |||
| self.sock.setblocking(0) | |||
| self._rbuf = '' | |||
| self._wbuf = '' | |||
| def __getattr__(self, name): | |||
| # Delegate to real socket attributes. | |||
| return getattr(self.sock, name) | |||
| def connect(self, *addr): | |||
| timeout = self.timeout | |||
| sock = self.sock | |||
| try: | |||
| # Non-blocking mode | |||
| sock.setblocking(0) | |||
| apply(sock.connect, addr) | |||
| sock.setblocking(timeout != 0) | |||
| return 1 | |||
| except socket.error,why: | |||
| if not timeout: | |||
| raise | |||
| sock.setblocking(1) | |||
| if len(why.args) == 1: | |||
| code = 0 | |||
| else: | |||
| code, why = why | |||
| if code not in ( | |||
| errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK | |||
| ): | |||
| raise | |||
| r,w,e = select.select([],[sock],[],timeout) | |||
| if w: | |||
| try: | |||
| apply(sock.connect, addr) | |||
| return 1 | |||
| except socket.error,why: | |||
| if len(why.args) == 1: | |||
| code = 0 | |||
| else: | |||
| code, why = why | |||
| if code in (errno.EISCONN, WSAEINVAL): | |||
| return 1 | |||
| raise | |||
| raise TimeoutError('socket connect() timeout.') | |||
| def send(self, data, flags=0): | |||
| total = len(data) | |||
| next = 0 | |||
| while 1: | |||
| r, w, e = select.select([],[self.sock], [], self.timeout) | |||
| if w: | |||
| buff = data[next:next + 8192] | |||
| sent = self.sock.send(buff, flags) | |||
| next = next + sent | |||
| if next == total: | |||
| return total | |||
| continue | |||
| raise TimeoutError('socket send() timeout.') | |||
| def recv(self, amt, flags=0): | |||
| if select.select([self.sock], [], [], self.timeout)[0]: | |||
| return self.sock.recv(amt, flags) | |||
| raise TimeoutError('socket recv() timeout.') | |||
| buffsize = 4096 | |||
| handles = 1 | |||
| def makefile(self, mode="r", buffsize=-1): | |||
| self.handles = self.handles + 1 | |||
| self.mode = mode | |||
| return self | |||
| def close(self): | |||
| self.handles = self.handles - 1 | |||
| if self.handles == 0 and self.sock.fileno() >= 0: | |||
| self.sock.close() | |||
| def read(self, n=-1): | |||
| if not isinstance(n, type(1)): | |||
| n = -1 | |||
| if n >= 0: | |||
| k = len(self._rbuf) | |||
| if n <= k: | |||
| data = self._rbuf[:n] | |||
| self._rbuf = self._rbuf[n:] | |||
| return data | |||
| n = n - k | |||
| L = [self._rbuf] | |||
| self._rbuf = "" | |||
| while n > 0: | |||
| new = self.recv(max(n, self.buffsize)) | |||
| if not new: break | |||
| k = len(new) | |||
| if k > n: | |||
| L.append(new[:n]) | |||
| self._rbuf = new[n:] | |||
| break | |||
| L.append(new) | |||
| n = n - k | |||
| return "".join(L) | |||
| k = max(4096, self.buffsize) | |||
| L = [self._rbuf] | |||
| self._rbuf = "" | |||
| while 1: | |||
| new = self.recv(k) | |||
| if not new: break | |||
| L.append(new) | |||
| k = min(k*2, 1024**2) | |||
| return "".join(L) | |||
| def readline(self, limit=-1): | |||
| data = "" | |||
| i = self._rbuf.find('\n') | |||
| while i < 0 and not (0 < limit <= len(self._rbuf)): | |||
| new = self.recv(self.buffsize) | |||
| if not new: break | |||
| i = new.find('\n') | |||
| if i >= 0: i = i + len(self._rbuf) | |||
| self._rbuf = self._rbuf + new | |||
| if i < 0: i = len(self._rbuf) | |||
| else: i = i+1 | |||
| if 0 <= limit < len(self._rbuf): i = limit | |||
| data, self._rbuf = self._rbuf[:i], self._rbuf[i:] | |||
| return data | |||
| def readlines(self, sizehint = 0): | |||
| total = 0 | |||
| list = [] | |||
| while 1: | |||
| line = self.readline() | |||
| if not line: break | |||
| list.append(line) | |||
| total += len(line) | |||
| if sizehint and total >= sizehint: | |||
| break | |||
| return list | |||
| def writelines(self, list): | |||
| self.send(''.join(list)) | |||
| def write(self, data): | |||
| self.send(data) | |||
| def flush(self): | |||
| pass | |||
| class TimeoutError(Exception): | |||
| pass | |||
| @@ -1,99 +0,0 @@ | |||
| """ | |||
| A more or less complete user-defined wrapper around tuple objects. | |||
| Adapted version of the standard library's UserList. | |||
| Taken from Stefan Schwarzer's ftputil library, available at | |||
| <http://www.ndh.net/home/sschwarzer/python/python_software.html>, and used under this license: | |||
| Copyright (C) 1999, Stefan Schwarzer | |||
| All rights reserved. | |||
| Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions are | |||
| met: | |||
| - Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | |||
| - Redistributions in binary form must reproduce the above copyright | |||
| notice, this list of conditions and the following disclaimer in the | |||
| documentation and/or other materials provided with the distribution. | |||
| - Neither the name of the above author nor the names of the | |||
| contributors to the software may be used to endorse or promote | |||
| products derived from this software without specific prior written | |||
| permission. | |||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR | |||
| CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| """ | |||
| # $Id: UserTuple.py,v 1.1 2003/07/21 14:18:54 warnes Exp $ | |||
| #XXX tuple instances (in Python 2.2) contain also: | |||
| # __class__, __delattr__, __getattribute__, __hash__, __new__, | |||
| # __reduce__, __setattr__, __str__ | |||
| # What about these? | |||
| class UserTuple: | |||
| def __init__(self, inittuple=None): | |||
| self.data = () | |||
| if inittuple is not None: | |||
| # XXX should this accept an arbitrary sequence? | |||
| if type(inittuple) == type(self.data): | |||
| self.data = inittuple | |||
| elif isinstance(inittuple, UserTuple): | |||
| # this results in | |||
| # self.data is inittuple.data | |||
| # but that's ok for tuples because they are | |||
| # immutable. (Builtin tuples behave the same.) | |||
| self.data = inittuple.data[:] | |||
| else: | |||
| # the same applies here; (t is tuple(t)) == 1 | |||
| self.data = tuple(inittuple) | |||
| def __repr__(self): return repr(self.data) | |||
| def __lt__(self, other): return self.data < self.__cast(other) | |||
| def __le__(self, other): return self.data <= self.__cast(other) | |||
| def __eq__(self, other): return self.data == self.__cast(other) | |||
| def __ne__(self, other): return self.data != self.__cast(other) | |||
| def __gt__(self, other): return self.data > self.__cast(other) | |||
| def __ge__(self, other): return self.data >= self.__cast(other) | |||
| def __cast(self, other): | |||
| if isinstance(other, UserTuple): return other.data | |||
| else: return other | |||
| def __cmp__(self, other): | |||
| return cmp(self.data, self.__cast(other)) | |||
| def __contains__(self, item): return item in self.data | |||
| def __len__(self): return len(self.data) | |||
| def __getitem__(self, i): return self.data[i] | |||
| def __getslice__(self, i, j): | |||
| i = max(i, 0); j = max(j, 0) | |||
| return self.__class__(self.data[i:j]) | |||
| def __add__(self, other): | |||
| if isinstance(other, UserTuple): | |||
| return self.__class__(self.data + other.data) | |||
| elif isinstance(other, type(self.data)): | |||
| return self.__class__(self.data + other) | |||
| else: | |||
| return self.__class__(self.data + tuple(other)) | |||
| # dir( () ) contains no __radd__ (at least in Python 2.2) | |||
| def __mul__(self, n): | |||
| return self.__class__(self.data*n) | |||
| __rmul__ = __mul__ | |||
| @@ -1,90 +0,0 @@ | |||
| """Translate strings to and from SOAP 1.2 XML name encoding | |||
| Implements rules for mapping application defined name to XML names | |||
| specified by the w3 SOAP working group for SOAP version 1.2 in | |||
| Appendix A of "SOAP Version 1.2 Part 2: Adjuncts", W3C Working Draft | |||
| 17, December 2001, <http://www.w3.org/TR/soap12-part2/#namemap> | |||
| Also see <http://www.w3.org/2000/xp/Group/xmlp-issues>. | |||
| Author: Gregory R. Warnes <Gregory.R.Warnes@Pfizer.com> | |||
| Date:: 2002-04-25 | |||
| Version 0.9.0 | |||
| """ | |||
| ident = "$Id: XMLname.py,v 1.4 2005/02/16 14:45:37 warnes Exp $" | |||
| from re import * | |||
| def _NCNameChar(x): | |||
| return x.isalpha() or x.isdigit() or x=="." or x=='-' or x=="_" | |||
| def _NCNameStartChar(x): | |||
| return x.isalpha() or x=="_" | |||
| def _toUnicodeHex(x): | |||
| hexval = hex(ord(x[0]))[2:] | |||
| hexlen = len(hexval) | |||
| # Make hexval have either 4 or 8 digits by prepending 0's | |||
| if (hexlen==1): hexval = "000" + hexval | |||
| elif (hexlen==2): hexval = "00" + hexval | |||
| elif (hexlen==3): hexval = "0" + hexval | |||
| elif (hexlen==4): hexval = "" + hexval | |||
| elif (hexlen==5): hexval = "000" + hexval | |||
| elif (hexlen==6): hexval = "00" + hexval | |||
| elif (hexlen==7): hexval = "0" + hexval | |||
| elif (hexlen==8): hexval = "" + hexval | |||
| else: raise Exception, "Illegal Value returned from hex(ord(x))" | |||
| return "_x"+ hexval + "_" | |||
| def _fromUnicodeHex(x): | |||
| return eval( r'u"\u'+x[2:-1]+'"' ) | |||
| def toXMLname(string): | |||
| """Convert string to a XML name.""" | |||
| if string.find(':') != -1 : | |||
| (prefix, localname) = string.split(':',1) | |||
| else: | |||
| prefix = None | |||
| localname = string | |||
| T = unicode(localname) | |||
| N = len(localname) | |||
| X = []; | |||
| for i in range(N) : | |||
| if i< N-1 and T[i]==u'_' and T[i+1]==u'x': | |||
| X.append(u'_x005F_') | |||
| elif i==0 and N >= 3 and \ | |||
| ( T[0]==u'x' or T[0]==u'X' ) and \ | |||
| ( T[1]==u'm' or T[1]==u'M' ) and \ | |||
| ( T[2]==u'l' or T[2]==u'L' ): | |||
| X.append(u'_xFFFF_' + T[0]) | |||
| elif (not _NCNameChar(T[i])) or (i==0 and not _NCNameStartChar(T[i])): | |||
| X.append(_toUnicodeHex(T[i])) | |||
| else: | |||
| X.append(T[i]) | |||
| if prefix: | |||
| return "%s:%s" % (prefix, u''.join(X)) | |||
| return u''.join(X) | |||
| def fromXMLname(string): | |||
| """Convert XML name to unicode string.""" | |||
| retval = sub(r'_xFFFF_','', string ) | |||
| def fun( matchobj ): | |||
| return _fromUnicodeHex( matchobj.group(0) ) | |||
| retval = sub(r'_x[0-9A-Za-z]+_', fun, retval ) | |||
| return retval | |||
| @@ -1,9 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """WSDL parsing services package for Web Services for Python.""" | |||
| ident = "$Id: __init__.py,v 1.11 2004/12/07 15:54:53 blunck2 Exp $" | |||
| import WSDLTools | |||
| import XMLname | |||
| import logging | |||
| @@ -1,536 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """Compatibility module, imported by ZSI if you don't have PyXML 0.7. | |||
| No copyright violations -- we're only using parts of PyXML that we | |||
| wrote. | |||
| """ | |||
| _copyright = '''ZSI: Zolera Soap Infrastructure. | |||
| Copyright 2001, Zolera Systems, Inc. All Rights Reserved. | |||
| Copyright 2002-2003, Rich Salz. All Rights Reserved. | |||
| Permission is hereby granted, free of charge, to any person obtaining a | |||
| copy of this software and associated documentation files (the "Software"), | |||
| to deal in the Software without restriction, including without limitation | |||
| the rights to use, copy, modify, merge, publish, distribute, and/or | |||
| sell copies of the Software, and to permit persons to whom the Software | |||
| is furnished to do so, provided that the above copyright notice(s) and | |||
| this permission notice appear in all copies of the Software and that | |||
| both the above copyright notice(s) and this permission notice appear in | |||
| supporting documentation. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT | |||
| OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS | |||
| INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT | |||
| OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | |||
| OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | |||
| OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE | |||
| OR PERFORMANCE OF THIS SOFTWARE. | |||
| Except as contained in this notice, the name of a copyright holder | |||
| shall not be used in advertising or otherwise to promote the sale, use | |||
| or other dealings in this Software without prior written authorization | |||
| of the copyright holder. | |||
| ''' | |||
| _copyright += "\n\nPortions are also: " | |||
| _copyright += '''Copyright 2001, Zolera Systems Inc. All Rights Reserved. | |||
| Copyright 2001, MIT. All Rights Reserved. | |||
| Distributed under the terms of: | |||
| Python 2.0 License or later. | |||
| http://www.python.org/2.0.1/license.html | |||
| or | |||
| W3C Software License | |||
| http://www.w3.org/Consortium/Legal/copyright-software-19980720 | |||
| ''' | |||
| from xml.dom import Node | |||
| from Namespaces import XMLNS | |||
| import cStringIO as StringIO | |||
| try: | |||
| from xml.dom.ext import c14n | |||
| except ImportError, ex: | |||
| _implementation2 = None | |||
| _attrs = lambda E: (E.attributes and E.attributes.values()) or [] | |||
| _children = lambda E: E.childNodes or [] | |||
| else: | |||
| class _implementation2(c14n._implementation): | |||
| """Patch for exclusive c14n | |||
| """ | |||
| def __init__(self, node, write, **kw): | |||
| self.unsuppressedPrefixes = kw.get('unsuppressedPrefixes') | |||
| self._exclusive = None | |||
| if node.nodeType == Node.ELEMENT_NODE: | |||
| if not c14n._inclusive(self): | |||
| self._exclusive = self._inherit_context(node) | |||
| c14n._implementation.__init__(self, node, write, **kw) | |||
| def _do_element(self, node, initial_other_attrs = []): | |||
| """Patch for the xml.dom.ext.c14n implemenation _do_element method. | |||
| This fixes a problem with sorting of namespaces. | |||
| """ | |||
| # Get state (from the stack) make local copies. | |||
| # ns_parent -- NS declarations in parent | |||
| # ns_rendered -- NS nodes rendered by ancestors | |||
| # ns_local -- NS declarations relevant to this element | |||
| # xml_attrs -- Attributes in XML namespace from parent | |||
| # xml_attrs_local -- Local attributes in XML namespace. | |||
| ns_parent, ns_rendered, xml_attrs = \ | |||
| self.state[0], self.state[1].copy(), self.state[2].copy() #0422 | |||
| ns_local = ns_parent.copy() | |||
| xml_attrs_local = {} | |||
| # Divide attributes into NS, XML, and others. | |||
| #other_attrs = initial_other_attrs[:] | |||
| other_attrs = [] | |||
| sort_these_attrs = initial_other_attrs[:] | |||
| in_subset = c14n._in_subset(self.subset, node) | |||
| #for a in _attrs(node): | |||
| sort_these_attrs +=c14n._attrs(node) | |||
| for a in sort_these_attrs: | |||
| if a.namespaceURI == c14n.XMLNS.BASE: | |||
| n = a.nodeName | |||
| if n == "xmlns:": n = "xmlns" # DOM bug workaround | |||
| ns_local[n] = a.nodeValue | |||
| elif a.namespaceURI == c14n.XMLNS.XML: | |||
| if c14n._inclusive(self) or (in_subset and c14n._in_subset(self.subset, a)): #020925 Test to see if attribute node in subset | |||
| xml_attrs_local[a.nodeName] = a #0426 | |||
| else: | |||
| if c14n._in_subset(self.subset, a): #020925 Test to see if attribute node in subset | |||
| other_attrs.append(a) | |||
| #add local xml:foo attributes to ancestor's xml:foo attributes | |||
| xml_attrs.update(xml_attrs_local) | |||
| # Render the node | |||
| W, name = self.write, None | |||
| if in_subset: | |||
| name = node.nodeName | |||
| W('<') | |||
| W(name) | |||
| # Create list of NS attributes to render. | |||
| ns_to_render = [] | |||
| for n,v in ns_local.items(): | |||
| # If default namespace is XMLNS.BASE or empty, | |||
| # and if an ancestor was the same | |||
| if n == "xmlns" and v in [ c14n.XMLNS.BASE, '' ] \ | |||
| and ns_rendered.get('xmlns') in [ c14n.XMLNS.BASE, '', None ]: | |||
| continue | |||
| # "omit namespace node with local name xml, which defines | |||
| # the xml prefix, if its string value is | |||
| # http://www.w3.org/XML/1998/namespace." | |||
| if n in ["xmlns:xml", "xml"] \ | |||
| and v in [ 'http://www.w3.org/XML/1998/namespace' ]: | |||
| continue | |||
| # If not previously rendered | |||
| # and it's inclusive or utilized | |||
| if (n,v) not in ns_rendered.items() \ | |||
| and (c14n._inclusive(self) or \ | |||
| c14n._utilized(n, node, other_attrs, self.unsuppressedPrefixes)): | |||
| ns_to_render.append((n, v)) | |||
| ##################################### | |||
| # JRB | |||
| ##################################### | |||
| if not c14n._inclusive(self): | |||
| if node.prefix is None: | |||
| look_for = [('xmlns', node.namespaceURI),] | |||
| else: | |||
| look_for = [('xmlns:%s' %node.prefix, node.namespaceURI),] | |||
| for a in c14n._attrs(node): | |||
| if a.namespaceURI != XMLNS.BASE: | |||
| #print "ATTRIBUTE: ", (a.namespaceURI, a.prefix) | |||
| if a.prefix: | |||
| #print "APREFIX: ", a.prefix | |||
| look_for.append(('xmlns:%s' %a.prefix, a.namespaceURI)) | |||
| for key,namespaceURI in look_for: | |||
| if ns_rendered.has_key(key): | |||
| if ns_rendered[key] == namespaceURI: | |||
| # Dont write out | |||
| pass | |||
| else: | |||
| #ns_to_render += [(key, namespaceURI)] | |||
| pass | |||
| elif (key,namespaceURI) in ns_to_render: | |||
| # Dont write out | |||
| pass | |||
| else: | |||
| # Unique write out, rewrite to render | |||
| ns_local[key] = namespaceURI | |||
| for a in self._exclusive: | |||
| if a.nodeName == key: | |||
| #self._do_attr(a.nodeName, a.value) | |||
| #ns_rendered[key] = namespaceURI | |||
| #break | |||
| ns_to_render += [(a.nodeName, a.value)] | |||
| break | |||
| elif key is None and a.nodeName == 'xmlns': | |||
| #print "DEFAULT: ", (a.nodeName, a.value) | |||
| ns_to_render += [(a.nodeName, a.value)] | |||
| break | |||
| #print "KEY: ", key | |||
| else: | |||
| #print "Look for: ", look_for | |||
| #print "NS_TO_RENDER: ", ns_to_render | |||
| #print "EXCLUSIVE NS: ", map(lambda f: (f.nodeName,f.value),self._exclusive) | |||
| raise RuntimeError, \ | |||
| 'can not find namespace (%s="%s") for exclusive canonicalization'\ | |||
| %(key, namespaceURI) | |||
| ##################################### | |||
| # Sort and render the ns, marking what was rendered. | |||
| ns_to_render.sort(c14n._sorter_ns) | |||
| for n,v in ns_to_render: | |||
| #XXX JRB, getting 'xmlns,None' here when xmlns='' | |||
| if v: self._do_attr(n, v) | |||
| else: | |||
| v = '' | |||
| self._do_attr(n, v) | |||
| ns_rendered[n]=v #0417 | |||
| # If exclusive or the parent is in the subset, add the local xml attributes | |||
| # Else, add all local and ancestor xml attributes | |||
| # Sort and render the attributes. | |||
| if not c14n._inclusive(self) or c14n._in_subset(self.subset,node.parentNode): #0426 | |||
| other_attrs.extend(xml_attrs_local.values()) | |||
| else: | |||
| other_attrs.extend(xml_attrs.values()) | |||
| #print "OTHER: ", other_attrs | |||
| other_attrs.sort(c14n._sorter) | |||
| for a in other_attrs: | |||
| self._do_attr(a.nodeName, a.value) | |||
| W('>') | |||
| # Push state, recurse, pop state. | |||
| state, self.state = self.state, (ns_local, ns_rendered, xml_attrs) | |||
| for c in c14n._children(node): | |||
| c14n._implementation.handlers[c.nodeType](self, c) | |||
| self.state = state | |||
| if name: W('</%s>' % name) | |||
| c14n._implementation.handlers[c14n.Node.ELEMENT_NODE] = _do_element | |||
| _IN_XML_NS = lambda n: n.namespaceURI == XMLNS.XML | |||
| # Does a document/PI has lesser/greater document order than the | |||
| # first element? | |||
| _LesserElement, _Element, _GreaterElement = range(3) | |||
| def _sorter(n1,n2): | |||
| '''_sorter(n1,n2) -> int | |||
| Sorting predicate for non-NS attributes.''' | |||
| i = cmp(n1.namespaceURI, n2.namespaceURI) | |||
| if i: return i | |||
| return cmp(n1.localName, n2.localName) | |||
| def _sorter_ns(n1,n2): | |||
| '''_sorter_ns((n,v),(n,v)) -> int | |||
| "(an empty namespace URI is lexicographically least)."''' | |||
| if n1[0] == 'xmlns': return -1 | |||
| if n2[0] == 'xmlns': return 1 | |||
| return cmp(n1[0], n2[0]) | |||
| def _utilized(n, node, other_attrs, unsuppressedPrefixes): | |||
| '''_utilized(n, node, other_attrs, unsuppressedPrefixes) -> boolean | |||
| Return true if that nodespace is utilized within the node''' | |||
| if n.startswith('xmlns:'): | |||
| n = n[6:] | |||
| elif n.startswith('xmlns'): | |||
| n = n[5:] | |||
| if n == node.prefix or n in unsuppressedPrefixes: return 1 | |||
| for attr in other_attrs: | |||
| if n == attr.prefix: return 1 | |||
| return 0 | |||
| _in_subset = lambda subset, node: not subset or node in subset | |||
| # | |||
| # JRB. Currently there is a bug in do_element, but since the underlying | |||
| # Data Structures in c14n have changed I can't just apply the | |||
| # _implementation2 patch above. But this will work OK for most uses, | |||
| # just not XML Signatures. | |||
| # | |||
| class _implementation: | |||
| '''Implementation class for C14N. This accompanies a node during it's | |||
| processing and includes the parameters and processing state.''' | |||
| # Handler for each node type; populated during module instantiation. | |||
| handlers = {} | |||
| def __init__(self, node, write, **kw): | |||
| '''Create and run the implementation.''' | |||
| self.write = write | |||
| self.subset = kw.get('subset') | |||
| if self.subset: | |||
| self.comments = kw.get('comments', 1) | |||
| else: | |||
| self.comments = kw.get('comments', 0) | |||
| self.unsuppressedPrefixes = kw.get('unsuppressedPrefixes') | |||
| nsdict = kw.get('nsdict', { 'xml': XMLNS.XML, 'xmlns': XMLNS.BASE }) | |||
| # Processing state. | |||
| self.state = (nsdict, ['xml'], []) | |||
| if node.nodeType == Node.DOCUMENT_NODE: | |||
| self._do_document(node) | |||
| elif node.nodeType == Node.ELEMENT_NODE: | |||
| self.documentOrder = _Element # At document element | |||
| if self.unsuppressedPrefixes is not None: | |||
| self._do_element(node) | |||
| else: | |||
| inherited = self._inherit_context(node) | |||
| self._do_element(node, inherited) | |||
| elif node.nodeType == Node.DOCUMENT_TYPE_NODE: | |||
| pass | |||
| else: | |||
| raise TypeError, str(node) | |||
| def _inherit_context(self, node): | |||
| '''_inherit_context(self, node) -> list | |||
| Scan ancestors of attribute and namespace context. Used only | |||
| for single element node canonicalization, not for subset | |||
| canonicalization.''' | |||
| # Collect the initial list of xml:foo attributes. | |||
| xmlattrs = filter(_IN_XML_NS, _attrs(node)) | |||
| # Walk up and get all xml:XXX attributes we inherit. | |||
| inherited, parent = [], node.parentNode | |||
| while parent and parent.nodeType == Node.ELEMENT_NODE: | |||
| for a in filter(_IN_XML_NS, _attrs(parent)): | |||
| n = a.localName | |||
| if n not in xmlattrs: | |||
| xmlattrs.append(n) | |||
| inherited.append(a) | |||
| parent = parent.parentNode | |||
| return inherited | |||
| def _do_document(self, node): | |||
| '''_do_document(self, node) -> None | |||
| Process a document node. documentOrder holds whether the document | |||
| element has been encountered such that PIs/comments can be written | |||
| as specified.''' | |||
| self.documentOrder = _LesserElement | |||
| for child in node.childNodes: | |||
| if child.nodeType == Node.ELEMENT_NODE: | |||
| self.documentOrder = _Element # At document element | |||
| self._do_element(child) | |||
| self.documentOrder = _GreaterElement # After document element | |||
| elif child.nodeType == Node.PROCESSING_INSTRUCTION_NODE: | |||
| self._do_pi(child) | |||
| elif child.nodeType == Node.COMMENT_NODE: | |||
| self._do_comment(child) | |||
| elif child.nodeType == Node.DOCUMENT_TYPE_NODE: | |||
| pass | |||
| else: | |||
| raise TypeError, str(child) | |||
| handlers[Node.DOCUMENT_NODE] = _do_document | |||
| def _do_text(self, node): | |||
| '''_do_text(self, node) -> None | |||
| Process a text or CDATA node. Render various special characters | |||
| as their C14N entity representations.''' | |||
| if not _in_subset(self.subset, node): return | |||
| s = node.data \ | |||
| .replace("&", "&") \ | |||
| .replace("<", "<") \ | |||
| .replace(">", ">") \ | |||
| .replace("\015", "
") | |||
| if s: self.write(s) | |||
| handlers[Node.TEXT_NODE] = _do_text | |||
| handlers[Node.CDATA_SECTION_NODE] = _do_text | |||
| def _do_pi(self, node): | |||
| '''_do_pi(self, node) -> None | |||
| Process a PI node. Render a leading or trailing #xA if the | |||
| document order of the PI is greater or lesser (respectively) | |||
| than the document element. | |||
| ''' | |||
| if not _in_subset(self.subset, node): return | |||
| W = self.write | |||
| if self.documentOrder == _GreaterElement: W('\n') | |||
| W('<?') | |||
| W(node.nodeName) | |||
| s = node.data | |||
| if s: | |||
| W(' ') | |||
| W(s) | |||
| W('?>') | |||
| if self.documentOrder == _LesserElement: W('\n') | |||
| handlers[Node.PROCESSING_INSTRUCTION_NODE] = _do_pi | |||
| def _do_comment(self, node): | |||
| '''_do_comment(self, node) -> None | |||
| Process a comment node. Render a leading or trailing #xA if the | |||
| document order of the comment is greater or lesser (respectively) | |||
| than the document element. | |||
| ''' | |||
| if not _in_subset(self.subset, node): return | |||
| if self.comments: | |||
| W = self.write | |||
| if self.documentOrder == _GreaterElement: W('\n') | |||
| W('<!--') | |||
| W(node.data) | |||
| W('-->') | |||
| if self.documentOrder == _LesserElement: W('\n') | |||
| handlers[Node.COMMENT_NODE] = _do_comment | |||
| def _do_attr(self, n, value): | |||
| ''''_do_attr(self, node) -> None | |||
| Process an attribute.''' | |||
| W = self.write | |||
| W(' ') | |||
| W(n) | |||
| W('="') | |||
| s = value \ | |||
| .replace("&", "&") \ | |||
| .replace("<", "<") \ | |||
| .replace('"', '"') \ | |||
| .replace('\011', '	') \ | |||
| .replace('\012', '
') \ | |||
| .replace('\015', '
') | |||
| W(s) | |||
| W('"') | |||
| def _do_element(self, node, initial_other_attrs = []): | |||
| '''_do_element(self, node, initial_other_attrs = []) -> None | |||
| Process an element (and its children).''' | |||
| # Get state (from the stack) make local copies. | |||
| # ns_parent -- NS declarations in parent | |||
| # ns_rendered -- NS nodes rendered by ancestors | |||
| # xml_attrs -- Attributes in XML namespace from parent | |||
| # ns_local -- NS declarations relevant to this element | |||
| ns_parent, ns_rendered, xml_attrs = \ | |||
| self.state[0], self.state[1][:], self.state[2][:] | |||
| ns_local = ns_parent.copy() | |||
| # Divide attributes into NS, XML, and others. | |||
| other_attrs = initial_other_attrs[:] | |||
| in_subset = _in_subset(self.subset, node) | |||
| for a in _attrs(node): | |||
| if a.namespaceURI == XMLNS.BASE: | |||
| n = a.nodeName | |||
| if n == "xmlns:": n = "xmlns" # DOM bug workaround | |||
| ns_local[n] = a.nodeValue | |||
| elif a.namespaceURI == XMLNS.XML: | |||
| if self.unsuppressedPrefixes is None or in_subset: | |||
| xml_attrs.append(a) | |||
| else: | |||
| other_attrs.append(a) | |||
| # Render the node | |||
| W, name = self.write, None | |||
| if in_subset: | |||
| name = node.nodeName | |||
| W('<') | |||
| W(name) | |||
| # Create list of NS attributes to render. | |||
| ns_to_render = [] | |||
| for n,v in ns_local.items(): | |||
| pval = ns_parent.get(n) | |||
| # If default namespace is XMLNS.BASE or empty, skip | |||
| if n == "xmlns" \ | |||
| and v in [ XMLNS.BASE, '' ] and pval in [ XMLNS.BASE, '' ]: | |||
| continue | |||
| # "omit namespace node with local name xml, which defines | |||
| # the xml prefix, if its string value is | |||
| # http://www.w3.org/XML/1998/namespace." | |||
| if n == "xmlns:xml" \ | |||
| and v in [ 'http://www.w3.org/XML/1998/namespace' ]: | |||
| continue | |||
| # If different from parent, or parent didn't render | |||
| # and if not exclusive, or this prefix is needed or | |||
| # not suppressed | |||
| if (v != pval or n not in ns_rendered) \ | |||
| and (self.unsuppressedPrefixes is None or \ | |||
| _utilized(n, node, other_attrs, self.unsuppressedPrefixes)): | |||
| ns_to_render.append((n, v)) | |||
| # Sort and render the ns, marking what was rendered. | |||
| ns_to_render.sort(_sorter_ns) | |||
| for n,v in ns_to_render: | |||
| self._do_attr(n, v) | |||
| ns_rendered.append(n) | |||
| # Add in the XML attributes (don't pass to children, since | |||
| # we're rendering them), sort, and render. | |||
| other_attrs.extend(xml_attrs) | |||
| xml_attrs = [] | |||
| other_attrs.sort(_sorter) | |||
| for a in other_attrs: | |||
| self._do_attr(a.nodeName, a.value) | |||
| W('>') | |||
| # Push state, recurse, pop state. | |||
| state, self.state = self.state, (ns_local, ns_rendered, xml_attrs) | |||
| for c in _children(node): | |||
| _implementation.handlers[c.nodeType](self, c) | |||
| self.state = state | |||
| if name: W('</%s>' % name) | |||
| handlers[Node.ELEMENT_NODE] = _do_element | |||
| def Canonicalize(node, output=None, **kw): | |||
| '''Canonicalize(node, output=None, **kw) -> UTF-8 | |||
| Canonicalize a DOM document/element node and all descendents. | |||
| Return the text; if output is specified then output.write will | |||
| be called to output the text and None will be returned | |||
| Keyword parameters: | |||
| nsdict: a dictionary of prefix:uri namespace entries | |||
| assumed to exist in the surrounding context | |||
| comments: keep comments if non-zero (default is 0) | |||
| subset: Canonical XML subsetting resulting from XPath | |||
| (default is []) | |||
| unsuppressedPrefixes: do exclusive C14N, and this specifies the | |||
| prefixes that should be inherited. | |||
| ''' | |||
| if output: | |||
| if _implementation2 is None: | |||
| _implementation(node, output.write, **kw) | |||
| else: | |||
| apply(_implementation2, (node, output.write), kw) | |||
| else: | |||
| s = StringIO.StringIO() | |||
| if _implementation2 is None: | |||
| _implementation(node, s.write, **kw) | |||
| else: | |||
| apply(_implementation2, (node, s.write), kw) | |||
| return s.getvalue() | |||
| if __name__ == '__main__': print _copyright | |||
| @@ -1,85 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """Logging""" | |||
| import sys | |||
| class ILogger: | |||
| '''Logger interface, by default this class | |||
| will be used and logging calls are no-ops. | |||
| ''' | |||
| level = 0 | |||
| def __init__(self, msg): | |||
| return | |||
| def warning(self, *args): | |||
| return | |||
| def debug(self, *args): | |||
| return | |||
| def error(self, *args): | |||
| return | |||
| def setLevel(cls, level): | |||
| cls.level = level | |||
| setLevel = classmethod(setLevel) | |||
| _LoggerClass = ILogger | |||
| class BasicLogger(ILogger): | |||
| def __init__(self, msg, out=sys.stdout): | |||
| self.msg, self.out = msg, out | |||
| def warning(self, msg, *args): | |||
| if self.level < 1: return | |||
| print >>self, self.WARN, self.msg, | |||
| print >>self, msg %args | |||
| WARN = 'WARN' | |||
| def debug(self, msg, *args): | |||
| if self.level < 2: return | |||
| print >>self, self.DEBUG, self.msg, | |||
| print >>self, msg %args | |||
| DEBUG = 'DEBUG' | |||
| def error(self, msg, *args): | |||
| print >>self, self.ERROR, self.msg, | |||
| print >>self, msg %args | |||
| ERROR = 'ERROR' | |||
| def write(self, *args): | |||
| '''Write convenience function; writes strings. | |||
| ''' | |||
| for s in args: self.out.write(s) | |||
| def setBasicLogger(): | |||
| '''Use Basic Logger. | |||
| ''' | |||
| setLoggerClass(BasicLogger) | |||
| BasicLogger.setLevel(0) | |||
| def setBasicLoggerWARN(): | |||
| '''Use Basic Logger. | |||
| ''' | |||
| setLoggerClass(BasicLogger) | |||
| BasicLogger.setLevel(1) | |||
| def setBasicLoggerDEBUG(): | |||
| '''Use Basic Logger. | |||
| ''' | |||
| setLoggerClass(BasicLogger) | |||
| BasicLogger.setLevel(2) | |||
| def setLoggerClass(loggingClass): | |||
| '''Set Logging Class. | |||
| ''' | |||
| assert issubclass(loggingClass, ILogger), 'loggingClass must subclass ILogger' | |||
| global _LoggerClass | |||
| _LoggerClass = loggingClass | |||
| def setLevel(level=0): | |||
| '''Set Global Logging Level. | |||
| ''' | |||
| ILogger.level = level | |||
| def getLogger(msg): | |||
| '''Return instance of Logging class. | |||
| ''' | |||
| return _LoggerClass(msg) | |||
| @@ -1,5 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """wstools.WSDLTools.WSDLReader tests directory.""" | |||
| import utils | |||
| @@ -1,20 +0,0 @@ | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import unittest | |||
| import test_wsdl | |||
| import utils | |||
| def makeTestSuite(): | |||
| suite = unittest.TestSuite() | |||
| suite.addTest(test_wsdl.makeTestSuite("services_by_file")) | |||
| return suite | |||
| def main(): | |||
| loader = utils.MatchTestLoader(True, None, "makeTestSuite") | |||
| unittest.main(defaultTest="makeTestSuite", testLoader=loader) | |||
| if __name__ == "__main__" : main() | |||
| @@ -1,160 +0,0 @@ | |||
| #!/usr/bin/env python | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import sys, unittest | |||
| import ConfigParser | |||
| from ZSI.wstools.Utility import DOM | |||
| from ZSI.wstools.WSDLTools import WSDLReader | |||
| from ZSI.wstools.TimeoutSocket import TimeoutError | |||
| class WSDLToolsTestCase(unittest.TestCase): | |||
| def __init__(self, methodName='runTest'): | |||
| unittest.TestCase.__init__(self, methodName) | |||
| def setUp(self): | |||
| self.path = nameGenerator.next() | |||
| print self.path | |||
| sys.stdout.flush() | |||
| def __str__(self): | |||
| teststr = unittest.TestCase.__str__(self) | |||
| if hasattr(self, "path"): | |||
| return "%s: %s" % (teststr, self.path ) | |||
| else: | |||
| return "%s" % (teststr) | |||
| def checkWSDLCollection(self, tag_name, component, key='name'): | |||
| if self.wsdl is None: | |||
| return | |||
| definition = self.wsdl.document.documentElement | |||
| version = DOM.WSDLUriToVersion(definition.namespaceURI) | |||
| nspname = DOM.GetWSDLUri(version) | |||
| for node in DOM.getElements(definition, tag_name, nspname): | |||
| name = DOM.getAttr(node, key) | |||
| comp = component[name] | |||
| self.failUnlessEqual(eval('comp.%s' %key), name) | |||
| def checkXSDCollection(self, tag_name, component, node, key='name'): | |||
| for cnode in DOM.getElements(node, tag_name): | |||
| name = DOM.getAttr(cnode, key) | |||
| component[name] | |||
| def test_all(self): | |||
| try: | |||
| if self.path[:7] == 'http://': | |||
| self.wsdl = WSDLReader().loadFromURL(self.path) | |||
| else: | |||
| self.wsdl = WSDLReader().loadFromFile(self.path) | |||
| except TimeoutError: | |||
| print "connection timed out" | |||
| sys.stdout.flush() | |||
| return | |||
| except: | |||
| self.path = self.path + ": load failed, unable to start" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('service', self.wsdl.services) | |||
| except: | |||
| self.path = self.path + ": wsdl.services" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('message', self.wsdl.messages) | |||
| except: | |||
| self.path = self.path + ": wsdl.messages" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('portType', self.wsdl.portTypes) | |||
| except: | |||
| self.path = self.path + ": wsdl.portTypes" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('binding', self.wsdl.bindings) | |||
| except: | |||
| self.path = self.path + ": wsdl.bindings" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('import', self.wsdl.imports, key='namespace') | |||
| except: | |||
| self.path = self.path + ": wsdl.imports" | |||
| raise | |||
| try: | |||
| for key in self.wsdl.types.keys(): | |||
| schema = self.wsdl.types[key] | |||
| self.failUnlessEqual(key, schema.getTargetNamespace()) | |||
| definition = self.wsdl.document.documentElement | |||
| version = DOM.WSDLUriToVersion(definition.namespaceURI) | |||
| nspname = DOM.GetWSDLUri(version) | |||
| for node in DOM.getElements(definition, 'types', nspname): | |||
| for snode in DOM.getElements(node, 'schema'): | |||
| tns = DOM.findTargetNS(snode) | |||
| schema = self.wsdl.types[tns] | |||
| self.schemaAttributesDeclarations(schema, snode) | |||
| self.schemaAttributeGroupDeclarations(schema, snode) | |||
| self.schemaElementDeclarations(schema, snode) | |||
| self.schemaTypeDefinitions(schema, snode) | |||
| except: | |||
| self.path = self.path + ": wsdl.types" | |||
| raise | |||
| if self.wsdl.extensions: | |||
| print 'No check for WSDLTools(%s) Extensions:' %(self.wsdl.name) | |||
| for ext in self.wsdl.extensions: print '\t', ext | |||
| def schemaAttributesDeclarations(self, schema, node): | |||
| self.checkXSDCollection('attribute', schema.attr_decl, node) | |||
| def schemaAttributeGroupDeclarations(self, schema, node): | |||
| self.checkXSDCollection('group', schema.attr_groups, node) | |||
| def schemaElementDeclarations(self, schema, node): | |||
| self.checkXSDCollection('element', schema.elements, node) | |||
| def schemaTypeDefinitions(self, schema, node): | |||
| self.checkXSDCollection('complexType', schema.types, node) | |||
| self.checkXSDCollection('simpleType', schema.types, node) | |||
| def setUpOptions(section): | |||
| cp = ConfigParser.ConfigParser() | |||
| cp.read('config.txt') | |||
| if not cp.sections(): | |||
| print 'fatal error: configuration file config.txt not present' | |||
| sys.exit(0) | |||
| if not cp.has_section(section): | |||
| print '%s section not present in configuration file, exiting' % section | |||
| sys.exit(0) | |||
| return cp, len(cp.options(section)) | |||
| def getOption(cp, section): | |||
| for name, value in cp.items(section): | |||
| yield value | |||
| def makeTestSuite(section='services_by_file'): | |||
| global nameGenerator | |||
| cp, numTests = setUpOptions(section) | |||
| nameGenerator = getOption(cp, section) | |||
| suite = unittest.TestSuite() | |||
| for i in range(0, numTests): | |||
| suite.addTest(unittest.makeSuite(WSDLToolsTestCase, 'test_')) | |||
| return suite | |||
| def main(): | |||
| unittest.main(defaultTest="makeTestSuite") | |||
| if __name__ == "__main__" : main() | |||
| @@ -1,37 +0,0 @@ | |||
| #!/usr/bin/env python | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import unittest, tarfile, os, ConfigParser | |||
| import test_wsdl | |||
| SECTION='files' | |||
| CONFIG_FILE = 'config.txt' | |||
| def extractFiles(section, option): | |||
| config = ConfigParser.ConfigParser() | |||
| config.read(CONFIG_FILE) | |||
| archives = config.get(section, option) | |||
| archives = eval(archives) | |||
| for file in archives: | |||
| tar = tarfile.open(file) | |||
| if not os.access(tar.membernames[0], os.R_OK): | |||
| for i in tar.getnames(): | |||
| tar.extract(i) | |||
| def makeTestSuite(): | |||
| suite = unittest.TestSuite() | |||
| suite.addTest(test_wsdl.makeTestSuite("services_by_file")) | |||
| return suite | |||
| def main(): | |||
| extractFiles(SECTION, 'archives') | |||
| unittest.main(defaultTest="makeTestSuite") | |||
| if __name__ == "__main__" : main() | |||
| @@ -1,20 +0,0 @@ | |||
| #!/usr/bin/env python | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import unittest | |||
| import test_wsdl | |||
| def makeTestSuite(): | |||
| suite = unittest.TestSuite() | |||
| suite.addTest(test_wsdl.makeTestSuite("services_by_http")) | |||
| return suite | |||
| def main(): | |||
| unittest.main(defaultTest="makeTestSuite") | |||
| if __name__ == "__main__" : main() | |||
| @@ -0,0 +1 @@ | |||
| *.pyc | |||
| @@ -0,0 +1,86 @@ | |||
| # This list of servers was taken from the SOAPBuilders Interoperability Lab | |||
| # (http://www.xmethods.net/ilab/ilab.html) 4/23/01. | |||
| # | |||
| # $Id: inventory.servers 4 2001-06-27 21:36:11Z cullman $ | |||
| Name: MST Bid (Microsoft SOAP Toolkit 2.0, Microsoft Windows 2000) | |||
| Endpoint: http://131.107.72.13/stk/Bid.wsdl | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: KeithBa's BidBuy Service (.NET Web Services) | |||
| Endpoint: http://131.107.72.13/test/bidbuy/bidbuy.asmx | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://soapinterop.org/xsd | |||
| Name: JHawk's BidBuyService (.NET Remoting, Win2K) | |||
| Endpoint: http://131.107.72.13/DotNetRemotingNI/BidBuy.soap | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| #Name: Idoox WASP | |||
| #Endpoint: http://soap.idoox.net:8888/soap/servlet/Bid/ | |||
| #SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| #Namespace: http://www.soapinterop.org/Bid | |||
| Name: Paul's Quick Bid (SOAP::Lite) | |||
| Endpoint: http://services.soaplite.com/tradeit.cgi | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: Phalanx Bid Service | |||
| Endpoint: http://www.phalanxsys.com/ni/listener.asp | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Nonfunctional: Buy admitted problem with the wsdl | |||
| Name: PranishK's BidBuy Service (ATL Web Service) | |||
| Endpoint: http://www.mssoapinterop.org/atls_soap/bidbuy.dll?Handler=Default | |||
| SOAPAction: "#%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: GLUE Bid | |||
| Endpoint: http://209.61.190.164:8004/glue/http://www.soapinterop.org/Bid | |||
| SOAPAction: "http://www.soapinterop.org/Bid#(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: Aumsoft's BidBuy | |||
| Endpoint: http://soap.aumsoft.com:8080/soap/BidBuy | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: SOAP.py 0.9 (actzero.com) | |||
| Endpoint: http://208.177.157.221:12080/xmethodsInterop | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: HP SOAP | |||
| Endpoint: http://soap.bluestone.com/scripts/SaISAPI.dll/SaServletEngine.class/hp-soap/soap/rpc/interop/BidBuy | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: EasySoap++ Bid Service (San Diego) | |||
| Endpoint: http://easysoap.no-ip.com:8080/cgi-bin/bidbuyservice | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| Name: Jake's Frontier 7.0b43 Bid Service (Santa Clara, CA) | |||
| Endpoint: http://www.soapware.org/BidBuy | |||
| SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| Namespace: http://www.soapinterop.org/Bid | |||
| #Name: Pete's Clear Bids (CapeConnect/Win2000) | |||
| #Endpoint: http://208.46.17.81/ccx/SOAPServlet | |||
| #SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| #Namespace: http://www.soapinterop.org/Bid | |||
| #Name: (PranishK's) ATL Server BidBuy | |||
| #Endpoint: http://208.46.17.121/bidbuy/bidbuy.dll?Handler=Default | |||
| #SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| #Namespace: http://www.soapinterop.org/Bid | |||
| #Name: HP-SOAP @ N+I | |||
| #Endpoint: http://208.46.17.112/scripts/SaISAPI.dll/SaServletEngine.class/hp-soap/soap/rpc/interop/BidBuy | |||
| #SOAPAction: "http://www.soapinterop.org/%(methodname)s" | |||
| #Namespace: http://www.soapinterop.org/Bid | |||
| @@ -0,0 +1 @@ | |||
| *.pyc | |||
| @@ -4,7 +4,7 @@ | |||
| CVS=0 | |||
| from distutils.core import setup, Command, Extension | |||
| from setuptools import setup, find_packages | |||
| def load_version(): | |||
| @@ -54,11 +54,13 @@ setup( | |||
| maintainer_email="Gregory.R.Warnes@Pfizer.com", | |||
| url = url, | |||
| long_description=long_description, | |||
| packages=['SOAPpy','SOAPpy/wstools'], | |||
| provides = ['SOAPpy'], | |||
| packages=find_packages('src'), | |||
| package_dir = {'': 'src'}, | |||
| include_package_data=True, | |||
| install_requires=[ | |||
| 'fpconst', | |||
| 'pyxml' | |||
| 'wstools' | |||
| ] | |||
| ) | |||
| @@ -1,3 +1,5 @@ | |||
| from __future__ import nested_scopes | |||
| """ | |||
| ################################################################################ | |||
| # | |||
| @@ -39,17 +41,18 @@ | |||
| # | |||
| ################################################################################ | |||
| """ | |||
| from __future__ import nested_scopes | |||
| ident = '$Id: Client.py 1496 2010-03-04 23:46:17Z pooryorick $' | |||
| ident = '$Id: Client.py,v 1.27 2005/02/21 20:27:09 warnes Exp $' | |||
| from version import __version__ | |||
| #import xml.sax | |||
| import urllib | |||
| from types import * | |||
| import re | |||
| import base64 | |||
| import socket, httplib | |||
| from httplib import HTTPConnection, HTTP | |||
| import Cookie | |||
| # SOAPpy modules | |||
| from Errors import * | |||
| @@ -110,8 +113,46 @@ class SOAPAddress: | |||
| __repr__ = __str__ | |||
| class SOAPTimeoutError(socket.timeout): | |||
| '''This exception is raised when a timeout occurs in SOAP operations''' | |||
| pass | |||
| class HTTPConnectionWithTimeout(HTTPConnection): | |||
| '''Extend HTTPConnection for timeout support''' | |||
| def __init__(self, host, port=None, strict=None, timeout=None): | |||
| HTTPConnection.__init__(self, host, port, strict) | |||
| self._timeout = timeout | |||
| def connect(self): | |||
| HTTPConnection.connect(self) | |||
| if self.sock and self._timeout: | |||
| self.sock.settimeout(self._timeout) | |||
| class HTTPWithTimeout(HTTP): | |||
| _connection_class = HTTPConnectionWithTimeout | |||
| ## this __init__ copied from httplib.HTML class | |||
| def __init__(self, host='', port=None, strict=None, timeout=None): | |||
| "Provide a default host, since the superclass requires one." | |||
| # some joker passed 0 explicitly, meaning default port | |||
| if port == 0: | |||
| port = None | |||
| # Note that we may pass an empty string as the host; this will throw | |||
| # an error when we attempt to connect. Presumably, the client code | |||
| # will call connect before then, with a proper host. | |||
| self._setup(self._connection_class(host, port, strict, timeout)) | |||
| class HTTPTransport: | |||
| def __init__(self): | |||
| self.cookies = Cookie.SimpleCookie(); | |||
| def getNS(self, original_namespace, data): | |||
| """Extract the (possibly extended) namespace from the returned | |||
| SOAP message.""" | |||
| @@ -125,12 +166,26 @@ class HTTPTransport: | |||
| return original_namespace | |||
| else: | |||
| return original_namespace | |||
| # Need a Timeout someday? | |||
| def __addcookies(self, r): | |||
| '''Add cookies from self.cookies to request r | |||
| ''' | |||
| for cname, morsel in self.cookies.items(): | |||
| attrs = [] | |||
| value = morsel.get('version', '') | |||
| if value != '' and value != '0': | |||
| attrs.append('$Version=%s' % value) | |||
| attrs.append('%s=%s' % (cname, morsel.coded_value)) | |||
| value = morsel.get('path') | |||
| if value: | |||
| attrs.append('$Path=%s' % value) | |||
| value = morsel.get('domain') | |||
| if value: | |||
| attrs.append('$Domain=%s' % value) | |||
| r.putheader('Cookie', "; ".join(attrs)) | |||
| def call(self, addr, data, namespace, soapaction = None, encoding = None, | |||
| http_proxy = None, config = Config): | |||
| import httplib | |||
| http_proxy = None, config = Config, timeout=None): | |||
| if not isinstance(addr, SOAPAddress): | |||
| addr = SOAPAddress(addr, config) | |||
| @@ -149,7 +204,7 @@ class HTTPTransport: | |||
| elif addr.proto == 'https': | |||
| r = httplib.HTTPS(real_addr) | |||
| else: | |||
| r = httplib.HTTP(real_addr) | |||
| r = HTTPWithTimeout(real_addr, timeout=timeout) | |||
| r.putrequest("POST", real_path) | |||
| @@ -157,14 +212,15 @@ class HTTPTransport: | |||
| r.putheader("User-agent", SOAPUserAgent()) | |||
| t = 'text/xml'; | |||
| if encoding != None: | |||
| t += '; charset="%s"' % encoding | |||
| t += '; charset=%s' % encoding | |||
| r.putheader("Content-type", t) | |||
| r.putheader("Content-length", str(len(data))) | |||
| self.__addcookies(r); | |||
| # if user is not a user:passwd format | |||
| # we'll receive a failure from the server. . .I guess (??) | |||
| if addr.user != None: | |||
| val = base64.encodestring(addr.user) | |||
| val = base64.encodestring(addr.user) | |||
| r.putheader('Authorization','Basic ' + val.replace('\012','')) | |||
| # This fixes sending either "" or "None" | |||
| @@ -200,9 +256,14 @@ class HTTPTransport: | |||
| # read response line | |||
| code, msg, headers = r.getreply() | |||
| self.cookies = Cookie.SimpleCookie(); | |||
| if headers: | |||
| content_type = headers.get("content-type","text/xml") | |||
| content_length = headers.get("Content-length") | |||
| for cookie in headers.getallmatchingheaders("Set-Cookie"): | |||
| self.cookies.load(cookie); | |||
| else: | |||
| content_type=None | |||
| content_length=None | |||
| @@ -218,7 +279,7 @@ class HTTPTransport: | |||
| message_len = int(content_length) | |||
| except: | |||
| message_len = -1 | |||
| if message_len < 0: | |||
| # Content-Length missing or invalid; just read the whole socket | |||
| # This won't work with HTTP/1.1 chunked encoding | |||
| @@ -233,7 +294,7 @@ class HTTPTransport: | |||
| print "headers=", headers | |||
| print "content-type=", content_type | |||
| print "data=", data | |||
| if config.dumpHeadersIn: | |||
| s = 'Incoming HTTP headers' | |||
| debugHeader(s) | |||
| @@ -246,7 +307,7 @@ class HTTPTransport: | |||
| def startswith(string, val): | |||
| return string[0:len(val)] == val | |||
| if code == 500 and not \ | |||
| ( startswith(content_type, "text/xml") and message_len > 0 ): | |||
| raise HTTPError(code, msg) | |||
| @@ -268,7 +329,7 @@ class HTTPTransport: | |||
| new_ns = None | |||
| else: | |||
| new_ns = self.getNS(namespace, data) | |||
| # return response payload | |||
| return data, new_ns | |||
| @@ -280,7 +341,7 @@ class SOAPProxy: | |||
| header = None, methodattrs = None, transport = HTTPTransport, | |||
| encoding = 'UTF-8', throw_faults = 1, unwrap_results = None, | |||
| http_proxy=None, config = Config, noroot = 0, | |||
| simplify_objects=None): | |||
| simplify_objects=None, timeout=None): | |||
| # Test the encoding, raising an exception if it's not known | |||
| if encoding != None: | |||
| @@ -309,6 +370,7 @@ class SOAPProxy: | |||
| self.http_proxy = http_proxy | |||
| self.config = config | |||
| self.noroot = noroot | |||
| self.timeout = timeout | |||
| # GSI Additions | |||
| if hasattr(config, "channel_mode") and \ | |||
| @@ -316,10 +378,10 @@ class SOAPProxy: | |||
| self.channel_mode = config.channel_mode | |||
| self.delegation_mode = config.delegation_mode | |||
| #end GSI Additions | |||
| def invoke(self, method, args): | |||
| return self.__call(method, args, {}) | |||
| def __call(self, name, args, kw, ns = None, sa = None, hd = None, | |||
| ma = None): | |||
| @@ -334,7 +396,7 @@ class SOAPProxy: | |||
| sa = self.soapaction | |||
| else: | |||
| sa = name | |||
| if hd: # Get header | |||
| if type(hd) == TupleType: | |||
| hd = hd[0] | |||
| @@ -356,11 +418,14 @@ class SOAPProxy: | |||
| call_retry = 0 | |||
| try: | |||
| r, self.namespace = self.transport.call(self.proxy, m, ns, sa, | |||
| encoding = self.encoding, | |||
| http_proxy = self.http_proxy, | |||
| config = self.config) | |||
| http_proxy = self.http_proxy, | |||
| config = self.config, | |||
| timeout = self.timeout) | |||
| except socket.timeout: | |||
| raise SOAPTimeoutError | |||
| except Exception, ex: | |||
| # | |||
| @@ -368,7 +433,7 @@ class SOAPProxy: | |||
| # | |||
| # See if we have a fault handling vector installed in our | |||
| # config. If we do, invoke it. If it returns a true value, | |||
| # retry the call. | |||
| # retry the call. | |||
| # | |||
| # In any circumstance other than the fault handler returning | |||
| # true, reraise the exception. This keeps the semantics of this | |||
| @@ -386,11 +451,15 @@ class SOAPProxy: | |||
| raise | |||
| if call_retry: | |||
| r, self.namespace = self.transport.call(self.proxy, m, ns, sa, | |||
| encoding = self.encoding, | |||
| http_proxy = self.http_proxy, | |||
| config = self.config) | |||
| try: | |||
| r, self.namespace = self.transport.call(self.proxy, m, ns, sa, | |||
| encoding = self.encoding, | |||
| http_proxy = self.http_proxy, | |||
| config = self.config, | |||
| timeout = self.timeout) | |||
| except socket.timeout: | |||
| raise SOAPTimeoutError | |||
| p, attrs = parseSOAPRPC(r, attrs = 1) | |||
| @@ -418,7 +487,7 @@ class SOAPProxy: | |||
| count += 1 | |||
| t = getattr(p, i) | |||
| if count == 1: # Only one piece of data, bubble it up | |||
| p = t | |||
| p = t | |||
| except: | |||
| pass | |||
| @@ -436,11 +505,12 @@ class SOAPProxy: | |||
| return self.__call(None, body, {}) | |||
| def __getattr__(self, name): # hook to catch method calls | |||
| if name == '__del__': | |||
| if name in ( '__del__', '__getinitargs__', '__getnewargs__', | |||
| '__getstate__', '__setstate__', '__reduce__', '__reduce_ex__'): | |||
| raise AttributeError, name | |||
| return self.__Method(self.__call, name, config = self.config) | |||
| # To handle attribute wierdness | |||
| # To handle attribute weirdness | |||
| class __Method: | |||
| # Some magic to bind a SOAP method to an RPC server. | |||
| # Supports "nested" methods (e.g. examples.getStateName) -- concept | |||
| @@ -468,7 +538,7 @@ class SOAPProxy: | |||
| return self.__f_call(*args, **kw) | |||
| else: | |||
| return self.__r_call(*args, **kw) | |||
| def __getattr__(self, name): | |||
| if name == '__del__': | |||
| raise AttributeError, name | |||
| @@ -33,10 +33,10 @@ | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: Config.py,v 1.9 2004/01/31 04:20:05 warnes Exp $' | |||
| ident = '$Id: Config.py 1298 2006-11-07 00:54:15Z sanxiyn $' | |||
| from version import __version__ | |||
| import copy, socket | |||
| import socket | |||
| from types import * | |||
| from NS import NS | |||
| @@ -40,7 +40,7 @@ | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: Errors.py,v 1.5 2005/02/15 16:32:22 warnes Exp $' | |||
| ident = '$Id: Errors.py 921 2005-02-15 16:32:23Z warnes $' | |||
| from version import __version__ | |||
| import exceptions | |||
| @@ -1,3 +1,5 @@ | |||
| from __future__ import nested_scopes | |||
| """ | |||
| GSIServer - Contributed by Ivan R. Judson <judson@mcs.anl.gov> | |||
| @@ -43,13 +45,9 @@ GSIServer - Contributed by Ivan R. Judson <judson@mcs.anl.gov> | |||
| ################################################################################ | |||
| """ | |||
| from __future__ import nested_scopes | |||
| ident = '$Id: GSIServer.py,v 1.5 2005/02/15 16:32:22 warnes Exp $' | |||
| ident = '$Id: GSIServer.py 1468 2008-05-24 01:55:33Z warnes $' | |||
| from version import __version__ | |||
| #import xml.sax | |||
| import re | |||
| import socket | |||
| @@ -1,3 +1,5 @@ | |||
| from __future__ import nested_scopes | |||
| """ | |||
| ################################################################################ | |||
| # | |||
| @@ -40,9 +42,7 @@ | |||
| ################################################################################ | |||
| """ | |||
| from __future__ import nested_scopes | |||
| ident = '$Id: NS.py,v 1.4 2005/02/15 16:32:22 warnes Exp $' | |||
| ident = '$Id: NS.py 1468 2008-05-24 01:55:33Z warnes $' | |||
| from version import __version__ | |||
| ############################################################################## | |||
| @@ -12,7 +12,7 @@ from wstools.XMLname import fromXMLname | |||
| try: from M2Crypto import SSL | |||
| except: pass | |||
| ident = '$Id: Parser.py,v 1.16 2005/02/22 04:29:42 warnes Exp $' | |||
| ident = '$Id: Parser.py 1497 2010-03-08 06:06:52Z pooryorick $' | |||
| from version import __version__ | |||
| @@ -85,6 +85,16 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| self._rules = rules | |||
| def startElementNS(self, name, qname, attrs): | |||
| def toStr( name ): | |||
| prefix = name[0] | |||
| tag = name[1] | |||
| if self._prem_r.has_key(prefix): | |||
| tag = self._prem_r[name[0]] + ':' + name[1] | |||
| elif prefix: | |||
| tag = prefix + ":" + tag | |||
| return tag | |||
| # Workaround two sax bugs | |||
| if name[0] == None and name[1][0] == ' ': | |||
| name = (None, name[1][1:]) | |||
| @@ -95,8 +105,8 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| if self._next == "E": | |||
| if name[1] != 'Envelope': | |||
| raise Error, "expected `SOAP-ENV:Envelope', gto `%s:%s'" % \ | |||
| (self._prem_r[name[0]], name[1]) | |||
| 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]) | |||
| @@ -108,16 +118,17 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| else: | |||
| raise Error, \ | |||
| "expected `SOAP-ENV:Header' or `SOAP-ENV:Body', " \ | |||
| "got `%s'" % self._prem_r[name[0]] + ':' + name[1] | |||
| "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'" % \ | |||
| self._prem_r[name[0]] + ':' + name[1] | |||
| raise Error, "expected `SOAP-ENV:Body', " \ | |||
| "got `%s'" % toStr( name ) | |||
| elif self._next == "": | |||
| raise Error, "expected nothing, got `%s'" % \ | |||
| self._prem_r[name[0]] + ':' + name[1] | |||
| raise Error, "expected nothing, " \ | |||
| "got `%s'" % toStr( name ) | |||
| if len(self._stack) == 2: | |||
| rules = self._rules | |||
| @@ -137,7 +148,10 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| i = kind.find(':') | |||
| if i >= 0: | |||
| kind = (self._prem[kind[:i]], kind[i + 1:]) | |||
| try: | |||
| kind = (self._prem[kind[:i]], kind[i + 1:]) | |||
| except: | |||
| kind = None | |||
| else: | |||
| kind = None | |||
| @@ -232,7 +246,10 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| if kind != None: | |||
| i = kind.find(':') | |||
| if i >= 0: | |||
| kind = (self._prem[kind[:i]], kind[i + 1:]) | |||
| try: | |||
| kind = (self._prem[kind[:i]], kind[i + 1:]) | |||
| except: | |||
| kind = (None, kind) | |||
| else: | |||
| # XXX What to do here? (None, kind) is just going to fail in convertType | |||
| #print "Kind with no NS:", kind | |||
| @@ -354,6 +371,12 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| # 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 == None: | |||
| # If the current item's container is an array, it will | |||
| # have a kind. If so, get the bit before the first [, | |||
| @@ -775,7 +798,7 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| 'negative-integer': (0, None, -1), | |||
| 'long': (1, -9223372036854775808L, | |||
| 9223372036854775807L), | |||
| 'int': (0, -2147483648L, 2147483647), | |||
| 'int': (0, -2147483648L, 2147483647L), | |||
| 'short': (0, -32768, 32767), | |||
| 'byte': (0, -128, 127), | |||
| 'nonNegativeInteger': (0, 0, None), | |||
| @@ -797,9 +820,6 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| zerofloatre = '[1-9]' | |||
| def convertType(self, d, t, attrs, config=Config): | |||
| if t[0] is None and t[1] is not None: | |||
| type = t[1].strip() | |||
| @@ -837,8 +857,18 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| #print " requested_type=", t | |||
| #print " data=", d | |||
| # print "convertToBasicTypes:" | |||
| # print " requested_type=", t | |||
| # print " data=", d | |||
| # print " attrs=", attrs | |||
| # print " t[0]=", t[0] | |||
| # print " t[1]=", t[1] | |||
| # print " in?", t[0] in NS.EXSD_L | |||
| if t[0] in NS.EXSD_L: | |||
| if t[1] == "integer": | |||
| if t[1]=="integer": # unbounded integer type | |||
| try: | |||
| d = int(d) | |||
| if len(attrs): | |||
| @@ -846,7 +876,7 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| except: | |||
| d = long(d) | |||
| return d | |||
| if self.intlimits.has_key (t[1]): # integer types | |||
| if self.intlimits.has_key (t[1]): # range-bounded integer types | |||
| l = self.intlimits[t[1]] | |||
| try: d = int(d) | |||
| except: d = long(d) | |||
| @@ -866,54 +896,49 @@ class SOAPParser(xml.sax.handler.ContentHandler): | |||
| return str(dnn) | |||
| except: | |||
| return dnn | |||
| if t[1] == "boolean": | |||
| if t[1] in ("bool", "boolean"): | |||
| d = d.strip().lower() | |||
| if d in ('0', 'false'): | |||
| return 0 | |||
| return False | |||
| if d in ('1', 'true'): | |||
| return 1 | |||
| return True | |||
| raise AttributeError, "invalid boolean value" | |||
| if t[1] in ('double','float'): | |||
| l = self.floatlimits[t[1]] | |||
| s = d.strip().lower() | |||
| d = float(s) | |||
| # Explicitly check for NaN and Infinities | |||
| if s == "nan": | |||
| d = fpconst.NaN | |||
| elif s[0:2]=="inf" or s[0:3]=="+inf": | |||
| d = fpconst.PosInf | |||
| elif s[0:3] == "-inf": | |||
| d = fpconst.NegInf | |||
| else : | |||
| d = float(s) | |||
| if config.strict_range: | |||
| if d < l[1]: raise UnderflowError | |||
| if d > l[2]: raise OverflowError | |||
| else: | |||
| # some older SOAP impementations (notably SOAP4J, | |||
| # Apache SOAP) return "infinity" instead of "INF" | |||
| # so check the first 3 characters for a match. | |||
| if s == "nan": | |||
| return fpconst.NaN | |||
| elif s[0:3] in ("inf", "+inf"): | |||
| return fpconst.PosInf | |||
| elif s[0:3] == "-inf": | |||
| return fpconst.NegInf | |||
| if fpconst.isNaN(d): | |||
| if s != 'nan': | |||
| raise ValueError, "invalid %s: %s" % (t[1], s) | |||
| elif fpconst.isNegInf(d): | |||
| if s != '-inf': | |||
| raise UnderflowError, "%s too small: %s" % (t[1], s) | |||
| elif fpconst.isPosInf(d): | |||
| if s != 'inf': | |||
| raise OverflowError, "%s too large: %s" % (t[1], s) | |||
| elif d < 0 and d < l[1]: | |||
| raise UnderflowError, "%s too small: %s" % (t[1], s) | |||
| elif d > 0 and ( d < l[0] or d > l[2] ): | |||
| raise OverflowError, "%s too large: %s" % (t[1], s) | |||
| elif d == 0: | |||
| if type(self.zerofloatre) == StringType: | |||
| self.zerofloatre = re.compile(self.zerofloatre) | |||
| if self.zerofloatre.search(s): | |||
| raise UnderflowError, "invalid %s: %s" % (t[1], s) | |||
| if fpconst.isNaN(d): | |||
| if s[0:2] != 'nan': | |||
| raise ValueError, "invalid %s: %s" % (t[1], s) | |||
| elif fpconst.isNegInf(d): | |||
| if s[0:3] != '-inf': | |||
| raise UnderflowError, "%s too small: %s" % (t[1], s) | |||
| elif fpconst.isPosInf(d): | |||
| if s[0:2] != 'inf' and s[0:3] != '+inf': | |||
| raise OverflowError, "%s too large: %s" % (t[1], s) | |||
| elif d < 0 and d < l[1]: | |||
| raise UnderflowError, "%s too small: %s" % (t[1], s) | |||
| elif d > 0 and ( d < l[0] or d > l[2] ): | |||
| raise OverflowError, "%s too large: %s" % (t[1], s) | |||
| elif d == 0: | |||
| if type(self.zerofloatre) == StringType: | |||
| self.zerofloatre = re.compile(self.zerofloatre) | |||
| if self.zerofloatre.search(s): | |||
| raise UnderflowError, "invalid %s: %s" % (t[1], s) | |||
| return d | |||
| if t[1] in ("dateTime", "date", "timeInstant", "time"): | |||
| return self.convertDateTime(d, t[1]) | |||
| if t[1] == "decimal": | |||
| @@ -3,7 +3,7 @@ | |||
| Delete when 1.0.0 is released! | |||
| """ | |||
| ident = '$Id: SOAP.py,v 1.38 2004/01/31 04:20:06 warnes Exp $' | |||
| ident = '$Id: SOAP.py 541 2004-01-31 04:20:06Z warnes $' | |||
| from version import __version__ | |||
| from Client import * | |||
| @@ -33,11 +33,10 @@ | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: SOAPBuilder.py,v 1.27 2005/02/21 20:24:13 warnes Exp $' | |||
| ident = '$Id: SOAPBuilder.py 1498 2010-03-12 02:13:19Z pooryorick $' | |||
| from version import __version__ | |||
| import cgi | |||
| import copy | |||
| from wstools.XMLname import toXMLname, fromXMLname | |||
| import fpconst | |||
| @@ -285,22 +284,7 @@ class SOAPBuilder: | |||
| if type(tag) not in (NoneType, StringType, UnicodeType): | |||
| raise KeyError, "tag must be a string or None" | |||
| try: | |||
| meth = getattr(self, "dump_" + type(obj).__name__) | |||
| except AttributeError: | |||
| if type(obj) == LongType: | |||
| obj_type = "integer" | |||
| elif pythonHasBooleanType and type(obj) == BooleanType: | |||
| obj_type = "boolean" | |||
| else: | |||
| obj_type = type(obj).__name__ | |||
| self.out.append(self.dumper(None, obj_type, obj, tag, typed, | |||
| ns_map, self.genroot(ns_map))) | |||
| else: | |||
| meth(obj, tag, typed, ns_map) | |||
| self.dump_dispatch(obj, tag, typed, ns_map) | |||
| self.depth -= 1 | |||
| # generic dumper | |||
| @@ -333,6 +317,7 @@ class SOAPBuilder: | |||
| data = obj | |||
| return xml % {"tag": tag, "type": t, "data": data, "root": rootattr, | |||
| "id": id, "attrs": a} | |||
| @@ -354,10 +339,20 @@ class SOAPBuilder: | |||
| else: | |||
| obj = repr(obj) | |||
| # Note: python 'float' is actually a SOAP 'double'. | |||
| self.out.append(self.dumper(None, "double", obj, tag, typed, ns_map, | |||
| self.genroot(ns_map))) | |||
| # Note: python 'float' is actually a SOAP 'double'. | |||
| self.out.append(self.dumper( | |||
| None, "double", obj, tag, typed, ns_map, self.genroot(ns_map))) | |||
| def dump_int(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_int." | |||
| self.out.append(self.dumper(None, 'integer', obj, tag, typed, | |||
| ns_map, self.genroot(ns_map))) | |||
| def dump_bool(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_bool." | |||
| self.out.append(self.dumper(None, 'boolean', obj, tag, typed, | |||
| ns_map, self.genroot(ns_map))) | |||
| def dump_string(self, obj, tag, typed = 0, ns_map = {}): | |||
| if Config.debug: print "In dump_string." | |||
| tag = tag or self.gentag() | |||
| @@ -408,12 +403,12 @@ class SOAPBuilder: | |||
| except: | |||
| # preserve type if present | |||
| if getattr(obj,"_typed",None) and getattr(obj,"_type",None): | |||
| if getattr(obj, "_complexType", None): | |||
| if getattr(obj, "_complexType", None): | |||
| sample = typedArrayType(typed=obj._type, | |||
| complexType = obj._complexType) | |||
| sample._typename = obj._type | |||
| if not getattr(obj,"_ns",None): obj._ns = NS.URN | |||
| else: | |||
| else: | |||
| sample = typedArrayType(typed=obj._type) | |||
| else: | |||
| sample = structType() | |||
| @@ -460,7 +455,7 @@ class SOAPBuilder: | |||
| else: | |||
| t = 'ur-type' | |||
| else: | |||
| typename = type(sample).__name__ | |||
| typename = type(sample).__name__ | |||
| # For Python 2.2+ | |||
| if type(sample) == StringType: typename = 'string' | |||
| @@ -468,10 +463,10 @@ class SOAPBuilder: | |||
| # HACK: unicode is a SOAP string | |||
| if type(sample) == UnicodeType: typename = 'string' | |||
| # HACK: python 'float' is actually a SOAP 'double'. | |||
| if typename=="float": typename="double" | |||
| t = self.genns(ns_map, self.config.typesNamespaceURI)[0] + \ | |||
| typename | |||
| # HACK: python 'float' is actually a SOAP 'double'. | |||
| if typename=="float": typename="double" | |||
| t = self.genns( | |||
| ns_map, self.config.typesNamespaceURI)[0] + typename | |||
| else: | |||
| t = self.genns(ns_map, self.config.typesNamespaceURI)[0] + \ | |||
| @@ -502,6 +497,17 @@ class SOAPBuilder: | |||
| dump_tuple = dump_list | |||
| def dump_exception(self, obj, tag, typed = 0, ns_map = {}): | |||
| if isinstance(obj, faultType): # Fault | |||
| cns, cdecl = self.genns(ns_map, NS.ENC) | |||
| vns, vdecl = self.genns(ns_map, NS.ENV) | |||
| self.out.append('<%sFault %sroot="1"%s%s>' % (vns, cns, vdecl, cdecl)) | |||
| self.dump(obj.faultcode, "faultcode", typed, ns_map) | |||
| self.dump(obj.faultstring, "faultstring", typed, ns_map) | |||
| if hasattr(obj, "detail"): | |||
| self.dump(obj.detail, "detail", typed, ns_map) | |||
| self.out.append("</%sFault>\n" % vns) | |||
| def dump_dictionary(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_dictionary." | |||
| tag = tag or self.gentag() | |||
| @@ -525,31 +531,32 @@ class SOAPBuilder: | |||
| dump_dict = dump_dictionary # For Python 2.2+ | |||
| def dump_instance(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_instance.", "obj=", obj, "tag=", tag | |||
| def dump_dispatch(self, obj, tag, typed = 1, ns_map = {}): | |||
| if not tag: | |||
| # If it has a name use it. | |||
| if isinstance(obj, anyType) and obj._name: | |||
| tag = obj._name | |||
| else: | |||
| tag = self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| if isinstance(obj, arrayType): # Array | |||
| self.dump_list(obj, tag, typed, ns_map) | |||
| return | |||
| if isinstance(obj, faultType): # Fault | |||
| cns, cdecl = self.genns(ns_map, NS.ENC) | |||
| vns, vdecl = self.genns(ns_map, NS.ENV) | |||
| self.out.append('''<%sFault %sroot="1"%s%s> | |||
| <faultcode>%s</faultcode> | |||
| <faultstring>%s</faultstring> | |||
| ''' % (vns, cns, vdecl, cdecl, obj.faultcode, obj.faultstring)) | |||
| if hasattr(obj, "detail"): | |||
| self.dump(obj.detail, "detail", typed, ns_map) | |||
| self.out.append("</%sFault>\n" % vns) | |||
| return | |||
| # watch out for order! | |||
| dumpmap = ( | |||
| (Exception, self.dump_exception), | |||
| (arrayType, self.dump_list), | |||
| (basestring, self.dump_string), | |||
| (NoneType, self.dump_None), | |||
| (bool, self.dump_bool), | |||
| (int, self.dump_int), | |||
| (long, self.dump_int), | |||
| (list, self.dump_list), | |||
| (tuple, self.dump_list), | |||
| (dict, self.dump_dictionary), | |||
| (float, self.dump_float), | |||
| ) | |||
| for dtype, func in dumpmap: | |||
| if isinstance(obj, dtype): | |||
| func(obj, tag, typed, ns_map) | |||
| return | |||
| r = self.genroot(ns_map) | |||
| @@ -558,11 +565,10 @@ class SOAPBuilder: | |||
| if isinstance(obj, voidType): # void | |||
| self.out.append("<%s%s%s></%s>\n" % (tag, a, r, tag)) | |||
| return | |||
| id = self.checkref(obj, tag, ns_map) | |||
| if id == None: | |||
| return | |||
| else: | |||
| id = self.checkref(obj, tag, ns_map) | |||
| if id == None: | |||
| return | |||
| if isinstance(obj, structType): | |||
| # Check for namespace | |||
| @@ -614,13 +620,16 @@ class SOAPBuilder: | |||
| else: # Some Class | |||
| self.out.append('<%s%s%s>\n' % (tag, id, r)) | |||
| for (k, v) in obj.__dict__.items(): | |||
| if k[0] != "_": | |||
| self.dump(v, k, 1, ns_map) | |||
| d1 = getattr(obj, '__dict__', None) | |||
| if d1 is not None: | |||
| for (k, v) in d1: | |||
| if k[0] != "_": | |||
| self.dump(v, k, 1, ns_map) | |||
| self.out.append('</%s>\n' % tag) | |||
| ################################################################################ | |||
| # SOAPBuilder's more public interface | |||
| ################################################################################ | |||
| @@ -1,3 +1,5 @@ | |||
| from __future__ import nested_scopes | |||
| """ | |||
| ################################################################################ | |||
| # | |||
| @@ -40,13 +42,10 @@ | |||
| ################################################################################ | |||
| """ | |||
| from __future__ import nested_scopes | |||
| ident = '$Id: Server.py,v 1.21 2005/02/15 16:32:22 warnes Exp $' | |||
| ident = '$Id: Server.py 1468 2008-05-24 01:55:33Z warnes $' | |||
| from version import __version__ | |||
| #import xml.sax | |||
| import re | |||
| import socket | |||
| import sys | |||
| import SocketServer | |||
| @@ -65,7 +64,7 @@ from Utilities import debugHeader, debugFooter | |||
| try: from M2Crypto import SSL | |||
| except: pass | |||
| ident = '$Id: Server.py,v 1.21 2005/02/15 16:32:22 warnes Exp $' | |||
| ident = '$Id: Server.py 1468 2008-05-24 01:55:33Z warnes $' | |||
| from version import __version__ | |||
| @@ -249,10 +248,11 @@ class SOAPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | |||
| # It is enabled by default. To disable, set | |||
| # Config.specialArgs to False. | |||
| if Config.specialArgs: | |||
| ordered_args = {} | |||
| named_args = {} | |||
| ordered_args = {} | |||
| named_args = {} | |||
| if Config.specialArgs: | |||
| for (k,v) in kw.items(): | |||
| @@ -514,7 +514,7 @@ class SOAPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | |||
| t = 'text/xml'; | |||
| if self.server.encoding != None: | |||
| t += '; charset="%s"' % self.server.encoding | |||
| t += '; charset=%s' % self.server.encoding | |||
| self.send_header("Content-type", t) | |||
| self.send_header("Content-length", str(len(resp))) | |||
| self.end_headers() | |||
| @@ -558,7 +558,7 @@ class SOAPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | |||
| self.connection.shutdown(1) | |||
| def do_GET(self): | |||
| #print 'command ', self.command | |||
| #print 'path ', self.path | |||
| #print 'request_version', self.request_version | |||
| @@ -567,7 +567,7 @@ class SOAPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | |||
| #print ' maintype', self.headers.maintype | |||
| #print ' subtype ', self.headers.subtype | |||
| #print ' params ', self.headers.plist | |||
| path = self.path.lower() | |||
| if path.endswith('wsdl'): | |||
| method = 'wsdl' | |||
| @@ -581,7 +581,7 @@ class SOAPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | |||
| l = method.split(".") | |||
| for i in l: | |||
| function = getattr(function, i) | |||
| if function: | |||
| self.send_response(200) | |||
| self.send_header("Content-type", 'text/plain') | |||
| @@ -589,7 +589,7 @@ class SOAPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | |||
| response = apply(function, ()) | |||
| self.wfile.write(str(response)) | |||
| return | |||
| # return error | |||
| self.send_response(200) | |||
| self.send_header("Content-type", 'text/html') | |||
| @@ -613,7 +613,7 @@ class SOAPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | |||
| </body>''') | |||
| def log_message(self, format, *args): | |||
| if self.server.log: | |||
| @@ -1,3 +1,5 @@ | |||
| from __future__ import nested_scopes | |||
| """ | |||
| ################################################################################ | |||
| # Copyright (c) 2003, Pfizer | |||
| @@ -32,12 +34,10 @@ | |||
| # | |||
| ################################################################################ | |||
| """ | |||
| from __future__ import nested_scopes | |||
| ident = '$Id: Types.py,v 1.19 2005/02/22 04:29:43 warnes Exp $' | |||
| ident = '$Id: Types.py 1496 2010-03-04 23:46:17Z pooryorick $' | |||
| from version import __version__ | |||
| import UserList | |||
| import base64 | |||
| import cgi | |||
| @@ -76,7 +76,7 @@ class anyType: | |||
| else: | |||
| self._ns = self._validURIs[0] | |||
| self._name = name | |||
| self._typed = typed | |||
| self._attrs = {} | |||
| @@ -142,7 +142,7 @@ class anyType: | |||
| value = unicode(value) | |||
| self._attrs[attr] = value | |||
| def _setAttrs(self, attrs): | |||
| if type(attrs) in (ListType, TupleType): | |||
| @@ -199,6 +199,10 @@ class stringType(anyType): | |||
| return data | |||
| def _marshalData(self): | |||
| return self._data | |||
| class untypedType(stringType): | |||
| def __init__(self, data = None, name = None, attrs = None): | |||
| stringType.__init__(self, data, name, 0, attrs) | |||
| @@ -588,9 +592,10 @@ class timeType(anyType): | |||
| def _marshalData(self): | |||
| if self._cache == None: | |||
| d = self._data | |||
| s = '' | |||
| s = time.strftime("%H:%M:%S", (0, 0, 0) + d + (0, 0, -1)) | |||
| #s = '' | |||
| # | |||
| #s = time.strftime("%H:%M:%S", (0, 0, 0) + d + (0, 0, -1)) | |||
| s = "%02d:%02d:%02d" % d | |||
| f = d[2] - int(d[2]) | |||
| if f != 0: | |||
| s += ("%g" % f)[1:] | |||
| @@ -1114,7 +1119,7 @@ class intType(anyType): | |||
| if type(data) not in (IntType, LongType) or \ | |||
| data < -2147483648L or \ | |||
| data > 2147483647: | |||
| data > 2147483647L: | |||
| raise ValueError, "invalid %s value" % self._type | |||
| return data | |||
| @@ -1275,7 +1280,7 @@ class compoundType(anyType): | |||
| retval[name] = getattr(self,name) | |||
| return retval | |||
| def __getitem__(self, item): | |||
| if type(item) == IntType: | |||
| return self.__dict__[self._keyord[item]] | |||
| @@ -1300,7 +1305,7 @@ class compoundType(anyType): | |||
| else: | |||
| self.__dict__[name] = value | |||
| self._keyord.append(name) | |||
| def _placeItem(self, name, value, pos, subpos = 0, attrs = None): | |||
| if subpos == 0 and type(self.__dict__[name]) != ListType: | |||
| @@ -1308,8 +1313,14 @@ class compoundType(anyType): | |||
| else: | |||
| self.__dict__[name][subpos] = value | |||
| self._keyord[pos] = name | |||
| # only add to key order list if it does not already | |||
| # exist in list | |||
| if not (name in self._keyord): | |||
| if pos < len(x): | |||
| self._keyord[pos] = name | |||
| else: | |||
| self._keyord.append(name) | |||
| def _getItemAsList(self, name, default = []): | |||
| try: | |||
| @@ -1421,10 +1432,10 @@ class arrayType(UserList.UserList, compoundType): | |||
| else: | |||
| retval = {} | |||
| def fun(x): retval[str(x).encode(encoding)] = self.data[x] | |||
| map( fun, range(len(self.data)) ) | |||
| return retval | |||
| def __getitem__(self, item): | |||
| try: | |||
| return self.data[int(item)] | |||
| @@ -1589,7 +1600,7 @@ class faultType(structType, Error): | |||
| __str__ = __repr__ | |||
| def __call__(self): | |||
| return (self.faultcode, self.faultstring, self.detail) | |||
| return (self.faultcode, self.faultstring, self.detail) | |||
| class SOAPException(Exception): | |||
| def __init__(self, code="", string="", detail=None): | |||
| @@ -1630,28 +1641,28 @@ class MethodFailed(Exception): | |||
| def __str__(self): | |||
| return repr(self.value) | |||
| ####### | |||
| # Convert complex SOAPpy objects to native python equivalents | |||
| ####### | |||
| def simplify(object, level=0): | |||
| """ | |||
| Convert the SOAPpy objects and thier contents to simple python types. | |||
| Convert the SOAPpy objects and their contents to simple python types. | |||
| This function recursively converts the passed 'container' object, | |||
| and all public subobjects. (Private subobjects have names that | |||
| start with '_'.) | |||
| Conversions: | |||
| - faultType --> raise python exception | |||
| - arrayType --> array | |||
| - compoundType --> dictionary | |||
| """ | |||
| if level > 10: | |||
| return object | |||
| if isinstance( object, faultType ): | |||
| if object.faultstring == "Required Header Misunderstood": | |||
| raise RequiredHeaderMismatch(object.detail) | |||
| @@ -1695,13 +1706,13 @@ def simplify_contents(object, level=0): | |||
| This function recursively converts the sub-objects contained in a | |||
| 'container' object to simple python types. | |||
| Conversions: | |||
| - faultType --> raise python exception | |||
| - arrayType --> array | |||
| - compoundType --> dictionary | |||
| """ | |||
| if level>10: return object | |||
| if isinstance( object, faultType ): | |||
| @@ -1709,7 +1720,7 @@ def simplify_contents(object, level=0): | |||
| if isPublic(k): | |||
| setattr(object, k, simplify(object[k], level=level+1)) | |||
| raise object | |||
| elif isinstance( object, arrayType ): | |||
| elif isinstance( object, arrayType ): | |||
| data = object._aslist() | |||
| for k in range(len(data)): | |||
| object[k] = simplify(data[k], level=level+1) | |||
| @@ -1730,7 +1741,7 @@ def simplify_contents(object, level=0): | |||
| elif type(object)==list: | |||
| for k in range(len(object)): | |||
| object[k] = simplify(object[k]) | |||
| return object | |||
| @@ -1,7 +1,7 @@ | |||
| """Provide a class for loading data from URL's that handles basic | |||
| authentication""" | |||
| ident = '$Id: URLopener.py,v 1.2 2004/01/31 04:20:06 warnes Exp $' | |||
| ident = '$Id: URLopener.py 541 2004-01-31 04:20:06Z warnes $' | |||
| from version import __version__ | |||
| from Config import Config | |||
| @@ -33,11 +33,9 @@ | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: Utilities.py,v 1.4 2004/01/31 04:20:06 warnes Exp $' | |||
| ident = '$Id: Utilities.py 1298 2006-11-07 00:54:15Z sanxiyn $' | |||
| from version import __version__ | |||
| import exceptions | |||
| import copy | |||
| import re | |||
| import string | |||
| import sys | |||
| @@ -2,10 +2,12 @@ | |||
| Rudimentary support.""" | |||
| ident = '$Id: WSDL.py,v 1.11 2005/02/21 20:16:15 warnes Exp $' | |||
| ident = '$Id: WSDL.py 1467 2008-05-16 23:32:51Z warnes $' | |||
| from version import __version__ | |||
| import wstools | |||
| import xml | |||
| from Errors import Error | |||
| from Client import SOAPProxy, SOAPAddress | |||
| from Config import Config | |||
| import urllib | |||
| @@ -39,8 +41,15 @@ class Proxy: | |||
| # From Mark Pilgrim's "Dive Into Python" toolkit.py--open anything. | |||
| if self.wsdl is None and hasattr(wsdlsource, "read"): | |||
| #print 'stream' | |||
| self.wsdl = reader.loadFromStream(wsdlsource) | |||
| print 'stream:', wsdlsource | |||
| try: | |||
| self.wsdl = reader.loadFromStream(wsdlsource) | |||
| except xml.parsers.expat.ExpatError, e: | |||
| newstream = urllib.urlopen(wsdlsource) | |||
| buf = newstream.readlines() | |||
| raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \ | |||
| (wsdlsource, "\t".join(buf)) | |||
| # NOT TESTED (as of April 17, 2003) | |||
| #if self.wsdl is None and wsdlsource == '-': | |||
| @@ -53,15 +62,24 @@ class Proxy: | |||
| file(wsdlsource) | |||
| self.wsdl = reader.loadFromFile(wsdlsource) | |||
| #print 'file' | |||
| except (IOError, OSError): | |||
| pass | |||
| except (IOError, OSError): pass | |||
| except xml.parsers.expat.ExpatError, e: | |||
| newstream = urllib.urlopen(wsdlsource) | |||
| buf = newstream.readlines() | |||
| raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \ | |||
| (wsdlsource, "\t".join(buf)) | |||
| if self.wsdl is None: | |||
| try: | |||
| stream = urllib.urlopen(wsdlsource) | |||
| self.wsdl = reader.loadFromStream(stream, wsdlsource) | |||
| except (IOError, OSError): pass | |||
| except xml.parsers.expat.ExpatError, e: | |||
| newstream = urllib.urlopen(wsdlsource) | |||
| buf = newstream.readlines() | |||
| raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \ | |||
| (wsdlsource, "\t".join(buf)) | |||
| if self.wsdl is None: | |||
| import StringIO | |||
| self.wsdl = reader.loadFromString(str(wsdlsource)) | |||
| @@ -1,3 +1,5 @@ | |||
| ident = '$Id: __init__.py 541 2004-01-31 04:20:06Z warnes $' | |||
| from version import __version__ | |||
| from Client import * | |||
| @@ -0,0 +1 @@ | |||
| *.pyc | |||
| @@ -3,7 +3,7 @@ | |||
| import string | |||
| import cgi | |||
| ident = '$Id: interop2html.py,v 1.1.1.1 2001/06/27 21:36:14 cullman Exp $' | |||
| ident = '$Id: interop2html.py 4 2001-06-27 21:36:11Z cullman $' | |||
| lines = open('output.txt').readlines() | |||
| #preserve the tally | |||
| @@ -0,0 +1 @@ | |||
| *.pyc | |||
| @@ -1,4 +1,4 @@ | |||
| $Id: server.pem,v 1.1.1.1 2001/06/27 21:36:14 cullman Exp $ | |||
| $Id: server.pem 4 2001-06-27 21:36:11Z cullman $ | |||
| # Test certificate generated using CA.pl written by Steve Hensen | |||
| # bundled with OpenSSL. | |||
| # | |||
| @@ -1,7 +1,7 @@ | |||
| # This list of servers was taken from the SOAPBuilders Interoperability Lab | |||
| # (http://www.xmethods.net/ilab/ilab.html) 4/23/01. | |||
| # | |||
| # $Id: silab.servers,v 1.1.1.1 2001/06/27 21:36:14 cullman Exp $ | |||
| # $Id: silab.servers 4 2001-06-27 21:36:11Z cullman $ | |||
| Name: SOAP.py 0.9.6 (1999) | |||
| Endpoint: http://208.177.157.221:9595/xmethodsInterop | |||
| @@ -21,7 +21,7 @@ from SOAPpy import SOAP | |||
| SOAP.Config.typesNamespace = SOAP.NS.XSD3 | |||
| SOAP.Config.typesNamespace = SOAP.NS.XSD3 | |||
| ident = '$Id: silabclient.py,v 1.2 2003/03/08 05:10:01 warnes Exp $' | |||
| ident = '$Id: silabclient.py 98 2003-03-08 05:10:01Z warnes $' | |||
| DEFAULT_SERVERS_FILE = 'silab.servers' | |||
| @@ -15,7 +15,7 @@ from SOAPpy import SOAP | |||
| if SOAP.Config.SSLserver: | |||
| from M2Crypto import SSL | |||
| ident = '$Id: silabserver.py,v 1.2 2003/03/08 05:10:01 warnes Exp $' | |||
| ident = '$Id: silabserver.py 98 2003-03-08 05:10:01Z warnes $' | |||
| def echoFloat (inputFloat): | |||
| return inputFloat | |||
| @@ -10,7 +10,7 @@ sys.path.insert (1, '..') | |||
| from SOAPpy import SOAP | |||
| ident = '$Id: soapware.py,v 1.2 2003/03/08 05:10:01 warnes Exp $' | |||
| ident = '$Id: soapware.py 98 2003-03-08 05:10:01Z warnes $' | |||
| def whichToolkit (): | |||
| return SOAP.SOAPUserAgent () | |||
| @@ -0,0 +1,28 @@ | |||
| Using SOAP with ZOPE | |||
| -------------------- | |||
| We can use Zope to provide web services. The first is to support SOAP like | |||
| XML-RPC. There are two patches for Zope 2.5.0 version and for Zope 2.6.2 | |||
| version. To apply the path, you only need to do: | |||
| $ cd <your home zope directory> | |||
| $ patch -p1 < /<patch directory>/zope-2.6.2-soappy.diff | |||
| You need to install SOAPpy and fpconst. You can download this two packages | |||
| from here: | |||
| http://sourceforge.net/projects/pywebsvcs | |||
| http://software.biostat.washington.edu/statsoft/snake/fpconst/ | |||
| If you are using the precompiled version of Zope, you need to add the path | |||
| to the PYTHONPATH environment variable to specify where this packages | |||
| lives. | |||
| To do this, add a line like this to your start script: | |||
| export PYTHONPATH=$PYTHONPATH:/usr/lib/python2.3/site-packages/ | |||
| Note: This can be dangerous because in your machine you are using several | |||
| versions of python. | |||
| [NB: The contents of this directory contributed by Antonio Beamud | |||
| Montero <antonio.beamud@linkend.com>] | |||
| @@ -0,0 +1,163 @@ | |||
| diff -urN Zope-2.5.0-linux2-x86/lib/python/ZPublisher/HTTPRequest.py Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py | |||
| --- Zope-2.5.0-linux2-x86/lib/python/ZPublisher/HTTPRequest.py 2002-01-03 20:41:05.000000000 +0100 | |||
| +++ Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py 2003-11-12 13:17:57.000000000 +0100 | |||
| @@ -21,6 +21,7 @@ | |||
| from Converters import get_converter | |||
| from maybe_lock import allocate_lock | |||
| xmlrpc=None # Placeholder for module that we'll import if we have to. | |||
| +soap=None | |||
| #cgi hotfix: | |||
| if not hasattr(cgi, 'valid_boundary'): | |||
| @@ -347,18 +348,28 @@ | |||
| meth=None | |||
| fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1) | |||
| if not hasattr(fs,'list') or fs.list is None: | |||
| - # Hm, maybe it's an XML-RPC | |||
| - if (fs.headers.has_key('content-type') and | |||
| - fs.headers['content-type'] == 'text/xml' and | |||
| + # Hm, maybe it's an XML-RPC or SOAP | |||
| + if (fs.headers.has_key('content-type') and | |||
| + fs.headers['content-type'][:8] == 'text/xml' and | |||
| method == 'POST'): | |||
| - # Ye haaa, XML-RPC! | |||
| - global xmlrpc | |||
| - if xmlrpc is None: import xmlrpc | |||
| - meth, self.args = xmlrpc.parse_input(fs.value) | |||
| - response=xmlrpc.response(response) | |||
| - other['RESPONSE']=self.response=response | |||
| - other['REQUEST_METHOD']='' # We don't want index_html! | |||
| - self.maybe_webdav_client = 0 | |||
| + if environ.has_key('HTTP_SOAPACTION'): | |||
| + # this is a SOAP request | |||
| + global soap | |||
| + if soap is None: | |||
| + import soap | |||
| + meth, self.args = soap.parse_input(fs.value) | |||
| + response = soap.response(response) | |||
| + other['RESPONSE'] = self.response = response | |||
| + other['REQUEST_METHOD'] = '' | |||
| + else: | |||
| + # Ye haaa, XML-RPC! | |||
| + global xmlrpc | |||
| + if xmlrpc is None: import xmlrpc | |||
| + meth, self.args = xmlrpc.parse_input(fs.value) | |||
| + response=xmlrpc.response(response) | |||
| + other['RESPONSE']=self.response=response | |||
| + other['REQUEST_METHOD']='' # We don't want index_html! | |||
| + self.maybe_webdav_client = 0 | |||
| else: | |||
| self._file=fs.file | |||
| else: | |||
| diff -urN Zope-2.5.0-linux2-x86/lib/python/ZPublisher/soap.py Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/soap.py | |||
| --- Zope-2.5.0-linux2-x86/lib/python/ZPublisher/soap.py 1970-01-01 01:00:00.000000000 +0100 | |||
| +++ Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/soap.py 2003-11-12 13:20:39.000000000 +0100 | |||
| @@ -0,0 +1,108 @@ | |||
| +"""SOAP support module | |||
| + | |||
| +by Antonio Beamud Montero <antonio.beamud@linkend.com> | |||
| + | |||
| +Based on the XML-RPC Zope support module written by Eric Kidd at UserLand | |||
| +software and the modifications made by Petru Paler, with much help | |||
| +from Jim Fulton at DC. | |||
| + | |||
| +This code hooks Zope up to SOAPpy library. | |||
| +""" | |||
| + | |||
| +import sys | |||
| +from string import replace | |||
| +from HTTPResponse import HTTPResponse | |||
| +from SOAPpy import * | |||
| +from zLOG import LOG, PROBLEM, ERROR, DEBUG, INFO,TRACE | |||
| + | |||
| +Config.specialArgs=0. | |||
| + | |||
| +def parse_input(data): | |||
| + """Parse input data and return a method path and argument tuple | |||
| + | |||
| + The data is a string. | |||
| + """ | |||
| + obj = Parser.parseSOAPRPC(data) | |||
| + method = obj._name | |||
| + args = tuple(obj._aslist) | |||
| + | |||
| + # Translate '.' to '/' in meth to represent object traversal. | |||
| + method = replace(method, '.', '/') | |||
| + return method, args | |||
| + | |||
| +####################################################################### | |||
| +# New Object response based on SOAPpy | |||
| +# | |||
| +class SOAPResponse: | |||
| + def __init__(self, real): self.__dict__['_real']=real | |||
| + def __getattr__(self, name): return getattr(self._real, name) | |||
| + def __setattr__(self, name, v): return setattr(self._real, name, v) | |||
| + def __delattr__(self, name): return delattr(self._real, name) | |||
| + | |||
| + def setBody(self, body, title='', is_error=0, bogus_str_search=None): | |||
| + # Marshall our body as an SOAP response. Strings will be sent | |||
| + # strings, integers as integers, etc. We do *not* convert | |||
| + # everything to a string first. | |||
| + status = 200 | |||
| + if isinstance(body, Types.faultType): | |||
| + status = 500 | |||
| + # Convert Fault object to SOAP response. | |||
| + soapbody = Types.faulType("%s:Server" % NS.ENV_T, body) | |||
| + body = buildSOAP(soapbody,encoding=None) | |||
| + else: | |||
| + try: | |||
| + body = buildSOAP((body,),encoding=None) | |||
| + except Exception,e: | |||
| + self.exception() | |||
| + return self | |||
| + | |||
| + t = 'text/xml' | |||
| + # Set our body to the XML-RPC message, and fix our MIME type. | |||
| + self._real.setBody(body) | |||
| + self._real.setHeader('content-type', t) | |||
| + self._real.setHeader("content-length", str(len(body))) | |||
| + self._real.setStatus(status) | |||
| + return self | |||
| + | |||
| + def exception(self, fatal=0, info=None, | |||
| + absuri_match=None, tag_search=None): | |||
| + # Fetch our exception info. t is type, v is value and tb is the | |||
| + # traceback object. | |||
| + | |||
| + if type(info) is type(()) and len(info)==3: t,v,tb = info | |||
| + else: t,v,tb = sys.exc_info() | |||
| + LOG('SOAPException', TRACE, tb) | |||
| + # Create an appropriate Fault object. Unfortunately, we throw away | |||
| + # most of the debugging information. More useful error reporting is | |||
| + # left as an exercise for the reader. | |||
| + Fault=Types.faultType | |||
| + f=None | |||
| + try: | |||
| + if isinstance(v, Fault): | |||
| + f=v | |||
| + elif isinstance(v, Exception): | |||
| + f=Fault("%s:Server" % NS.ENV_T, | |||
| + "Unexpected Zope exception: %s"%str(v)) | |||
| + else: | |||
| + f=Fault("%s:Server" % NS.ENV_T, | |||
| + "Unexpected Zope error value: %s"%str(v)) | |||
| + except: | |||
| + f=Fault("%s:Server" % NS.ENV_T, | |||
| + "Unknown Zope fault type") | |||
| + | |||
| + # Do the damage. | |||
| + body = buildSOAP(f) | |||
| + self._real.setBody(body) | |||
| + self._real.setHeader('content-type', 'text/xml') | |||
| + self._real.setStatus(500) | |||
| + return tb | |||
| + | |||
| +response=SOAPResponse | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| @@ -0,0 +1,175 @@ | |||
| diff -urN Zope-2.6.2-linux2-x86/lib/python/ZPublisher/HTTPRequest.py Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py | |||
| --- Zope-2.6.2-linux2-x86/lib/python/ZPublisher/HTTPRequest.py 2003-04-09 16:00:27.000000000 +0200 | |||
| +++ Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py 2003-11-12 14:51:01.000000000 +0100 | |||
| @@ -24,6 +24,7 @@ | |||
| from TaintedString import TaintedString | |||
| from maybe_lock import allocate_lock | |||
| xmlrpc=None # Placeholder for module that we'll import if we have to. | |||
| +soap=None # Placeholder for module that we'll import if we have to. | |||
| #cgi hotfix: | |||
| if not hasattr(cgi, 'valid_boundary'): | |||
| @@ -369,16 +370,26 @@ | |||
| meth=None | |||
| fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1) | |||
| if not hasattr(fs,'list') or fs.list is None: | |||
| - # Hm, maybe it's an XML-RPC | |||
| + # Hm, maybe it's an XML-RPC or SOAP | |||
| if (fs.headers.has_key('content-type') and | |||
| - fs.headers['content-type'] == 'text/xml' and | |||
| + fs.headers['content-type'][:8] == 'text/xml' and | |||
| method == 'POST'): | |||
| - # Ye haaa, XML-RPC! | |||
| - global xmlrpc | |||
| - if xmlrpc is None: import xmlrpc | |||
| - meth, self.args = xmlrpc.parse_input(fs.value) | |||
| - response=xmlrpc.response(response) | |||
| - other['RESPONSE']=self.response=response | |||
| + if environ.has_key('HTTP_SOAPACTION'): | |||
| + # this is a SOAP request | |||
| + global soap | |||
| + if soap is None: | |||
| + import soap | |||
| + meth, self.args = soap.parse_input(fs.value) | |||
| + response = soap.response(response) | |||
| + other['RESPONSE'] = self.response = response | |||
| + other['REQUEST_METHOD'] = '' | |||
| + else: | |||
| + # Ye haaa, XML-RPC! | |||
| + global xmlrpc | |||
| + if xmlrpc is None: import xmlrpc | |||
| + meth, self.args = xmlrpc.parse_input(fs.value) | |||
| + response=xmlrpc.response(response) | |||
| + other['RESPONSE']=self.response=response | |||
| self.maybe_webdav_client = 0 | |||
| else: | |||
| self._file=fs.file | |||
| diff -urN Zope-2.6.2-linux2-x86/lib/python/ZPublisher/soap.py Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/soap.py | |||
| --- Zope-2.6.2-linux2-x86/lib/python/ZPublisher/soap.py 1970-01-01 01:00:00.000000000 +0100 | |||
| +++ Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/soap.py 2003-11-12 14:51:01.000000000 +0100 | |||
| @@ -0,0 +1,125 @@ | |||
| +"""SOAP support module | |||
| + | |||
| +by Antonio Beamud Montero <antonio.beamud@linkend.com> | |||
| + | |||
| +Based on the XML-RPC Zope support module written by Eric Kidd at UserLand | |||
| +software and the modifications made by Petru Paler, with much help | |||
| +from Jim Fulton at DC. | |||
| + | |||
| +This code hooks Zope up to SOAPpy library. | |||
| +""" | |||
| + | |||
| +import sys | |||
| +from string import replace | |||
| +from HTTPResponse import HTTPResponse | |||
| +from SOAPpy import * | |||
| +from zLOG import LOG, PROBLEM, ERROR, DEBUG, INFO,TRACE | |||
| + | |||
| +Config.specialArgs=0. | |||
| + | |||
| +def parse_input(data): | |||
| + """Parse input data and return a method path and argument tuple | |||
| + | |||
| + The data is a string. | |||
| + """ | |||
| + obj = Parser.parseSOAPRPC(data) | |||
| + method = obj._name | |||
| + args = tuple(obj._aslist) | |||
| + | |||
| + # Translate '.' to '/' in meth to represent object traversal. | |||
| + method = replace(method, '.', '/') | |||
| + return method, args | |||
| + | |||
| +# See below | |||
| +# | |||
| +# def response(anHTTPResponse): | |||
| +# """Return a valid ZPublisher response object | |||
| +# | |||
| +# Use data already gathered by the existing response. | |||
| +# The new response will replace the existing response. | |||
| +# """ | |||
| +# # As a first cut, lets just clone the response and | |||
| +# # put all of the logic in our refined response class below. | |||
| +# r=Response() | |||
| +# r.__dict__.update(anHTTPResponse.__dict__) | |||
| +# return r | |||
| + | |||
| + | |||
| + | |||
| + | |||
| +####################################################################### | |||
| +# New Object response based on SoapPy | |||
| +# | |||
| +class SOAPResponse: | |||
| + def __init__(self, real): self.__dict__['_real']=real | |||
| + def __getattr__(self, name): return getattr(self._real, name) | |||
| + def __setattr__(self, name, v): return setattr(self._real, name, v) | |||
| + def __delattr__(self, name): return delattr(self._real, name) | |||
| + | |||
| + def setBody(self, body, title='', is_error=0, bogus_str_search=None): | |||
| + # Marshall our body as an SOAP response. Strings will be sent | |||
| + # strings, integers as integers, etc. We do *not* convert | |||
| + # everything to a string first. | |||
| + status = 200 | |||
| + if isinstance(body, Types.faultType): | |||
| + status = 500 | |||
| + # Convert Fault object to SOAP response. | |||
| + soapbody = Types.faulType("%s:Server" % NS.ENV_T, body) | |||
| + body = buildSOAP(soapbody,encoding=None) | |||
| + else: | |||
| + try: | |||
| + body = buildSOAP((body,),encoding=None) | |||
| + except Exception,e: | |||
| + self.exception() | |||
| + return self | |||
| + | |||
| + t = 'text/xml' | |||
| + # Set our body to the XML-RPC message, and fix our MIME type. | |||
| + self._real.setBody(body) | |||
| + self._real.setHeader('content-type', t) | |||
| + self._real.setHeader("content-length", str(len(body))) | |||
| + self._real.setStatus(status) | |||
| + return self | |||
| + | |||
| + def exception(self, fatal=0, info=None, | |||
| + absuri_match=None, tag_search=None): | |||
| + # Fetch our exception info. t is type, v is value and tb is the | |||
| + # traceback object. | |||
| + | |||
| + if type(info) is type(()) and len(info)==3: t,v,tb = info | |||
| + else: t,v,tb = sys.exc_info() | |||
| + LOG('SOAPException', TRACE, tb) | |||
| + # Create an appropriate Fault object. Unfortunately, we throw away | |||
| + # most of the debugging information. More useful error reporting is | |||
| + # left as an exercise for the reader. | |||
| + Fault=Types.faultType | |||
| + f=None | |||
| + try: | |||
| + if isinstance(v, Fault): | |||
| + f=v | |||
| + elif isinstance(v, Exception): | |||
| + f=Fault("%s:Server" % NS.ENV_T, | |||
| + "Unexpected Zope exception: %s"%str(v)) | |||
| + else: | |||
| + f=Fault("%s:Server" % NS.ENV_T, | |||
| + "Unexpected Zope error value: %s"%str(v)) | |||
| + except: | |||
| + f=Fault("%s:Server" % NS.ENV_T, | |||
| + "Unknown Zope fault type") | |||
| + | |||
| + # Do the damage. | |||
| + body = buildSOAP(f) | |||
| + self._real.setBody(body) | |||
| + self._real.setHeader('content-type', 'text/xml') | |||
| + self._real.setStatus(500) | |||
| + return tb | |||
| + | |||
| +response=SOAPResponse | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| @@ -0,0 +1,18 @@ | |||
| #!/usr/bin/env python | |||
| import sys | |||
| from SOAPpy import SOAP | |||
| # Uncomment to see outgoing HTTP headers and SOAP and incoming SOAP. | |||
| SOAP.Config.debug = 1 | |||
| SOAP.Config.BuildWithNoType = 0 | |||
| SOAP.Config.BuildWithNoNamespacePrefix = 0 | |||
| if len(sys.argv) > 1 and sys.argv[1] == '-s': | |||
| server = SOAP.SOAPProxy("https://localhost:8080") | |||
| else: | |||
| server = SOAP.SOAPProxy("http://admin:pw3340@localhost:8080/",encoding=None) | |||
| x = server.sopa() | |||
| print x | |||