brpclib.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # by Greg Hazel
  2. import xmlrpclib
  3. from xmlrpclib2 import *
  4. from BTL import brpc
  5. old_PyCurlTransport = PyCurlTransport
  6. class PyCurlTransport(old_PyCurlTransport):
  7. def set_connection_params(self, h):
  8. h.add_header('User-Agent', "brpclib.py/1.0")
  9. h.add_header('Connection', "Keep-Alive")
  10. h.add_header('Content-Type', "application/octet-stream")
  11. def _parse_response(self, response):
  12. # read response from input file/socket, and parse it
  13. return brpc.loads(response.getvalue())[0]
  14. # --------------------------------------------------------------------
  15. # request dispatcher
  16. class _Method:
  17. # some magic to bind an B-RPC method to an RPC server.
  18. # supports "nested" methods (e.g. examples.getStateName)
  19. def __init__(self, send, name):
  20. self.__send = send
  21. self.__name = name
  22. def __getattr__(self, name):
  23. return _Method(self.__send, "%s.%s" % (self.__name, name))
  24. def __call__(self, *args, **kwargs):
  25. args = (args, kwargs)
  26. return self.__send(self.__name, args)
  27. # ARG! prevent repr(_Method()) from submiting an RPC call!
  28. def __repr__(self):
  29. return "<%s instance at 0x%08X>" % (self.__class__, id(self))
  30. # Double underscore is BAD!
  31. class BRPC_ServerProxy(xmlrpclib.ServerProxy):
  32. """uri [,options] -> a logical connection to an B-RPC server
  33. uri is the connection point on the server, given as
  34. scheme://host/target.
  35. The standard implementation always supports the "http" scheme. If
  36. SSL socket support is available (Python 2.0), it also supports
  37. "https".
  38. If the target part and the slash preceding it are both omitted,
  39. "/RPC2" is assumed.
  40. The following options can be given as keyword arguments:
  41. transport: a transport factory
  42. encoding: the request encoding (default is UTF-8)
  43. All 8-bit strings passed to the server proxy are assumed to use
  44. the given encoding.
  45. """
  46. def __init__(self, uri, transport=None, encoding=None, verbose=0,
  47. allow_none=0):
  48. # establish a "logical" server connection
  49. # get the url
  50. import urllib
  51. type, uri = urllib.splittype(uri)
  52. if type not in ("http", "https"):
  53. raise IOError, "unsupported B-RPC protocol"
  54. self.__host, self.__handler = urllib.splithost(uri)
  55. if not self.__handler:
  56. self.__handler = "/RPC2"
  57. if transport is None:
  58. if type == "https":
  59. transport = xmlrpclib.SafeTransport()
  60. else:
  61. transport = xmlrpclib.Transport()
  62. self.__transport = transport
  63. self.__encoding = encoding
  64. self.__verbose = verbose
  65. self.__allow_none = allow_none
  66. def __request(self, methodname, params):
  67. # call a method on the remote server
  68. request = brpc.dumps(params, methodname, encoding=self.__encoding,
  69. allow_none=self.__allow_none)
  70. response = self.__transport.request(
  71. self.__host,
  72. self.__handler,
  73. request,
  74. verbose=self.__verbose
  75. )
  76. if len(response) == 1:
  77. response = response[0]
  78. return response
  79. def __repr__(self):
  80. return (
  81. "<ServerProxy for %s%s>" %
  82. (self.__host, self.__handler)
  83. )
  84. __str__ = __repr__
  85. def __getattr__(self, name):
  86. # magic method dispatcher
  87. return _Method(self.__request, name)
  88. def new_server_proxy(url):
  89. c = cache_set.get_cache(PyCURL_Cache, url)
  90. t = PyCurlTransport(c)
  91. return BRPC_ServerProxy(url, transport=t)
  92. ServerProxy = new_server_proxy
  93. if __name__ == '__main__':
  94. s = ServerProxy('https://greg.mitte.bittorrent.com:7080/')
  95. def ping(*a, **kw):
  96. (a2, kw2) = s.ping(*a, **kw)
  97. assert a2 == list(a), '%s list is not %s' % (r, list(a))
  98. assert kw2 == dict(kw), '%s dict is not %s' % (kw2, dict(kw))
  99. ping(0, 1, 1, name="potato")
  100. ping(0, 1, 1, name="anime")
  101. ping("phish", 0, 1, 1)
  102. ping("games", 0, 1, 1)