Author: gsim
Date: Mon Mar  7 10:34:42 2011
New Revision: 1078733

URL: http://svn.apache.org/viewvc?rev=1078733&view=rev
Log:
QPID-3115: Recognise sasl_mechanisms (plural) and support a space separate list 
as does the python client (continue to recognise sasl-mechanism as well for 
backword compatibility)

Modified:
    qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
    qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp?rev=1078733&r1=1078732&r2=1078733&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp Mon Mar  7 
10:34:42 2011
@@ -22,6 +22,7 @@
 #include "qpid/client/ConnectionHandler.h"
 
 #include "qpid/SaslFactory.h"
+#include "qpid/StringUtils.h"
 #include "qpid/client/Bounds.h"
 #include "qpid/framing/amqp_framing.h"
 #include "qpid/framing/all_method_bodies.h"
@@ -202,6 +203,24 @@ void ConnectionHandler::fail(const std::
 
 namespace {
 std::string SPACE(" ");
+
+std::string join(const std::vector<std::string>& in)
+{
+    std::string result;
+    for (std::vector<std::string>::const_iterator i = in.begin(); i != 
in.end(); ++i) {
+        if (result.size()) result += SPACE;
+        result += *i;
+    }
+    return result;
+}
+
+void intersection(const std::vector<std::string>& a, const 
std::vector<std::string>& b, std::vector<std::string>& results)
+{
+    for (std::vector<std::string>::const_iterator i = a.begin(); i != a.end(); 
++i) {
+        if (std::find(b.begin(), b.end(), *i) != b.end())  
results.push_back(*i);
+    }
+}
+
 }
 
 void ConnectionHandler::start(const FieldTable& /*serverProps*/, const Array& 
mechanisms, const Array& /*locales*/)
@@ -216,25 +235,24 @@ void ConnectionHandler::start(const Fiel
                                               maxSsf
                                             );
 
-    std::string mechlist;
-    bool chosenMechanismSupported = mechanism.empty();
-    for (Array::const_iterator i = mechanisms.begin(); i != mechanisms.end(); 
++i) {
-        if (!mechanism.empty() && mechanism == (*i)->get<std::string>()) {
-            chosenMechanismSupported = true;
-            mechlist = (*i)->get<std::string>() + SPACE + mechlist;
-        } else {
-            if (i != mechanisms.begin()) mechlist += SPACE;
-            mechlist += (*i)->get<std::string>();
+    std::vector<std::string> mechlist;
+    if (mechanism.empty()) {
+        //mechlist is simply what the server offers
+        mechanisms.collect(mechlist);
+    } else {
+        //mechlist is the intersection of those indicated by user and
+        //those supported by server, in the order listed by user
+        std::vector<std::string> allowed = split(mechanism, " ");
+        std::vector<std::string> supported;
+        mechanisms.collect(supported);
+        intersection(allowed, supported, mechlist);
+        if (mechlist.empty()) {
+            throw Exception(QPID_MSG("Desired mechanism(s) not valid: " << 
mechanism << " (supported: " << join(supported) << ")"));
         }
     }
 
-    if (!chosenMechanismSupported) {
-        fail("Selected mechanism not supported: " + mechanism);
-    }
-
     if (sasl.get()) {
-        string response = sasl->start(mechanism.empty() ? mechlist : mechanism,
-                                      getSecuritySettings ? 
getSecuritySettings() : 0);
+        string response = sasl->start(join(mechlist), getSecuritySettings ? 
getSecuritySettings() : 0);
         proxy.startOk(properties, sasl->getMechanism(), response, locale);
     } else {
         //TODO: verify that desired mechanism and locale are supported

Modified: qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp?rev=1078733&r1=1078732&r2=1078733&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp Mon Mar  7 
10:34:42 2011
@@ -101,8 +101,8 @@ void ConnectionImpl::setOption(const std
         settings.username = value.asString();
     } else if (name == "password") {
         settings.password = value.asString();
-    } else if (name == "sasl-mechanism" || name == "sasl_mechanism") {
-        //TODO: handle space separate lists of mechanisms
+    } else if (name == "sasl-mechanism" || name == "sasl_mechanism" ||
+               name == "sasl-mechanisms" || name == "sasl_mechanisms") {
         settings.mechanism = value.asString();
     } else if (name == "sasl-service" || name == "sasl_service") {
         settings.service = value.asString();



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:[email protected]

Reply via email to