made bindname an attribute of nsILDAPConnection. folded all remaining code from ldapSearch.cpp into various parts of nsLDAPChannel in preparation for pushing threading down out of nsLDAPChannel and into the core SDK wrapper classes (nsILDAP{Connection,Operation,Message}). added an (as-yet unimplemented) toString method to nsILDAPMessage; some of the code in nsLDAPChannel should eventually move there. a=r=(notbuilt)

This commit is contained in:
dmose%mozilla.org 2000-06-21 04:44:58 +00:00
Родитель 2ac4a625a1
Коммит 0c6474b843
12 изменённых файлов: 206 добавлений и 246 удалений

Просмотреть файл

@ -47,8 +47,13 @@ interface nsILDAPConnection : nsISupports
// return the string version of lderrno
readonly attribute string errorString;
// wrapper for ldap_init()
void init(in string defhost, in short defport);
// who we're binding as
readonly attribute string bindName;
// set up the connection. the first two params are for ldap init,
// the third is for this connection
//
void init(in string aHost, in short aPort, in string aBindName);
// wrapper for ldap_get_lderrno()
long getLdErrno(out string matched, out string s);

Просмотреть файл

@ -74,5 +74,9 @@ interface nsILDAPMessage : nsISupports
// errcode (wrapper around ldap_parse_result)
//
long getErrorCode();
// returns an LDIF-like string representation of this message
// XXXdmose - should use wstring here
//
string toString();
};

Просмотреть файл

@ -48,7 +48,7 @@ interface nsILDAPOperation : nsISupports
// wrapper for ldap_simple_bind()
//
void simpleBind(in string binddn, in string passwd);
void simpleBind(in string passwd);
// wrapper for ldap_search_url()
//

Просмотреть файл

@ -54,7 +54,6 @@ CPPSRCS = \
nsLDAPConnection.cpp \
nsLDAPOperation.cpp \
nsLDAPURL.cpp \
ldapSearch.cpp \
$(NULL)
EXTRA_DSO_LDOPTS += -lldap40 -llber40 $(MOZ_COMPONENT_LIBS)

Просмотреть файл

@ -108,7 +108,7 @@ main ()
fflush(stderr);
myOperation = new ldapOperation(myConnection);
returnCode = myOperation->SearchExt("ou=member_directory,o=netcenter.com",
LDAP_SCOPE_SUBTREE, "(sn=Mosedale)",
LDAP_SCOPE_SUBTREE, "(sn=Rasputin)",
&timeout, -1);
switch (returnCode) {

Просмотреть файл

@ -1,180 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the mozilla.org LDAP XPCOM component.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s): Dan Mosedale <dmose@mozilla.org>n
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include <errno.h>
#include <unistd.h>
#include "nspr.h"
#include "ldap.h"
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsILDAPConnection.h"
#include "nsILDAPOperation.h"
#include "nsILDAPMessage.h"
#include "nsLDAPChannel.h"
NS_METHOD
lds(class nsLDAPChannel *chan, const char *url)
{
nsCOMPtr<nsILDAPConnection> myConnection;
nsCOMPtr<nsILDAPMessage> myMessage;
nsCOMPtr<nsILDAPOperation> myOperation;
PRInt32 returnCode;
char *errString;
nsresult rv;
// create an LDAP connection
//
myConnection = do_CreateInstance("mozilla.network.ldapconnection", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// initialize it with the defaults
// XXX should return reasonable err msg, not assert
//
rv = myConnection->Init("nsdirectory.netscape.com", LDAP_PORT);
NS_ENSURE_SUCCESS(rv, rv);
// create and initialize an LDAP operation on the new connection
//
myOperation = do_CreateInstance("mozilla.network.ldapoperation", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = myOperation->SetConnection(myConnection);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef NO_URL_SEARCH
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "starting bind\n");
#endif
if ( !myOperation->SimpleBind(NULL, NULL) ) {
(void)myConnection->GetErrorString(&errString);
PR_fprintf(PR_STDERR, "ldap_simple_bind: %s\n", errString);
return NS_ERROR_FAILURE;
}
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "waiting for bind to complete");
#endif
myMessage = new nsLDAPMessage(myOperation);
returnCode = myOperation->Result(0, &nullTimeval, myMessage);
while (returnCode == 0 ) {
returnCode =
myOperation->Result(0, &nullTimeval, myMessage);
usleep(20);
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR,".");
#endif
}
switch (returnCode) {
case LDAP_RES_BIND:
// success
break;
case -1:
(void)myConnection->GetErrorString(&errString);
PR_fprintf(PR_STDERR,
"myOperation->Result() [myOperation->SimpleBind]: %s: errno=%d\n",
errString, errno);
ldap_memfree(errString);
return NS_ERROR_FAILURE;
break;
default:
PR_fprintf(PR_STDERR,
"\nmyOperation->Result() returned unexpected value: %d",
returnCode);
return NS_ERROR_FAILURE;
}
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "bound\n");
#endif
#endif
// start search
//
PR_fprintf(PR_STDERR, "starting search\n");
myOperation = do_CreateInstance("mozilla.network.ldapoperation", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = myOperation->SetConnection(myConnection);
NS_ENSURE_SUCCESS(rv, rv);
// XXX what about timeouts?
// XXX failure is a reasonable thing; don't assert
//
rv = myOperation->UrlSearch(url, PR_FALSE);
NS_ENSURE_SUCCESS(rv,rv);
// poll for results
//
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "polling search operation");
#endif
returnCode = LDAP_SUCCESS;
while ( returnCode != LDAP_RES_SEARCH_RESULT ) {
PR_fprintf(PR_STDERR,".");
// XXX is 0 the right value?
//
rv = myOperation->Result(LDAP_MSG_ONE, (PRIntervalTime)0,
getter_AddRefs(myMessage), &returnCode);
switch (returnCode) {
case -1: // something went wrong
(void)myConnection->GetErrorString(&errString);
#ifdef DEBUG
PR_fprintf(PR_STDERR,
"\nmyOperation->Result() [URLSearch]: %s: errno=%d\n",
errString, errno);
#endif
ldap_memfree(errString);
return NS_ERROR_FAILURE;
case 0: // nothing's been returned yet
break;
default:
chan->OnLDAPMessage(myMessage, returnCode);
break;
}
myMessage = 0;
PR_Sleep(200);
}
return NS_OK;
}

Просмотреть файл

@ -50,8 +50,6 @@
#include "nspr.h"
#endif
NS_METHOD lds(class nsLDAPChannel *chan, const char *);
NS_IMPL_THREADSAFE_ISUPPORTS4(nsLDAPChannel, nsIChannel, nsIRequest,
nsIRunnable, nsILDAPMessageListener);
@ -64,12 +62,32 @@ nsLDAPChannel::~nsLDAPChannel()
{
}
// initialize the channel
//
nsresult
nsLDAPChannel::Init(nsIURI *uri)
{
mURI = uri;
mReadPipeOffset = 0;
return NS_OK;
nsresult rv;
mURI = uri;
mReadPipeOffset = 0;
// create an LDAP connection
//
mConnection = do_CreateInstance("mozilla.network.ldapconnection", &rv);
if (NS_FAILED(rv)) {
return rv;
}
// initialize it with the defaults
// XXX - should use nsLDAPURL and get the correct default
//
rv = mConnection->Init("memberdir.netscape.com", LDAP_PORT, NULL);
if (NS_FAILED(rv)) {
return (rv);
}
return NS_OK;
}
// impl code cribbed from nsJARChannel.cpp
@ -493,27 +511,61 @@ NS_IMETHODIMP
nsLDAPChannel::AsyncRead(nsIStreamListener* aListener,
nsISupports* aCtxt)
{
nsresult rv;
nsresult rv;
nsXPIDLCString urlSpec;
// deal with the input args
//
mListener = aListener;
mResponseContext = aCtxt;
// deal with the input args
//
mListener = aListener;
mResponseContext = aCtxt;
// add ourselves to the appropriate loadgroup
//
if (mLoadGroup) {
mLoadGroup->AddChannel(this, nsnull);
}
// add ourselves to the appropriate loadgroup
//
if (mLoadGroup) {
mLoadGroup->AddChannel(this, nsnull);
}
// kick off a thread to do the work
//
NS_ASSERTION(!mThread, "nsLDAPChannel thread already exists!");
// start search
//
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "starting search\n");
#endif
rv = NS_NewThread(getter_AddRefs(mThread), this, 0, PR_JOINABLE_THREAD);
NS_ENSURE_SUCCESS(rv, rv);
// create and initialize an LDAP operation (to be used for the bind)
//
mOperation = do_CreateInstance("mozilla.network.ldapoperation", &rv);
if (NS_FAILED(rv)) {
return (rv);
}
rv = mOperation->SetConnection(mConnection);
if (NS_FAILED(rv)) {
return (rv);
}
return NS_OK;
// get the URI spec
//
rv = mURI->GetSpec(getter_Copies(urlSpec));
NS_ENSURE_SUCCESS(rv, rv);
// we already know the content type, so we can fire this now
//
mListener->OnStartRequest(this, mResponseContext);
// XXX what about timeouts?
// XXX failure is a reasonable thing; don't assert
//
rv = mOperation->UrlSearch(urlSpec, PR_FALSE);
NS_ENSURE_SUCCESS(rv,rv);
// kick off a thread to wait for results
//
NS_ASSERTION(!mThread, "nsLDAPChannel thread already exists!");
rv = NS_NewThread(getter_AddRefs(mThread), this, 0, PR_JOINABLE_THREAD);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
// Writes asynchronously to the URL's specified destination. Notifications
@ -545,6 +597,9 @@ nsLDAPChannel::Run(void)
{
nsresult rv;
nsXPIDLCString spec;
PRInt32 returnCode;
nsCOMPtr<nsILDAPMessage> myMessage;
char *errString; // XXX fix ownership model
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "nsLDAPChannel::Run() entered!\n");
@ -556,10 +611,6 @@ nsLDAPChannel::Run(void)
NS_UI_THREAD_EVENTQ);
NS_ENSURE_SUCCESS(rv, rv);
// we already know the content type, so might as well fire this now
//
mAsyncListener->OnStartRequest(this, mResponseContext);
// since the LDAP SDK does all the socket management, we don't have
// an underlying transport channel to create an nsIInputStream to hand
// back to the nsIStreamListener. So we do it ourselves:
@ -584,15 +635,41 @@ nsLDAPChannel::Run(void)
// XXX handle incorrect second call to Run
}
// get the URI spec
// wait for results
//
rv = mURI->GetSpec(getter_Copies(spec));
NS_ENSURE_SUCCESS(rv, rv);
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "waiting for messages\n");
#endif
// do the search
//
rv = lds(this, spec);
NS_ENSURE_SUCCESS(rv, rv);
returnCode = LDAP_SUCCESS;
while ( returnCode != LDAP_RES_SEARCH_RESULT ) {
// XXX is 0 the right value?
//
rv = mOperation->Result(LDAP_MSG_ONE, (PRIntervalTime)0,
getter_AddRefs(myMessage), &returnCode);
switch (returnCode) {
case -1: // something went wrong
(void)mConnection->GetErrorString(&errString);
#ifdef DEBUG
PR_fprintf(PR_STDERR,"\nmyOperation->Result() [URLSearch]: %s\n",
errString);
#endif
ldap_memfree(errString);
return NS_ERROR_FAILURE;
case 0: // nothing's been returned yet
break;
default:
this->OnLDAPMessage(myMessage, returnCode);
break;
}
myMessage = 0;
PR_Sleep(200);
}
// close the pipe
//
@ -667,7 +744,7 @@ nsLDAPChannel::OnLDAPSearchResult(nsILDAPMessage *aMessage)
nsresult rv;
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "\nresult returned: \n");
PR_fprintf(PR_STDERR, "result returned\n");
#endif
// XXX should use GetErrorString here?
@ -678,27 +755,17 @@ nsLDAPChannel::OnLDAPSearchResult(nsILDAPMessage *aMessage)
return NS_ERROR_FAILURE;
}
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "success\n");
#endif
// done with this message; cause nsCOMPtr to call the destructor
//
aMessage = 0;
// XXX need to destroy the connection (to unbind) here
// the old code that did this in ldapSearch.cpp is pasted below
//
#if 0
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR,"unbinding\n");
#endif
myConnection = 0;
// XXXdmose this is synchronous! (and presumably could conceivably stall)
// should check SDK code to verify, and somehow deal with this better.
//
mConnection = 0;
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR,"unbound\n");
#endif
#endif
return NS_OK;
@ -707,7 +774,7 @@ nsLDAPChannel::OnLDAPSearchResult(nsILDAPMessage *aMessage)
// void OnLDAPSearchEntry (in nsILDAPMessage aMessage);
//
// XXX need to addref my message? deal with scope?
// XXXdmose most of this function should live in nsILDAPMessage::toString
// XXXdmose most of this function should live in nsILDAPMessage::toString()
//
nsresult
nsLDAPChannel::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
@ -716,7 +783,7 @@ nsLDAPChannel::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
char *dn, *attr;
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "\nentry returned!\n");
PR_fprintf(PR_STDERR, "entry returned!\n");
#endif
// get the DN

Просмотреть файл

@ -91,7 +91,9 @@ protected:
//
nsCOMPtr<nsIStreamListener> mAsyncListener; // since we can't call mListener
// directly from the worker thread
nsCOMPtr<nsIThread> mThread; // worker thread for this channer
nsCOMPtr<nsILDAPConnection> mConnection; // LDAP connection for this channel
nsCOMPtr<nsILDAPOperation> mOperation; // current LDAP operation
nsCOMPtr<nsIThread> mThread; // worker thread for this channel
nsCOMPtr<nsIStreamListener> mListener; // whoever is listening to us
nsCOMPtr<nsISupports> mResponseContext;
nsCOMPtr<nsIBufferInputStream> mReadPipeIn; // this end given to the listener

Просмотреть файл

@ -32,6 +32,7 @@
*/
#include <stdio.h>
#include "nspr.h"
#include "nsLDAPConnection.h"
NS_IMPL_THREADSAFE_ISUPPORTS1(nsLDAPConnection, nsILDAPConnection);
@ -52,23 +53,67 @@ nsLDAPConnection::~nsLDAPConnection()
rc = ldap_unbind_s(this->mConnectionHandle);
if (rc != LDAP_SUCCESS) {
fprintf(stderr, "nsLDAPConnection::~nsLDAPConnection: %s\n",
#ifdef DEBUG
PR_fprintf(PR_STDERR, "nsLDAPConnection::~nsLDAPConnection: %s\n",
ldap_err2string(rc));
#endif
}
// XXX use delete here?
// XXX can delete fail?
//
if (mBindName) {
delete mBindName;
}
}
// wrapper for ldap_init()
//
NS_IMETHODIMP
nsLDAPConnection::Init(const char *aDefHost, PRInt16 aDefPort)
nsLDAPConnection::Init(const char *aHost, PRInt16 aPort, const char *aBindName)
{
NS_ENSURE_ARG(aDefHost);
NS_ENSURE_ARG(aDefPort);
NS_ENSURE_ARG(aHost);
NS_ENSURE_ARG(aPort);
if (aBindName) {
mBindName = new nsCString(aBindName);
if (!mBindName) {
return NS_ERROR_OUT_OF_MEMORY;
}
} else {
mBindName = NULL;
}
this->mConnectionHandle = ldap_init(aHost, aPort);
this->mConnectionHandle = ldap_init(aDefHost, aDefPort);
return (this->mConnectionHandle == NULL ? NS_ERROR_FAILURE : NS_OK);
}
// who we're binding as
//
// readonly attribute string bindName
NS_IMETHODIMP
nsLDAPConnection::GetBindName(char **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
// check for NULL (meaning bind anonymously)
//
if (!mBindName) {
*_retval = nsnull;
} else {
// otherwise, hand out a copy of the bind name
//
*_retval = mBindName->ToNewCString();
if (!(*_retval)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
return NS_OK;
}
// wrapper for ldap_get_lderrno
//
NS_IMETHODIMP

Просмотреть файл

@ -36,6 +36,7 @@
#include "nsILDAPConnection.h"
#include "ldap.h"
#include "nsString.h"
// 0d871e30-1dd2-11b2-8ea9-831778c78e93
//
@ -60,8 +61,8 @@ class nsLDAPConnection : public nsILDAPConnection {
protected:
// the LDAP SDK's struct for the connection
LDAP *mConnectionHandle;
LDAP *mConnectionHandle; // the LDAP C SDK's connection object
nsCString *mBindName; // who to bind as
};
#endif /* _nsLDAPConnection_h_ */

Просмотреть файл

@ -280,3 +280,13 @@ nsLDAPMessage::GetValues(const char *aAttr, PRUint32 *aCount,
*aValues = values;
return NS_OK;
}
// returns an LDIF-like string representation of this message
//
// string toString();
//
NS_IMETHODIMP
nsLDAPMessage::ToString(char* *aString)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -35,6 +35,7 @@
#include "nsLDAPOperation.h"
#include "nsILDAPMessage.h"
#include "nsIComponentManager.h"
#include "nsXPIDLString.h"
struct timeval nsLDAPOperation::sNullTimeval = {0, 0};
@ -87,10 +88,16 @@ nsLDAPOperation::GetConnection(nsILDAPConnection* *aConnection)
// wrapper for ldap_simple_bind()
//
NS_IMETHODIMP
nsLDAPOperation::SimpleBind(const char *who, const char *passwd)
nsLDAPOperation::SimpleBind(const char *passwd)
{
this->mMsgId = ldap_simple_bind(this->mConnectionHandle, who,
passwd);
nsresult rv;
nsXPIDLCString bindName;
rv = this->mConnection->GetBindName(getter_Copies(bindName));
if (NS_FAILED(rv))
return rv;
this->mMsgId = ldap_simple_bind(this->mConnectionHandle, bindName, passwd);
if (this->mMsgId == -1) {
return NS_ERROR_FAILURE;