1. Michael Granger
  2. ruby-openldap

Commits

Michael Granger  committed deee728

OpenLDAP::Connection additions:
* modified ::new to accept multiple URIs like the underlying library.
* Added a #uris instance method to return the URIs it was constructed with.

  • Participants
  • Parent commits 6495057
  • Branches default

Comments (0)

Files changed (5)

File ext/connection.c

View file
  * -------------------------------------------------------------- */
 
 /*
- *  call-seq:
- *     OpenLDAP::Connection.allocate   -> store
+ * call-seq:
+ *    OpenLDAP::Connection.allocate   -> store
  *
- *  Allocate a new OpenLDAP::Connection object.
+ * Allocate a new OpenLDAP::Connection object.
  *
  */
 static VALUE
-ropenldap_conn_s_allocate( VALUE klass ) {
+ropenldap_conn_s_allocate( VALUE klass )
+{
 	return Data_Wrap_Struct( klass, ropenldap_conn_gc_mark, ropenldap_conn_gc_free, 0 );
 }
 
  * -------------------------------------------------------------- */
 
 /*
- *  call-seq:
- *     OpenLDAP::Connection.new( url )           -> conn
+ * call-seq:
+ *    OpenLDAP::Connection.new( *uris )           -> conn
  *
- *  Create a new OpenLDAP::Connection object using the given +url+.
+ * Create a new OpenLDAP::Connection object using the given +uris+.
  *
  */
 static VALUE
-ropenldap_conn_initialize( VALUE self, VALUE urlstring ) {
+ropenldap_conn_initialize( VALUE self, VALUE urls )
+{
 	ropenldap_log_obj( self, "debug", "Initializing 0x%x", self );
 
 	if ( !check_conn(self) ) {
+		VALUE urlstring;
 		LDAP *ldp = NULL;
-		char *url = StringValueCStr( urlstring );
+		char *url = NULL;
 		struct ropenldap_connection *conn;
 		int result = 0;
 		int proto_ver = 3;
 
+		urlstring = rb_funcall( urls, rb_intern("join"), 1, rb_str_new(" ", 1) );
+		url = RSTRING_PTR( rb_obj_as_string(urlstring) );
+
 		if ( !ldap_is_ldap_url(url) )
 			rb_raise( rb_eArgError, "'%s' is not an LDAP url", url );
 
 		ropenldap_log_obj( self, "info", "Creating a new %s (%s)", rb_obj_classname(self), url );
 		result = ldap_initialize( &ldp, url );
-		ropenldap_check_result( ldp, result, "ldap_initialize" );
+		ropenldap_check_result( result, "ldap_initialize( \"%s\" )", url );
 
 		ropenldap_log_obj( self, "debug", "  setting protocol to LDAPv3." );
 		result = ldap_set_option( ldp, LDAP_OPT_PROTOCOL_VERSION, &proto_ver );
-		ropenldap_check_opt_result( ldp, result, "LDAP_OPT_PROTOCOL_VERSION" );
+		ropenldap_check_opt_result( result, "LDAP_OPT_PROTOCOL_VERSION" );
 
 		conn = DATA_PTR( self ) = ropenldap_conn_alloc( ldp );
 
 }
 
 
+/*
+ * Turn a STRING_T into a URI object via URI::parse.
+ */
+static VALUE
+ropenldap_parse_uri( VALUE string )
+{
+	StringValue( string );
+	return rb_funcall( ropenldap_rbmURI, rb_intern("parse"), 1, string );
+}
+
+
+/*
+ * call-seq:
+ *     connection.uris   -> array
+ *
+ * Gets an Array of URIs to be contacted by the library when trying to establish 
+ * a connection.
+ *
+ */
+static VALUE
+ropenldap_conn_uris( VALUE self )
+{
+	struct ropenldap_connection *ptr = ropenldap_get_conn( self );
+	char *uris;
+	VALUE uristring, uriarray;
+	int result;
+
+	result = ldap_get_option( ptr->ldap, LDAP_OPT_URI, &uris );
+	ropenldap_check_opt_result( result, "LDAP_OPT_PROTOCOL_VERSION" );
+
+	/* Convert to strings first, then collect them into URI objects */
+	uristring = rb_str_new2( uris );
+	ldap_memfree( uris );
+
+	uriarray = rb_funcall( uristring, rb_intern("split"), 0 );
+	rb_block_call( uriarray, rb_intern("collect!"), 0, NULL, 
+	               ropenldap_parse_uri, Qnil );
+
+	return uriarray;
+}
+
 
 
 
  * OpenLDAP Connection class
  */
 void
-ropenldap_init_connection( void ) {
+ropenldap_init_connection( void )
+{
 	ropenldap_log( "debug", "Initializing OpenLDAP::Connection" );
 
 #ifdef FOR_RDOC
 
 	rb_define_alloc_func( ropenldap_cOpenLDAPConnection, ropenldap_conn_s_allocate );
 
-	rb_define_method( ropenldap_cOpenLDAPConnection, "initialize", ropenldap_conn_initialize, 1 );
+	rb_define_method( ropenldap_cOpenLDAPConnection, "initialize", ropenldap_conn_initialize, -2 );
+
+	rb_define_method( ropenldap_cOpenLDAPConnection, "uris", ropenldap_conn_uris, 0 );
+
 
 }
 

File ext/extconf.rb

View file
 require 'fileutils'
 
 if ENV['MAINTAINER_MODE']
-	$stderr.puts "Maintainer mode enabled."
+	$stderr.puts "** Maintainer mode enabled. **"
 	$CFLAGS << ' -Wall' << ' -ggdb' << ' -DDEBUG'
 end
 

File ext/openldap.c

View file
+
 /*
  * Ruby-OpenLDAP -- a Ruby binding to OpenLDAP's libldap
  * $Id$
 
 VALUE ropenldap_eOpenLDAPError;
 
+VALUE ropenldap_rbmURI;
+
 
 /* --------------------------------------------------------------
  * Logging Functions
  * resultcode.
  */
 void
-ropenldap_check_result( LDAP *ldp, int resultcode, const char *func )
+#ifdef HAVE_STDARG_PROTOTYPES
+ropenldap_check_result( int resultcode, const char *func, ... )
+#else
+ropenldap_check_result( int resultcode, const char *func, va_dcl )
+#endif
 {
+	char buf[BUFSIZ];
+	va_list args;
 	VALUE exception_class = Qnil;
 
 	if ( resultcode == LDAP_SUCCESS ) return;
 
+	va_init_list( args, func );
+	vsnprintf( buf, BUFSIZ, func, args );
+
 	exception_class =
 		rb_funcall( ropenldap_eOpenLDAPError, rb_intern("subclass_for"), 1, INT2FIX(resultcode) );
 
-	rb_raise( exception_class, func );
+	rb_raise( exception_class, "%s", buf );
 }
 
 
  * warranted.
  */
 void
-ropenldap_check_opt_result( LDAP *ldp, int optresult, const char *opt )
+ropenldap_check_opt_result( int optresult, const char *opt )
 {
 	if ( optresult == LDAP_OPT_SUCCESS ) return;
 	rb_raise( rb_eRuntimeError, "Failed to set option %s: %d", opt, optresult );
 /*
  * Convert an array of string pointers to a Ruby Array of Strings.
  */
-static VALUE
+VALUE
 ropenldap_rb_string_array( char **strings )
 {
 	VALUE ary = rb_ary_new();
  * - crit_exts
  */
 static VALUE
-ropenldap_s_split_url( VALUE _, VALUE urlstring )
+ropenldap_s_split_url( VALUE UNUSED(module), VALUE urlstring )
 {
 	const char *url = StringValueCStr( urlstring );
 	LDAPURLDesc *urldesc;
  *
  */
 static VALUE
-ropenldap_s_err2string( VALUE _, VALUE resultcode )
+ropenldap_s_err2string( VALUE UNUSED(module), VALUE resultcode )
 {
 	int err = FIX2INT( resultcode );
 	char *string = ldap_err2string( err );
 void
 Init_openldap_ext( void )
 {
+	rb_require( "uri" );
+	ropenldap_rbmURI = rb_const_get( rb_cObject, rb_intern("URI") );
+
 	rb_require( "openldap" );
 	ropenldap_mOpenLDAP = rb_define_module( "OpenLDAP" );
 	ropenldap_mOpenLDAPLoggable = rb_define_module_under( ropenldap_mOpenLDAP, "Loggable" );

File ext/openldap.h

View file
 #include <ruby.h>
 
 
+
 /* --------------------------------------------------------------
  * Globals
  * -------------------------------------------------------------- */
 
+/* Reference to the URI module */
+extern VALUE ropenldap_rbmURI;
+
 extern VALUE ropenldap_mOpenLDAP;
 extern VALUE ropenldap_mOpenLDAPLoggable;
 
 
 /* OpenLDAP::Connection struct */
 struct ropenldap_connection {
-	LDAP	*ldap;
-	VALUE	connection;
+    LDAP    *ldap;
+    VALUE   connection;
 };
 
 
  * -------------------------------------------------------------- */
 #define IsConnection( obj ) rb_obj_is_kind_of( (obj), ropenldap_cOpenLDAPConnection )
 
+#ifdef UNUSED
+#elif defined(__GNUC__)
+# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
+#elif defined(__LCLINT__)
+# define UNUSED(x) /*@unused@*/ x
+#else
+# define UNUSED(x) x
+#endif
+
 
 /* --------------------------------------------------------------
  * Declarations
 #define va_init_list(a,b) va_start(a,b)
 void ropenldap_log_obj( VALUE, const char *, const char *, ... );
 void ropenldap_log( const char *, const char *, ... );
+void ropenldap_check_result( int, const char *, ... );
 #else
 #include <varargs.h>
 #define va_init_list(a,b) va_start(a)
 void ropenldap_log_obj( VALUE, const char *, const char *, va_dcl );
 void ropenldap_log( const char *, const char *, va_dcl );
+void ropenldap_check_result( int, va_dcl );
 #endif
 
-void ropenldap_check_result				_(( LDAP *, int, const char * ));
-void ropenldap_check_opt_result			_(( LDAP *, int, const char * ));
+void ropenldap_check_opt_result         _(( int, const char * ));
+
+VALUE ropenldap_rb_string_array         _(( char ** ));
 
 
 /* --------------------------------------------------------------
  * Initializers
  * -------------------------------------------------------------- */
 
-void Init_openldap_ext					_(( void ));
-void ropenldap_init_connection			_(( void ));
+void Init_openldap_ext                  _(( void ));
+void ropenldap_init_connection          _(( void ));
 
 
 #endif /* __OPENLDAP_H__ */

File spec/openldap/connection_spec.rb

View file
 	$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
 }
 
+require 'uri'
 require 'rspec'
 require 'spec/lib/helpers'
 require 'openldap/connection'
 	end
 
 
-	TEST_LDAP_URI = 'ldap://localhost/'
+	TEST_LDAP_URI = URI( 'ldap://localhost' )
 
-	it "can be created with an LDAP uri" do
-		OpenLDAP::Connection.new( TEST_LDAP_URI )
+	TEST_LDAP_URI2 = URI( 'ldap://ldap.example.com' )
+
+	it "can be created with an LDAP URI" do
+		conn = OpenLDAP::Connection.new( TEST_LDAP_URI )
+		conn.uris.should == [ TEST_LDAP_URI ]
 	end
 
+	it "can be created with an LDAP URI String" do
+		conn = OpenLDAP::Connection.new( TEST_LDAP_URI.to_s )
+		conn.uris.should == [ TEST_LDAP_URI ]
+	end
+
+	it "can be created with several LDAP URIs" do
+		conn = OpenLDAP::Connection.new( TEST_LDAP_URI, TEST_LDAP_URI2 )
+		conn.uris.should == [ TEST_LDAP_URI, TEST_LDAP_URI2 ]
+	end
+
+	describe "a connection instance" do
+
+		before( :each ) do
+			@conn = OpenLDAP::Connection.new( TEST_LDAP_URI )
+		end
+
+	end
 
 end