extras-buildsys/common AuthedXMLRPCServer.py, 1.2, 1.3 XMLRPCServerProxy.py, 1.3, 1.4
Daniel Williams (dcbw)
fedora-extras-commits at redhat.com
Sun Jul 10 03:44:39 UTC 2005
- Previous message: extras-buildsys/client client.py,1.9,1.10
- Next message: extras-buildsys/server Builder.py, 1.3, 1.4 User.py, 1.3, 1.4 UserInterface.py, 1.16, 1.17 main.py, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: dcbw
Update of /cvs/fedora/extras-buildsys/common
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv19340/common
Modified Files:
AuthedXMLRPCServer.py XMLRPCServerProxy.py
Log Message:
2005-07-09 Dan Williams <dcbw at redhat.com>
* Rework the authorization framework so we don't need to
subclass/override subclass so much stuff
* Make the specfile Python version independent
Index: AuthedXMLRPCServer.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/AuthedXMLRPCServer.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AuthedXMLRPCServer.py 6 Jul 2005 21:20:55 -0000 1.2
+++ AuthedXMLRPCServer.py 10 Jul 2005 03:44:36 -0000 1.3
@@ -12,8 +12,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-# Copyright 2005 Konstantin Ryabitsev <icon at phy.duke.edu>
-# Modified by Dan Williams <dcbw at redhat.com>
+# Copyright 2005 Dan Williams <dcbw at redhat.com> and Red Hat, Inc.
+
import os, sys
import socket
@@ -22,6 +22,44 @@
import xmlrpclib
import SimpleXMLRPCServer
import SSLCommon
+import threading
+
+
+
+"""
+So we need a way of getting data from the RequestHandler instance, which
+is unique to each request, into the actual handler instance that we've registered.
+
+To do this without overriding a bunch of member functions, we have a global
+dict of data that maps authorization info to a particular thread, since each
+request is handled in its own thread. Therefore, the handler instance can
+access the data that our request handler has set.
+
+"""
+
+__authinfos_lock = threading.Lock()
+__authinfos = {}
+
+
+def _add_authinfo(authinfo):
+ __authinfos_lock.acquire()
+ __authinfos[threading.currentThread()] = authinfo
+ __authinfos_lock.release()
+
+def get_authinfo():
+ i = None
+ __authinfos_lock.acquire()
+ try:
+ i = __authinfos[threading.currentThread()]
+ except KeyError:
+ pass
+ __authinfos_lock.release()
+ return i
+
+def _del_authinfo():
+ __authinfos_lock.acquire()
+ del __authinfos[threading.currentThread()]
+ __authinfos_lock.release()
class AuthedSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
@@ -32,50 +70,10 @@
protocol_version = "HTTP/1.1"
def do_POST(self):
- """
- See documentation on SimpleXMLRPCRequestHandler. Modifications
- include the ability to pass through local request-specific data,
- and removal of code to deal with historical _dispatch methods.
- """
-
- if 0:
- # ONLY FOR DEBUGGING, so we can see exceptions on the console
- # get arguments
- data = self.rfile.read(int(self.headers["content-length"]))
- authinfo = self.server.get_authinfo(self.request, self.client_address)
- response = self.server._marshaled_dispatch(data, authinfo)
-
- # got a valid XML RPC response
- self.send_response(200)
- self.send_header("Content-type", "text/xml")
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- self.wfile.write(response)
-
- # shut down the connection
- self.wfile.flush()
- self.connection.shutdown(1)
- else:
- try:
- # get arguments
- data = self.rfile.read(int(self.headers["content-length"]))
- authinfo = self.server.get_authinfo(self.request, self.client_address)
- response = self.server._marshaled_dispatch(data, authinfo)
- except: # This should only happen if the module is buggy
- # internal error, report as HTTP server error
- self.send_response(500)
- self.end_headers()
- else:
- # got a valid XML RPC response
- self.send_response(200)
- self.send_header("Content-type", "text/xml")
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- self.wfile.write(response)
-
- # shut down the connection
- self.wfile.flush()
- self.connection.shutdown(1)
+ authinfo = self.server.get_authinfo(self.request, self.client_address)
+ _add_authinfo(authinfo)
+ SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self)
+ _del_authinfo()
class BaseAuthedXMLRPCServer:
@@ -92,68 +90,6 @@
return self.authinfo_callback(request, client_address)
return None
- def verify_request(self, request, client_address):
- return True
-
- def _marshaled_dispatch(self, data, authinfo):
- """
- Allow the ability to pass request-dependent objects into
- the handler instance.
- """
- params, method = xmlrpclib.loads(data)
-
- # generate response
- try:
- response = self._dispatch(authinfo, method, params)
- # wrap response in a singleton tuple
- response = (response,)
- response = xmlrpclib.dumps(response, methodresponse=1)
- except xmlrpclib.Fault, fault:
- response = xmlrpclib.dumps(fault)
- except:
- # report exception back to server
- response = xmlrpclib.dumps(
- xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
- )
-
- return response
-
- def _dispatch(self, authinfo, method, params):
- """
- Allow the ability to pass request-dependent objects into
- the handler instance.
- """
- func = None
- try:
- # check to see if a matching function has been registered
- func = self.funcs[method]
- except KeyError:
- if self.instance is not None:
- # call instance method directly
- try:
- func = self.lcl_resolve_dotted_attribute(method)
- except AttributeError:
- pass
-
- if func is not None:
- # Only pass authinfo into Instance if we have are set
- # up to get authinfo
- if self.authinfo_callback is not None:
- return func(authinfo, *params)
- else:
- return func(*params)
- else:
- raise Exception('method "%s" is not supported' % method)
-
- def lcl_resolve_dotted_attribute(self, method):
- pyver = sys.version_info[:3]
- if pyver <= (2, 3, 4):
- return SimpleXMLRPCServer.resolve_dotted_attribute(
- self.instance, method)
- elif pyver > (2, 3, 4):
- return SimpleXMLRPCServer.resolve_dotted_attribute(
- self.instance, method, self.allow_dotted_names)
-
class AuthedSSLXMLRPCServer(BaseAuthedXMLRPCServer, SSLCommon.PlgBaseSSLServer, SimpleXMLRPCServer.SimpleXMLRPCServer):
""" Extension to allow more fine-tuned SSL handling """
@@ -176,8 +112,24 @@
class ReqHandler:
def ping(self):
+ authinfo = get_authinfo()
+ print "AUTHINFO: %s" % authinfo
return "pong"
+class TestServer(AuthedSSLXMLRPCServer):
+ """
+ SSL XMLRPC server that authenticates clients based on their certificate.
+ """
+
+ def __init__(self, address, certs):
+ AuthedSSLXMLRPCServer.__init__(self, address, self.auth_cb, certs)
+
+ def auth_cb(self, request, client_address):
+ import random
+ peer_cert = request.get_peer_certificate()
+ email = peer_cert.get_subject().countryName
+ return "AUTH: %s - %d" % (email, random.randint(1, 100))
+
if __name__ == '__main__':
if len(sys.argv) < 4:
@@ -190,7 +142,7 @@
certs['peer_ca_cert'] = sys.argv[3]
print "Starting the server."
- server = AuthedSSLXMLRPCServer(('localhost', 8886), None, certs)
+ server = TestServer(('localhost', 8886), certs)
h = ReqHandler()
server.register_instance(h)
server.serve_forever()
Index: XMLRPCServerProxy.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/XMLRPCServerProxy.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- XMLRPCServerProxy.py 9 Jul 2005 21:44:23 -0000 1.3
+++ XMLRPCServerProxy.py 10 Jul 2005 03:44:36 -0000 1.4
@@ -49,6 +49,32 @@
# Testing stuff
###########################################################
+
+import threading
+import time
+import random
+
+client_start = False
+
+_lock = threading.Lock()
+
+class TestClient(threading.Thread):
+ def __init__(self, certs):
+ self.server = PlgXMLRPCServerProxy("https://127.0.0.1:8886", certs)
+ threading.Thread.__init__(self)
+
+ def run(self):
+ while not client_start:
+ time.sleep(0.05)
+ i = 0
+ while i < 5:
+# _lock.acquire()
+ print self.server.ping()
+ time.sleep(0.05)
+# _lock.release()
+ i = i + 1
+
+
if __name__ == '__main__':
if len(sys.argv) < 4:
print "Usage: python XMLRPCServerProxy.py key_and_cert ca_cert peer_ca_cert"
@@ -59,5 +85,19 @@
certs['ca_cert'] = sys.argv[2]
certs['peer_ca_cert'] = sys.argv[3]
- s = XMLRPCServerProxy("https://127.0.0.1:8886", certs)
- print s.ping()
+ i = 100
+ while i > 0:
+ t = TestClient(certs)
+ print "Created thread %d." % i
+ t.start()
+ i = i - 1
+
+ time.sleep(3)
+ print "Unleashing threads."
+ client_start = True
+ while True:
+ try:
+ time.sleep(0.25)
+ except KeyboardInterrupt:
+ os._exit(0)
+
- Previous message: extras-buildsys/client client.py,1.9,1.10
- Next message: extras-buildsys/server Builder.py, 1.3, 1.4 User.py, 1.3, 1.4 UserInterface.py, 1.16, 1.17 main.py, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the scm-commits
mailing list