>From http://docs.python.org/library/xmlrpclib.html: When passing strings, characters special to XML such as <, >, and & will be automatically escaped. However, it’s the caller’s responsibility to ensure that the string is free of characters that aren’t allowed in XML, such as the control characters with ASCII values between 0 and 31 (except, of course, tab, newline and carriage return); failing to do this will result in an XML-RPC request that isn’t well-formed XML. If you have to pass arbitrary strings via XML-RPC, use the Binary wrapper class --- func/minion/server.py | 9 ++++++++- func/overlord/client.py | 4 +++- func/utils.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/func/minion/server.py b/func/minion/server.py index fbe5c4b..27b4181 100644 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -201,7 +201,14 @@ class FuncApiMethod: rc = utils.nice_exception(t,v,tb) self.logger.debug("Return code for %s: %s" % (self.__name, rc)) - return rc + if self.__name == 'jobs.job_status': + # don't double-encode (which ultimately ends up being a no-op, + # since deep_base64(deep_base64(foo)) == foo + # the return value stored by jobthing is already encoded at this + # point + return rc + else: + return futils.deep_base64(rc) def serve(): diff --git a/func/overlord/client.py b/func/overlord/client.py index e011929..4b8c689 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -649,7 +649,9 @@ class Overlord(object): if self.interactive: print retval - + + retval = func_utils.deep_base64(retval) + except Exception, e: (t, v, tb) = sys.exc_info() retval = utils.nice_exception(t,v,tb) diff --git a/func/utils.py b/func/utils.py index 75ac368..011b902 100644 --- a/func/utils.py +++ b/func/utils.py @@ -168,6 +168,34 @@ def should_log(args): return True return False +def deep_base64(ds): + """ + Run through an arbitrary datastructure of dicts / lists / tuples + to find all strings and base 64 encode/decode them with + xmlrpclib.Binary objects. + """ + from xmlrpclib import Binary + + if isinstance(ds, Binary): + return ds.data + + if isinstance(ds, basestring): + return Binary(ds) + + if isinstance(ds, list) or isinstance(ds, tuple): + cleaned = map(lambda x: deep_base64(x), ds) + if isinstance(ds, tuple): + cleaned = tuple(cleaned) + return cleaned + + if isinstance(ds, dict): + cleaned = {} + for k,v in ds.iteritems(): + cleaned[deep_base64(k)] = deep_base64(v) + return cleaned + + return ds + #################### PROGRESS BAR ################################## # The code below can be used for progress bar purposes as we will do #it is a combination of http://code.activestate.com/recipes/168639/ and -- 1.6.6 _______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list