From cfe4ec2175c42f208ae23401991febb8525bdd9b Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 19 Nov 2008 16:11:23 -0700 Subject: Added util.xmlrpc_wrap(), util.xmlrpc_unwrap() functions an corresponding unit tests --- ipalib/util.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'ipalib/util.py') diff --git a/ipalib/util.py b/ipalib/util.py index 89e2c5a74..60b9409fa 100644 --- a/ipalib/util.py +++ b/ipalib/util.py @@ -27,9 +27,12 @@ import imp import optparse import logging import time +from types import NoneType +from xmlrpclib import Binary import krbV + def xmlrpc_marshal(*args, **kw): """ Marshal (args, kw) into ((kw,) + args). @@ -56,6 +59,67 @@ def xmlrpc_unmarshal(*params): return (params[1:], kw) +def xmlrpc_wrap(value): + """ + Wrap all ``str`` in ``xmlrpclib.Binary``. + + Because ``xmlrpclib.dumps()`` will itself convert all ``unicode`` instances + into UTF-8 encoded ``str`` instances, we don't do it here. + + So in total, when encoding data for an XML-RPC request, the following + transformations occur: + + * All ``str`` instances are treated as binary data and are wrapped in + an ``xmlrpclib.Binary()`` instance. + + * Only ``unicode`` instances are treated as character data. They get + converted to UTF-8 encoded ``str`` instances (although as mentioned, + not by this function). + + Also see `xmlrpc_unwrap`. + """ + if type(value) in (list, tuple): + return tuple(xmlrpc_wrap(v) for v in value) + if type(value) is dict: + return dict( + (k, xmlrpc_wrap(v)) for (k, v) in value.iteritems() + ) + if type(value) is str: + return Binary(value) + assert type(value) in (unicode, int, float, bool, NoneType) + return value + + +def xmlrpc_unwrap(value, encoding='UTF-8'): + """ + Unwrap all ``xmlrpc.Binary``, decode all ``str`` into ``unicode``. + + When decoding data from an XML-RPC request, the following transformations + occur: + + * The binary payloads of all ``xmlrpclib.Binary`` instances are + returned as ``str`` instances. + + * All ``str`` instances are treated as UTF-8 encoded character data. + They are decoded and the resulting ``unicode`` instance is returned. + + Also see `xmlrpc_wrap`. + """ + if type(value) in (list, tuple): + return tuple(xmlrpc_unwrap(v, encoding) for v in value) + if type(value) is dict: + return dict( + (k, xmlrpc_unwrap(v, encoding)) for (k, v) in value.iteritems() + ) + if type(value) is str: + return value.decode(encoding) + if isinstance(value, Binary): + assert type(value.data) is str + return value.data + assert type(value) in (int, float, bool, NoneType) + return value + + def get_current_principal(): try: return krbV.default_context().default_ccache().principal().name -- cgit