[Zope-Checkins] CVS: Zope3/lib/python/Zope/Publisher/SOAP - ISOAPPublisher.py:1.1.2.1 MethodPublisher.py:1.1.2.1 SOAPPayload.py:1.1.2.1 __init__.py:1.1.2.1 metaConfigure.py:1.1.2.1 soap-meta.zcml:1.1.2.1 soaplib.py:1.1.2.1
Stephan Richter
srichter@cbu.edu
Wed, 13 Mar 2002 05:57:36 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Publisher/SOAP
In directory cvs.zope.org:/tmp/cvs-serv11175/lib/python/Zope/Publisher/SOAP
Added Files:
Tag: srichter-OFS_Formulator-branch
ISOAPPublisher.py MethodPublisher.py SOAPPayload.py
__init__.py metaConfigure.py soap-meta.zcml soaplib.py
Log Message:
- Added some more tests. Won;t do more, since Publisher is being redesigned
later this week. I will wait until then.
- Added preliminary SOAP support, so we can test Mozilla's SOAP
capabilities. Unfortunately, soaplib is very old; I will look into using
SOAPpy instead. It seems fairly complete.
=== Added File Zope3/lib/python/Zope/Publisher/SOAP/ISOAPPublisher.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
$Id: ISOAPPublisher.py,v 1.1.2.1 2002/03/13 10:57:34 srichter Exp $
"""
from Interface import Interface
class ISOAPPublisher(Interface):
"""This is very similar to the Browser version;
"""
def soap_traverse(request, name):
"""Lookup a name
"""
def soap_default(request):
"""Provide the default object
"""
=== Added File Zope3/lib/python/Zope/Publisher/SOAP/MethodPublisher.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
$Id: MethodPublisher.py,v 1.1.2.1 2002/03/13 10:57:34 srichter Exp $
"""
from ISOAPPublisher import ISOAPPublisher
class MethodPublisher:
__implements__ = ISOAPPublisher
# Implementation methods for interface
# Zope.Publisher.SOAP.ISOAPPublisher.
def soap_traverse(self, request, name):
'''See interface ISOAPPublisher'''
return getattr(self, name)
def soap_default(self, request):
'''See interface ISOAPPublisher'''
return self, ("info",)
=== Added File Zope3/lib/python/Zope/Publisher/SOAP/SOAPPayload.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
SOAP Request/Response Handler
$Id: SOAPPayload.py,v 1.1.2.1 2002/03/13 10:57:34 srichter Exp $
"""
from types import ClassType, ListType, StringType
from cgi import FieldStorage, escape
from Zope.Publisher.HTTP.cgi_names import hide_key
import soaplib
from Zope.Publisher.HTTP.IPayload import IRequestPayload, IResponsePayload
from Zope.Publisher.Converters import get_converter
from Zope.Publisher.Exceptions import Redirect, Unauthorized
from ISOAPPublisher import ISOAPPublisher
class SOAPRequestPayload:
"""
Works with the body of a XML-RPC request.
"""
__implements__ = IRequestPayload
_viewtype = ISOAPPublisher
def __init__(self, publication):
self.publication = publication
def processInputs(self, request, fs=None):
"""
Processes form data
"""
environ = request.environ
form = request.form
other = request.other
method = environ.get('REQUEST_METHOD', 'GET')
if fs is None:
if method != 'GET':
# Process form if not a GET request.
fp = request.body_instream
else:
fp = None
fs = FieldStorage(fp=fp, environ=environ, keep_blank_values=1)
# Parse the request XML structure
function, request.args = soaplib.loads(fs.value)
print request.args
print function
# Translate '.' to '/' in function to represent object traversal.
function = function.replace('.', '/')
other['REQUEST_METHOD']='' # We don't want index_html!
other.update(form)
if function:
request.setRequestDefault(function)
def getPublication(self, request):
return self.publication
def debugInfo(self, request):
result = "<p>URL: %s</p>" % request.URL
result = result + "<p>SERVER_URL: %s</p>" % request.SERVER_URL
return result
def setViewType(self, viewtype):
self._viewtype = viewtype
def getViewType(self):
return self._viewtype
class SOAPResponsePayload:
"""Customized Response that handles XML-RPC-specific details.
We override setBody to marhsall Python objects into XML-RPC. We
also override exception to convert errors to XML-RPC faults.
If these methods stop getting called, make sure that ZPublisher is
using the soap.Response object created above and not the original
HTTPResponse object from which it was cloned.
It's probably possible to improve the 'exception' method quite a bit.
The current implementation, however, should suffice for now.
"""
__implements__ = IResponsePayload
def setBody(self, response, body):
""" """
if isinstance(body, soaplib.Fault):
# Convert Fault object to XML-RPC response.
body = soaplib.dumps(body, envelope=1)
else:
try:
body = soaplib.dumps((body,), envelope=1)
except:
self.exception()
return
# Set our body to the XML-RPC message, and fix our MIME type.
response.body = body
# client identifier (may be overridden)
user_agent = "soaplib.py/0.8 (from www.pythonware.com)"
# required by SOAP
response.setHeader("User-Agent", user_agent)
response.setHeader("Content-Type", "text/xml")
response.setHeader("Content-Length", str(len(body)))
response.setHeader("SOAPAction", '""')
return response
def handleException(self, response, exc_info):
"""
"""
t, value = exc_info[:2]
import traceback
traceback.print_tb(exc_info[2])
print t
print value
# 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 = soaplib.Fault
fault_text = None
try:
if isinstance(value, Fault):
fault_text = value
elif isinstance(value, Exception):
fault_text = Fault(-1, "Unexpected Zope exception: " + str(value))
else:
fault_text = Fault(-2, "Unexpected Zope error value: " + str(value))
except:
fault_text = Fault(-3, "Unknown Zope fault type")
# Do the damage.
response.setBody(fault_text)
response.setStatus(200)
=== Added File Zope3/lib/python/Zope/Publisher/SOAP/__init__.py ===
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#from IBrowserPublisher import IBrowserPublisher
=== Added File Zope3/lib/python/Zope/Publisher/SOAP/metaConfigure.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
$Id: metaConfigure.py,v 1.1.2.1 2002/03/13 10:57:34 srichter Exp $
"""
from Zope.ComponentArchitecture import provideView, setDefaultViewName
from Zope.Configuration.name import resolve
from Zope.Configuration.Action import Action
from ISOAPPublisher import ISOAPPublisher
def defaultView(name, factory, for_=None, layer=''):
if for_ is not None:
for_ = resolve(for_)
factory = map(resolve, factory.split(' '))
return [
Action(
discriminator = ('view', for_, name, ISOAPPublisher),
callable = provideView,
args = (for_, name, ISOAPPublisher, factory, layer),
),
Action(
discriminator = ('defaultViewName', for_, name, ISOAPPublisher),
callable = setDefaultViewName,
args = (for_, ISOAPPublisher, name),
)
]
def view(name, factory, for_=None, layer=''):
if for_ is not None:
for_ = resolve(for_)
factory = map(resolve, factory.split(' '))
return [
Action(
discriminator = ('view', for_, name, ISOAPPublisher, layer),
callable = provideView,
args = (for_, name, ISOAPPublisher, factory, layer),
)
]
=== Added File Zope3/lib/python/Zope/Publisher/SOAP/soap-meta.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
<!-- Zope.Publisher.SOAP -->
<directives namespace="http://namespaces.zope.org/soap">
<directive name="view" attributes="factory, name, for"
handler="Zope.Publisher.SOAP.metaConfigure.view" />
<directive name="defaultView" attributes="factory, name, for"
handler="Zope.Publisher.SOAP.metaConfigure.defaultView" />
</directives>
</zopeConfigure>
=== Added File Zope3/lib/python/Zope/Publisher/SOAP/soaplib.py === (769/869 lines abridged)
#
# SOAP CLIENT LIBRARY
# $Id: soaplib.py,v 1.1.2.1 2002/03/13 10:57:34 srichter Exp $
#
# an SOAP 1.1 client interface for Python.
#
# the marshalling and response parser code can also be used to
# implement SOAP servers.
#
# Notes:
# this version uses the sgmlop XML parser, if installed. this is
# typically 10-15x faster than using Python's standard XML parser.
#
# you can get the sgmlop distribution from:
#
# http://www.pythonware.com/products/xml
#
# also note that this version is designed to work with Python 1.5.2
# and newer. it does not work under 1.5.1 or earlier.
#
# Contact:
# fredrik@pythonware.com
# http://www.pythonware.com
#
# History:
# 2000-01-05 fl First experimental version (based on xmlrpclib.py)
# 2000-02-15 fl Updated to SOAP 1.0
# 2000-04-30 fl Major overhaul, updated for SOAP 1.1
# 2000-05-27 fl Fixed xmllib support
# 2000-06-20 fl Frontier interoperability testing
#
# Copyright (c) 1999-2000 by Secret Labs AB.
# Copyright (c) 1999-2000 by Fredrik Lundh.
#
# Portions of this engine have been developed in cooperation with
# Loudcloud, Inc.
#
# --------------------------------------------------------------------
# The soaplib.py library is
#
# Copyright (c) 1999-2000 by Secret Labs AB
# Copyright (c) 1999-2000 by Fredrik Lundh
#
# By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions:
#
# Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in
[-=- -=- -=- 769 lines omitted -=- -=- -=-]
def _defmethod(self, methodname, namespace):
# associate information with a remote methodname
self.__methods[methodname] = namespace
def __request(self, methodname, pargs, kwargs):
# call a method on the remote server
# wrap the arguments up
params = MethodCall(
methodname, self.__methods.get(methodname), pargs, kwargs
)
request = dumps(params, 1)
response = self.__transport.request(
self.__host,
self.__handler,
request
)
return response
def __repr__(self):
return (
"<Server proxy for %s%s>" %
(self.__host, self.__handler)
)
__str__ = __repr__
def __getattr__(self, name):
# magic method dispatcher
return _Method(self.__request, name)
def __getitem__(self, name):
# alternate method dispatcher
return _Method(self.__request, name)
# xmlrpclib compatibility
Server = ServerProxy