@@ -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 |