XMLRPC publisher

Pre-marshal / Proxy removal

>>> sample = {'foo': (1, ['x', 'y', 1.2])}

if we put the sample in a security proxy:

>>> from zope.security.checker import ProxyFactory
>>> proxied_sample = ProxyFactory(sample)

We can still get to the data, but the non-rock data is proxied:

>>> from zope.security.proxy import Proxy
>>> proxied_sample['foo']
(1, ['x', 'y', 1.2])
>>> type(proxied_sample['foo']) is Proxy
True
>>> type(proxied_sample['foo'][1]) is Proxy
True

But we can strip the proxies using premarshal:

>>> from zope.publisher.xmlrpc import premarshal
>>> stripped = premarshal(proxied_sample)
>>> stripped
{'foo': [1, ['x', 'y', 1.2]]}
>>> type(stripped['foo']) is Proxy
False
>>> type(stripped['foo'][1]) is Proxy
False

So xmlrpclib will be happy. :)

Import xmlrpclib depending on current python interpreter version

>>> import sys
>>> if sys.version_info[0] == 2:
...     import xmlrpclib
... else:
...     import xmlrpc.client as xmlrpclib

We can also use premarshal to strip proxies off of Fault objects. We have to make a security declaration first though:

>>> fault = xmlrpclib.Fault(1, 'waaa')
>>> proxied_fault = ProxyFactory(fault)
>>> stripped_fault = premarshal(proxied_fault)
>>> type(stripped_fault) is Proxy
False

Standard python datetime objects are also handled:

>>> import datetime
>>> sample = datetime.datetime(2006,6,17,21,41,00)
>>> stripped_date = premarshal(sample)
>>> isinstance(stripped_date, datetime.datetime)
False
>>> isinstance(stripped_date, xmlrpclib.DateTime)
True

We can also use premarshal to strip proxies off of Binary objects. We have to make a security declaration first though:

>>> binary = xmlrpclib.Binary(b'foobar')
>>> proxied_binary = ProxyFactory(binary)
>>> stripped_binary = premarshal(proxied_binary)
>>> type(stripped_binary) is Proxy
False

Interfaces

Interfaces for the XMLRPC publisher.

interface zope.publisher.interfaces.xmlrpc.IXMLRPCPublisher[source]

Extends: zope.publisher.interfaces.IPublishTraverse

XML-RPC Publisher

interface zope.publisher.interfaces.xmlrpc.IXMLRPCPublication[source]

Extends: zope.publisher.interfaces.IPublication

Object publication framework.

getDefaultTraversal(request, ob)

Get the default published object for the request

Allows a default view to be added to traversal. Returns (ob, steps_reversed).

interface zope.publisher.interfaces.xmlrpc.IXMLRPCRequest[source]

Extends: zope.publisher.interfaces.http.IHTTPRequest

XML-RPC Request

interface zope.publisher.interfaces.xmlrpc.IXMLRPCView[source]

Extends: zope.browser.interfaces.IView

XMLRPC View

interface zope.publisher.interfaces.xmlrpc.IXMLRPCPremarshaller[source]

Pre-Marshaller to remove proxies for xmlrpclib

__call__(self)

Return the given object without proxies.

Implementation

XML-RPC Publisher

This module contains the XMLRPCRequest and XMLRPCResponse

class zope.publisher.xmlrpc.XMLRPCResponse[source]

Bases: zope.publisher.http.HTTPResponse

XMLRPC response.

This object is responsible for converting all output to valid XML-RPC.

setResult(result)[source]

Sets the result of the response

Sets the return body equal to the (string) argument “body”. Also updates the “content-length” return header.

If the body is a 2-element tuple, then it will be treated as (title,body)

If is_error is true then the HTML will be formatted as a Zope error message instead of a generic HTML page.

handleException(exc_info)[source]

Handle Errors during publsihing and wrap it in XML-RPC XML

>>> import sys
>>> resp = XMLRPCResponse()
>>> try:
...     raise AttributeError('xyz')
... except:
...     exc_info = sys.exc_info()
...     resp.handleException(exc_info)
>>> resp.getStatusString()
'200 OK'
>>> resp.getHeader('content-type')
'text/xml;charset=utf-8'
>>> body = ''.join(resp.consumeBody())
>>> 'Unexpected Zope exception: AttributeError: xyz' in body
True
class zope.publisher.xmlrpc.XMLRPCView(context, request)[source]

Bases: object

A base XML-RPC view that can be used as mix-in for XML-RPC views.

class zope.publisher.xmlrpc.PreMarshallerBase(data)[source]

Bases: object

Abstract base class for pre-marshallers.

class zope.publisher.xmlrpc.DictPreMarshaller(data)[source]

Bases: zope.publisher.xmlrpc.PreMarshallerBase

Pre-marshaller for dicts

class zope.publisher.xmlrpc.ListPreMarshaller(data)[source]

Bases: zope.publisher.xmlrpc.PreMarshallerBase

Pre-marshaller for list

class zope.publisher.xmlrpc.BinaryPreMarshaller(data)[source]

Bases: zope.publisher.xmlrpc.PreMarshallerBase

Pre-marshaller for xmlrpc.Binary

class zope.publisher.xmlrpc.FaultPreMarshaller(data)[source]

Bases: zope.publisher.xmlrpc.PreMarshallerBase

Pre-marshaller for xmlrpc.Fault

class zope.publisher.xmlrpc.DateTimePreMarshaller(data)[source]

Bases: zope.publisher.xmlrpc.PreMarshallerBase

Pre-marshaller for xmlrpc.DateTime

class zope.publisher.xmlrpc.PythonDateTimePreMarshaller(data)[source]

Bases: zope.publisher.xmlrpc.PreMarshallerBase

Pre-marshaller for datetime.datetime

zope.publisher.xmlrpc.premarshal(data)[source]

Premarshal data before handing it to xmlrpclib for marhalling

The initial purpose of this function is to remove security proxies without resorting to removeSecurityProxy. This way, we can avoid inadvertently providing access to data that should be protected.