# HG changeset patch # User Edwin Zhai # Date 1170406736 -28800 # Node ID 6e6878bc6789fe0e1add4baf67231c8083f56e69 # Parent ee9f4ddf517fe88e0e05ef7ad76c42e37a9696e0 fix python exception of int exceed limit on 64b machine diff -r ee9f4ddf517f -r 6e6878bc6789 tools/python/xen/util/xmlrpclib2.py --- a/tools/python/xen/util/xmlrpclib2.py Fri Feb 02 15:24:17 2007 +0800 +++ b/tools/python/xen/util/xmlrpclib2.py Fri Feb 02 16:58:56 2007 +0800 @@ -27,9 +27,11 @@ from types import * from httplib import HTTPConnection, HTTP +from xmlrpclib import Fault from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler import SocketServer -import xmlrpclib, socket, os, stat +import xmlrpclib, socket, os, stat, traceback, string +from types import * import mkdir @@ -69,6 +71,9 @@ def stringify(value): # httpu:///absolute/path/to/socket.sock # # It assumes that the RPC handler is /RPC2. This probably needs to be improved + +MAXINT = 2L**31-1 +MININT = -2L**31 # We're forced to subclass the RequestHandler class so that we can work around # some bugs in Keep-Alive handling and also enabled it by default @@ -159,6 +164,67 @@ class ServerProxy(xmlrpclib.ServerProxy) return conv_string(response) +class Marshaller(xmlrpclib.Marshaller): + def __init__(self, encoding=None, allow_none=0): + xmlrpclib.Marshaller.__init__(self, encoding, allow_none) + self.dispatch[IntType] = Marshaller.dump_int + self.dispatch[LongType] = Marshaller.dump_long + + def dump_int(self, value, write): + if value > MAXINT or value < MININT: + self.dispatch[StringType](self, str(value), write) + else: + xmlrpclib.Marshaller.dump_int(self, value, write) + + def dump_long(self, value, write): + if value > MAXINT or value < MININT: + self.dispatch[StringType](self, str(value), write) + else: + xmlrpclib.Marshaller.dump_long(self, value, write) + +def dumps(params, methodname=None, methodresponse=None, encoding=None, + allow_none=0): + assert isinstance(params, TupleType) or isinstance(params, Fault),\ + "argument must be tuple or Fault instance" + + if isinstance(params, Fault): + methodresponse = 1 + elif methodresponse and isinstance(params, TupleType): + assert len(params) == 1, "response tuple must be a singleton" + + if not encoding: + encoding = "utf-8" + + m = Marshaller(encoding, allow_none) + + data = m.dumps(params) + + if encoding != "utf-8": + xmlheader = "\n" % str(encoding) + else: + xmlheader = "\n" # utf-8 is default + + if methodname: + if not isinstance(methodname, StringType): + methodname = methodname.encode(encoding) + data = ( + xmlheader, + "\n" + "", methodname, "\n", + data, + "\n" + ) + elif methodresponse: + data = ( + xmlheader, + "\n", + data, + "\n" + ) + else: + return data + return string.join(data, "") + # This is a base XML-RPC server for TCP. It sets allow_reuse_address to # true, and has an improved marshaller that logs and serializes exceptions. @@ -212,11 +278,11 @@ class TCPXMLRPCServer(SocketServer.Threa response = repr(response)[1:-1] response = (response,) - response = xmlrpclib.dumps(response, - methodresponse=1, - allow_none=1) + response = dumps(response, + methodresponse=1, + allow_none=1) except xmlrpclib.Fault, fault: - response = xmlrpclib.dumps(fault) + response = dumps(fault) except Exception, exn: if self.xenapi: if _is_not_supported(exn): @@ -224,14 +290,14 @@ class TCPXMLRPCServer(SocketServer.Threa else: log.exception('Internal error handling %s', method) errdesc = ['INTERNAL_ERROR', str(exn)] - response = xmlrpclib.dumps( + response = dumps( ({ "Status": "Failure", "ErrorDescription": errdesc },), methodresponse = 1) else: log.exception('Internal error handling %s', method) import xen.xend.XendClient - response = xmlrpclib.dumps( + response = dumps( xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn))) return response