Index: fedd/fedd.py
===================================================================
--- fedd/fedd.py	(revision 329f61d5ad85f73d5c14fb854483fabef73b7f0b)
+++ fedd/fedd.py	(revision 0a47d52f26f152e6f38f4cc3c00274a3cb88a3ab)
@@ -43,5 +43,5 @@
     def send_fault(self, f, code=500):
 	"""Send a SOAP encoded fault as reply"""
-	self.send_xml(f.AsSOAP(), code)
+	self.send_xml(f.AsSOAP(processContents="lax"), code)
 
     def check_headers(self, ps):
@@ -72,5 +72,5 @@
 	    ps = ParsedSoap(data)
 	except ParseException, e:
-	    self.send_fault(FaultFromZSIException(e))
+	    self.send_fault(Fault(Fault.Client, str(e)))
 	    return
 	except Exception, e:
@@ -108,20 +108,26 @@
 	resp = None
 	data = None
+	method = None
 	cl = int(self.headers['content-length'])
 	data = self.rfile.read(cl)
-	params, method = xmlrpclib.loads(data)
 
 	try:
-	    resp = self.server.impl.xmlrpc_dispatch(method, params,
-			fedid(cert=self.request.get_peer_cert()))
-	    data = xmlrpclib.dumps((resp,), methodresponse=True)
-	except Fault, f:
-	    xf = xmlrpclib.Fault(f.code, f.string)
-	    data = xmlrpclib.dumps(xf, methodresponse=True)
-	    resp = None
-	except xmlrpclib.Fault, f:
-	    data = xmlrpclib.dumps(f, methodresponse=True)
-	    resp = None
-
+	    params, method = xmlrpclib.loads(data)
+	except xmlrpclib.ResponseError:
+	    data = xmlrpclib.dumps(xmlrpclib.Fault("Client", 
+		"Malformed request"), methodresponse=True)
+	
+	if method != None:
+	    try:
+		resp = self.server.impl.xmlrpc_dispatch(method, params,
+			    fedid(cert=self.request.get_peer_cert()))
+		data = xmlrpclib.dumps((resp,), methodresponse=True)
+	    except Fault, f:
+		xf = xmlrpclib.Fault(f.code, f.string)
+		data = xmlrpclib.dumps(xf, methodresponse=True)
+		resp = None
+	    except xmlrpclib.Fault, f:
+		data = xmlrpclib.dumps(f, methodresponse=True)
+		resp = None
 	self.send_xml(data)
 
Index: fedd/fedd_client.py
===================================================================
--- fedd/fedd_client.py	(revision 329f61d5ad85f73d5c14fb854483fabef73b7f0b)
+++ fedd/fedd_client.py	(revision 0a47d52f26f152e6f38f4cc3c00274a3cb88a3ab)
@@ -289,4 +289,6 @@
     try:
 	resp = port.RequestAccess(req)
+    except ZSI.ParseException, e:
+	sys.exit("Malformed response (XMLPRC?): %s" % e)
     except ZSI.FaultException, e:
 	sys.exit("Fault: %s" % e)
Index: fedd/fedd_proj.py
===================================================================
--- fedd/fedd_proj.py	(revision 329f61d5ad85f73d5c14fb854483fabef73b7f0b)
+++ fedd/fedd_proj.py	(revision 0a47d52f26f152e6f38f4cc3c00274a3cb88a3ab)
@@ -6,4 +6,5 @@
 from ZSI import *
 from M2Crypto import SSL
+from M2Crypto.m2xmlrpclib import SSL_Transport
 from M2Crypto.SSL.SSLServer import SSLServer
 import M2Crypto.httpslib
@@ -15,4 +16,5 @@
 import subprocess
 import tempfile
+import copy
 
 from fedd_services import *
@@ -228,11 +230,20 @@
 	os.unlink(projfile)
 
-    def proxy_request(self, dt, req):
-	"""
-	Send req on to the real destination in dt and return the response
-
-	Req is just the requestType object.  This function re-wraps it.  It
-	also rethrows any faults.
-	"""
+    
+    def strip_unicode(self, obj):
+	"""Loosly de-unicode an object"""
+	if isinstance(obj, dict):
+	    for k in obj.keys():
+		obj[k] = self.strip_unicode(obj[k])
+	    return obj
+	elif isinstance(obj, basestring):
+	    return str(obj)
+	elif getattr(obj, "__iter__", None):
+	    return [ self.strip_unicode(x) for x in obj]
+	else:
+	    return obj
+
+    def proxy_xmlrpc_request(self, dt, req):
+	"""Send an XMLRPC proxy request.  Called if the SOAP RPC fails"""
 	tc = self.proxy_trusted_certs or self.trusted_certs
 
@@ -244,4 +255,46 @@
 	    raise Fault(Fault.Server, "Server certificates misconfigured")
 
+	# Of all the dumbass things.  The XMLRPC library in use here won't
+	# properly encode unicode strings, so we make a copy of req with the
+	# unicode objects converted.  We also convert the destination testbed
+	# to a basic string if it isn't one already.
+	if isinstance(dt, str): url = dt
+	else: url = str(dt)
+
+	r = copy.deepcopy(req)
+	self.strip_unicode(r)
+	
+	transport = SSL_Transport(ctx)
+	port = xmlrpclib.ServerProxy(url, transport=transport)
+
+	# Reconstruct the full request message
+	try:
+	    resp = port.RequestAccess(
+		    { "RequestAccessRequestBody": r})
+	    resp, method = xmlrpclib.loads(resp)
+	except xmlrpclib.Error, e:
+	    raise Fault(Fault.Server, "Remote XMLRPC Fault: %s" % e)
+	
+	if resp[0].has_key('RequestAccessResponseBody'):
+	    return resp[0]['RequestAccessResponseBody']
+	else:
+	    raise Fault(Fault.Server, "Bad proxy response")
+
+    def proxy_request(self, dt, req):
+	"""
+	Send req on to the real destination in dt and return the response
+
+	Req is just the requestType object.  This function re-wraps it.  It
+	also rethrows any faults.
+	"""
+	tc = self.proxy_trusted_certs or self.trusted_certs
+
+	# No retry loop here.  Proxy servers must correctly authenticate
+	# themselves without help
+	try:
+	    ctx = fedd_ssl_context(self.cert_file, tc, password=self.cert_pwd)
+	except SSL.SSLError:
+	    raise Fault(Fault.Server, "Server certificates misconfigured")
+
 	loc = feddServiceLocator();
 	port = loc.getfeddPortType(dt,
@@ -255,4 +308,7 @@
 	try:
 	    resp = port.RequestAccess(msg)
+	except ZSI.ParseException, e:
+	    raise Fault(Fault.Server, "Bad format message (XMLRPC??): %s" %
+		    str(e))
 	except ZSI.FaultException, e:
 	    raise e.fault
@@ -423,6 +479,4 @@
 	    dt = unpack_id(req['destinationTestbed'])
 	
-	print dt
-
 	if dt == None or dt == self.testbed:
 	    # Request for this fedd
@@ -454,6 +508,20 @@
 	    return resp
 	else:
-	    # Proxy the request
-	    return self.proxy_request(dt, req)
+	    p_fault = None	# Any SOAP failure (sent unless XMLRPC works)
+	    try:
+		# Proxy the request using SOAP
+		return self.proxy_request(dt, req)
+	    except Fault, f:
+		p_fault = f
+	  
+	   
+	    # This runs if SOAP failed
+	    try:
+		return self.proxy_xmlrpc_request(dt, req)
+	    except Fault:
+		# Both failed, return the SOAP error.  If somehow that
+		# exception is gone, return the XMLRPC one
+		if p_fault != None: raise p_fault
+		else: raise
 
     def soap_RequestAccess(self, ps, fid):
Index: fedd/fedd_util.py
===================================================================
--- fedd/fedd_util.py	(revision 329f61d5ad85f73d5c14fb854483fabef73b7f0b)
+++ fedd/fedd_util.py	(revision 0a47d52f26f152e6f38f4cc3c00274a3cb88a3ab)
@@ -211,8 +211,11 @@
 	    sub = getattr(element, m)()
 	    if sub != None:
-		rv[n] = unpack_soap(sub)
+		if isinstance(sub, basestring):
+		    rv[n] = sub
+		elif getattr(sub, "__iter__", None) != None:
+		    if len(sub) > 0: rv[n] = [unpack_soap(e) for e in sub]
+		else:
+		    rv[n] = unpack_soap(sub)
 	return rv
-    elif getattr(element, "__iter__", None) != None:
-	return [unpack_soap(e) for e in element]
     else: 
-	return element;
+	return element
