LDAP error-handling cleanup, part 1. a=r=(not built)

This commit is contained in:
dmose%mozilla.org 2000-10-17 23:07:38 +00:00
Родитель 6e3e11f2f1
Коммит 71e1b8348a
15 изменённых файлов: 618 добавлений и 234 удалений

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

@ -1,17 +1,28 @@
housecleaning for first 0.x release
-----------------------------------
* error handling: sort out what should be NS_ASSERTIONs vs. normal
error conditions (eg network & data errors), especially in nsLDAPChannel.
also shouldn't be casting results of nsILDAPConnection::GetErrorString to
void in ldapSearch. (ideally this would use xpidl nsresult decls
(bug 13423), but that's not done yet). This also requires some
threadsafety work related to the data and interfaces touched by
nsLDAPChannel::Cancel, since these are used in the connection
callbacks, and we also need to be able to cancel from the connection
callbacks themselves.
* audit for and fix leaks / bloat
* grep for XXXs and fix the issues
items blocked waiting for other work
------------------------------------
* destroy connection & thread when done with it; deal with timeouts
(blocked on LDAP C SDK 4.1, in the hopes that the NSPR
binding of the IO functions will provide us with some way to pop out
of the select() that's called under ldap_result(). It may not be worth
implementing this until nsLDAPService is ressurected.
implementing this until nsLDAPService is resurrected. If this
doesn't work, we may have to give nsLDAPConnection an event queue &
loop of its own, instead of using the LDAP C SDK as a vector to get
events over there.
items blocked waiting for other work
------------------------------------
* go through the various options that can be used with the SDK function
ldap_set_options() and decide if and where the various functions should
be used. This will include memory allocator settings, and possibly
@ -48,18 +59,14 @@ items blocked waiting for other work
misc
----
* error handling: sort out what should be NS_ASSERTIONs vs. normal
error conditions (eg network & data errors). should audit interface
boundaries to make sure they do appropriate checking. also,
shouldn't be casting results of nsILDAPConnection::GetErrorString to
void in ldapSearch. (ideally this would use xpidl nsresult decls
(bug 13423), but that's not done yet).
* verify that ldap_parse_result() and ldap_get_ldaperrno() aren't
required to be called from the same thread as ldap_result() and
before the thread-specific ldaperrno has a chance to change.
before the thread-specific ldaperrno has a chance to change. Note:
now that ldap_parse_result is only called inside the initializer
nsLDAPMessage::Init(), this is probably no longer an issue there at
least. Need to confirm.
* investigate use of DNS in LDAP sdk. are sync functions used in the
* investigate use of DNS in LDAP sdk. I think sync functions used in the
wrong places (eg they end up getting called from Mozilla on the UI thread)?
* audit for and implement any appropriate NOT_IMPLEMENTED functions
@ -88,6 +95,8 @@ misc
heuristic to figure out if they're a string. I wonder how
ldapsearch does this.
* grep for XXXs and fix the issues
rdf datasource
--------------
@ -107,7 +116,7 @@ testing
perf
----
* rather than having one thread per nsILDAPConnection, have identical
* rather than having one thread per nsILDAPConnection, have multiple
nsILDAPConnections share the same thread. possibly pre-spin up a
thread-pool to handle this?
@ -122,8 +131,12 @@ perf
later
-----
* rationalize the logging strategy. right now there is a mix of
PR_LOG/NS{WARNING|ERROR} and nsIConsoleService and non-logging,
as I have been vacillating on how much logging it's really important to have
(part of my thought process about the XPCOM-wrapper being part of
Mozilla-as-platform)
* get rid of inappropriate use of nsVoidKey by implementing an nsPRInt32Key
* get rid of "friend"liness of nsLDAP{Message,Connection,Operation} classes?
* handle referrals
* failover
* addressbook/mail UI glue

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

@ -63,11 +63,14 @@ interface nsILDAPConnection : nsISupports
*
* @param aHost server name for ldap_init()
* @param aPort server port number for ldap_init()
* 0 == default port (389)
* @param aBindName DN to bind as
*
* @exception NS_ERROR_OUT_OF_MEMORY
* @exception NS_ERROR_FAILURE
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
* @exception NS_ERROR_NOT_AVAILABLE Couldn't create thread.
* @exception NS_ERROR_FAILURE
* @exception NS_ERROR_UNEXPECTED internal error
*/
void init(in string aHost, in short aPort, in string aBindName);
@ -77,7 +80,7 @@ interface nsILDAPConnection : nsISupports
/**
* really only for the internal use of nsLDAPOperation and friends
*
* @exception NS_ERROR_INVALID_POINTER pointer passed in was NULL
* @exception NS_ERROR_ILLEGAL_VALUE pointer passed in was NULL
*/
[noscript] readonly attribute ldapConnectionHandle connectionHandle;
@ -88,7 +91,7 @@ interface nsILDAPConnection : nsISupports
* for this connection has an operation to callback to.
*
* @param aOperation operation to add
* @exception NS_ERROR_INVALID_POINTER aOperation was NULL
* @exception NS_ERROR_ILLEGAL_VALUE aOperation was NULL
* @exception NS_ERROR_UNEXPECTED this operation's msgId was not
* unique to this connection
* @exception NS_ERROR_OUT_OF_MEMORY out of memory

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

@ -52,8 +52,10 @@ interface nsILDAPMessage : nsISupports
* @param aConnection The connection this message lives on.
* @param aMsgHandle The native LDAPMessage to be wrapped.
*
* @exception NS_ERROR_INVALID_POINTER
* @exception NS_ERROR_FAILURE Err getting connection handle.
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
* @exception NS_ERROR_UNEXPECTED internal err; shouldn't happen
* @exception NS_ERROR_LDAP_DECODING_ERROR problem during BER decoding
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
*/
[noscript] void init(in nsILDAPConnection aConnection,
in ldapMsgHandle aMsgHandle);
@ -84,7 +86,6 @@ interface nsILDAPMessage : nsISupports
/**
* wrapper for ldap_get_values()
*
*
* @param attr The attribute whose values are to be returned
* @param count Number of values in the outbound array.
@ -98,10 +99,28 @@ interface nsILDAPMessage : nsISupports
void getValues(in string attr, out unsigned long count,
[retval, array, size_is(count)] out string values);
// turn an error condition associated with this message into an LDAP
// errcode (wrapper around ldap_parse_result)
//
long getErrorCode();
/**
* The result code (ie lderrno) for this message.
*
* XXXdmose these codes are defined in ldap.h; presumably need to reexport
* these as IDL constants (or somehow map to nsresults?)
*
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
*/
readonly attribute long errorCode;
/**
* Wrapper for ldap_msgtype()
*
* XXXdmose the message types are defined in ldap.h; presumably need
* to reexport these as IDL constants
*
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
* @exception NS_ERROR_UNEXPECTED internal error (possible memory
* corruption)
*
*/
readonly attribute long type;
// returns an LDIF-like string representation of this message
// XXXdmose - should use wstring here

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

@ -45,8 +45,9 @@ interface nsILDAPMessageListener : nsISupports
* Messages received are passed back via this function.
*
* @arg aMessage The message that was returned, NULL if none was.
* @arg aRetVal the return value from ldap_result()
*
* XXX semantics of NULL?
*/
void onLDAPMessage(in nsILDAPMessage aMessage, in PRInt32 aRetVal);
void onLDAPMessage(in nsILDAPMessage aMessage);
};

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

@ -44,6 +44,8 @@ interface nsILDAPOperation : nsISupports
{
/**
* The connection this operation is on.
*
* @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
*/
readonly attribute nsILDAPConnection connection;
@ -51,13 +53,15 @@ interface nsILDAPOperation : nsISupports
* Callback for individual result messages related to this operation (set
* by the init() method). This is actually an nsISupports proxy object,
* as the callback will happen from another thread.
*
* @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
*/
readonly attribute nsILDAPMessageListener messageListener;
/**
* The message-id associated with this operation.
*
* @exception NS_ERROR_INVALID_POINTER if a NULL pointer is passed in
* @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
*/
readonly attribute long messageId;
@ -71,8 +75,8 @@ interface nsILDAPOperation : nsISupports
* @param aConnection connection this operation should use
* @param aMessageListener interface used to call back the results.
*
* @exception NS_ERROR_INVALID_POINTER
* @exception NS_ERROR_FAILURE failed to get connection handle
* @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
* @exception NS_ERROR_UNEXPECTED failed to get connection handle
*/
void init(in nsILDAPConnection aConnection,
in nsILDAPMessageListener aMessageListener);
@ -81,6 +85,12 @@ interface nsILDAPOperation : nsISupports
* wrapper for ldap_simple_bind()
*
* @param passwd the password used for binding; NULL for anon-binds
*
* @exception NS_ERROR_LDAP_ENCODING_ERROR problem encoding bind request
* @exception NS_ERROR_FAILURE server down (XXX rebinds?)
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
* @exception NS_ERROR_UNEXPECTED internal error
*
*/
void simpleBind(in string passwd);
@ -89,6 +99,9 @@ interface nsILDAPOperation : nsISupports
// doesn't know what result came for whom. also, the it calls
// a synchronous bind function under the hood
//
// XXXdmose should probably get rid of this method, due to it's
// synchronity, and since we have other classes to
//
void urlSearch(in string url, in boolean attrsonly);
/**
@ -100,7 +113,7 @@ interface nsILDAPOperation : nsISupports
* @param aTimeOut How long to wait
* @param aSizeLimit Maximum number of entries to return.
*
* @exception NS_ERROR_ILLEGAL_VALUE
* @exception NS_ERROR_NOT_INITIALIZED
* @exception NS_ERROR_LDAP_ENCODING_ERROR
* @exception NS_ERROR_LDAP_SERVER_DOWN
* @exception NS_ERROR_OUT_OF_MEMORY
@ -116,7 +129,7 @@ interface nsILDAPOperation : nsISupports
* wrapper for ldap_abandon_ext() with NULL LDAPControl
* parameters, equivalent to old-style ldap_abandon(), thus the name.
*
* @exception NS_ERROR_ILLEGAL_VALUE an argument was invalid
* @exception NS_ERROR_NOT_INITIALIZED operation not initialized
* @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
* @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
* receive the request or the

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

@ -38,6 +38,16 @@ interface nsILDAPURL : nsIURI {
/**
* the distinguished name of the URL (ie the base DN for the search)
*
* XXXdmose NS_ERROR_NOT_INITIALIZED may become unneccessary once
* it becomes possible to build up the URL by using the setters for its
* constituent parts
*
* for the getter:
*
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
* @exception NS_ERROR_NOT_INITIALIZED URL spec not set
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
*/
attribute string dn;

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

@ -43,13 +43,13 @@
#include "nsILDAPURL.h"
#include "nsIProxyObjectManager.h"
#include "nsIServiceManager.h"
#include "nsIConsoleService.h"
#if !INVOKE_LDAP_CALLBACKS_ON_MAIN_THREAD
#include "nsNetUtil.h"
#include "nsIEventQueueService.h"
#endif
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
static NS_DEFINE_IID(kILDAPMessageListenerIID, NS_ILDAPMESSAGELISTENER_IID);
static NS_DEFINE_IID(kILoadGroupIID, NS_ILOADGROUP_IID);
static NS_DEFINE_IID(kIProgressEventSink, NS_IPROGRESSEVENTSINK_IID);
@ -83,7 +83,11 @@ nsLDAPChannel::Init(nsIURI *uri)
//
mConnection = do_CreateInstance("@mozilla.org/network/ldap-connection;1",
&rv);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::Init(): could not create "
"@mozilla.org/network/ldap-connection;1");
return NS_ERROR_FAILURE;
}
// i think that in the general case, it will be worthwhile to leave the
// callbacks for this channel be invoked on the LDAP connection thread.
@ -97,8 +101,12 @@ nsLDAPChannel::Init(nsIURI *uri)
// get the proxy object manager
//
nsCOMPtr<nsIProxyObjectManager> proxyObjMgr =
do_GetService(kProxyObjectManagerCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
do_GetService("@mozilla.org/xpcomproxy;1", &rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::Init(): could not create "
"proxy object manager");
return NS_ERROR_FAILURE;
}
// and use it to get a proxy for this callback, saving it off in mCallback
//
@ -108,7 +116,11 @@ nsLDAPChannel::Init(nsIURI *uri)
, this),
PROXY_ASYNC|PROXY_ALWAYS,
getter_AddRefs(mCallback));
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::Init(): could not create proxy object");
return NS_ERROR_FAILURE;
}
#else
mCallback = this;
#endif
@ -168,6 +180,7 @@ nsLDAPChannel::Cancel(nsresult aStatus)
mStatus = aStatus;
// if there is an operation running, abandon it and remove it from the
// queue
//
if (mCurrentOperation) {
@ -176,11 +189,18 @@ nsLDAPChannel::Cancel(nsresult aStatus)
rv = mCurrentOperation->Abandon();
NS_ASSERTION(NS_SUCCEEDED(rv), "nsLDAPChannel::Cancel(): "
"mCurrentOperation->Abandon() failed\n");
// make nsCOMPtr call Release()
//
mCurrentOperation = 0;
}
// if the read pipe exists and hasn't already been closed, close it
//
if (mReadPipeOut != 0 && !mReadPipeClosed) {
// XXX set mReadPipeClosed?
// if this fails in a non-debug build, there's not much we can do
//
@ -344,7 +364,9 @@ nsLDAPChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
NS_IMETHODIMP
nsLDAPChannel::GetContentType(char* *aContentType)
{
NS_ENSURE_ARG_POINTER(aContentType);
if (!aContentType) {
return NS_ERROR_ILLEGAL_VALUE;
}
*aContentType = nsCRT::strdup(TEXT_PLAIN);
if (!*aContentType) {
@ -437,8 +459,12 @@ nsLDAPChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
// get the proxy object manager
//
nsCOMPtr<nsIProxyObjectManager> proxyObjMgr =
do_GetService(kProxyObjectManagerCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
do_GetService("@mozilla.org/xpcomproxy;1", &rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::SetLoadGroup(): could not create "
"proxy object manager");
return NS_ERROR_FAILURE;
}
// and use it to get and save a proxy for the load group
//
@ -446,8 +472,11 @@ nsLDAPChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
mUnproxiedLoadGroup,
PROXY_SYNC|PROXY_ALWAYS,
getter_AddRefs(mLoadGroup));
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::SetLoadGroup(): could not create proxy "
"event");
return NS_ERROR_FAILURE;
}
#endif
return NS_OK;
@ -497,10 +526,10 @@ nsLDAPChannel::SetNotificationCallbacks(nsIInterfaceRequestor*
// get the proxy object manager
//
nsCOMPtr<nsIProxyObjectManager> proxyObjMgr =
do_GetService(kProxyObjectManagerCID, &rv);
do_GetService("@mozilla.org/xpcomproxy;1", &rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::SetNotificationCallbacks(): "
"couldn't get proxy object manager");
NS_ERROR("nsLDAPChannel::SetNotificationCallbacks(): could not "
"create proxy object manager");
return NS_ERROR_FAILURE;
}
@ -673,10 +702,17 @@ nsLDAPChannel::AsyncRead(nsIStreamListener* aListener,
// slurp out relevant pieces of the URL
//
rv = mURI->GetHost(getter_Copies(host));
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::AsyncRead(): mURI->GetHost failed\n");
return NS_ERROR_FAILURE;
}
rv = mURI->GetPort(&port);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::AsyncRead(): mURI->GetPort failed\n");
return NS_ERROR_FAILURE;
}
if (port == -1)
port = LDAP_PORT;
@ -698,7 +734,10 @@ nsLDAPChannel::AsyncRead(nsIStreamListener* aListener,
NS_PIPE_DEFAULT_SEGMENT_SIZE,
NS_PIPE_DEFAULT_BUFFER_SIZE,
PR_TRUE, PR_FALSE, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::AsyncRead(): unable to create new pipe");
return NS_ERROR_FAILURE;
}
}
// get an AsyncStreamListener to proxy for mListener, if we're
@ -710,29 +749,53 @@ nsLDAPChannel::AsyncRead(nsIStreamListener* aListener,
#else
rv = NS_NewAsyncStreamListener(getter_AddRefs(mListener),
mUnproxiedListener, NS_UI_THREAD_EVENTQ);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::AsyncRead(): unable to create new "
"AsyncStreamListener");
return NS_ERROR_FAILURE;
}
#endif
// we already know the content type, so we can fire this now
//
mUnproxiedListener->OnStartRequest(this, mResponseContext);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::AsyncRead(): error firing OnStartRequest");
return NS_ERROR_FAILURE;
}
// initialize it with the defaults
// XXXdmose - need to deal with bind name
//
rv = mConnection->Init(host, port, NULL);
NS_ENSURE_SUCCESS(rv, rv);
switch (rv) {
case NS_OK:
break;
case NS_ERROR_OUT_OF_MEMORY:
case NS_ERROR_NOT_AVAILABLE:
case NS_ERROR_FAILURE:
return rv;
case NS_ERROR_ILLEGAL_VALUE:
default:
return NS_ERROR_UNEXPECTED;
}
// create and initialize an LDAP operation (to be used for the bind)
//
mCurrentOperation = do_CreateInstance(
"@mozilla.org/network/ldap-operation;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
// our OnLDAPMessage accepts all result callbacks
//
rv = mCurrentOperation->Init(mConnection, mCallback);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv))
return NS_ERROR_UNEXPECTED; // this should never happen
// kick off a bind operation
//
@ -742,10 +805,7 @@ nsLDAPChannel::AsyncRead(nsIStreamListener* aListener,
// XXXdmose better error handling / passthrough; deal with password
//
#ifdef DEBUG
PR_fprintf(PR_STDERR, "mCurrentOperation->SimpleBind failed. rv=%d\n",
rv);
#endif
NS_WARNING("mCurrentOperation->SimpleBind failed.");
return(rv);
}
@ -776,17 +836,29 @@ nsLDAPChannel::AsyncWrite(nsIInputStream* fromStream,
* Messages received are passed back via this function.
*
* @arg aMessage The message that was returned, NULL if none was.
* @arg aRetVal the return value from ldap_result()
*
* void OnLDAPMessage (in nsILDAPMessage aMessage, in PRInt32 aRetVal
* void OnLDAPMessage (in nsILDAPMessage aMessage)
*/
NS_IMETHODIMP
nsLDAPChannel::OnLDAPMessage(nsILDAPMessage *aMessage, PRInt32 aRetVal)
nsLDAPChannel::OnLDAPMessage(nsILDAPMessage *aMessage)
{
switch (aRetVal) {
PRInt32 messageType;
// figure out what sort of message was returned
//
nsresult rv = aMessage->GetType(&messageType);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::OnLDAPMessage(): unexpected error in "
"nsLDAPChannel::GetType()");
return NS_ERROR_UNEXPECTED;
}
switch (messageType) {
case LDAP_RES_BIND:
// a bind has completed
//
return OnLDAPBind(aMessage);
break;
@ -805,11 +877,26 @@ nsLDAPChannel::OnLDAPMessage(nsILDAPMessage *aMessage, PRInt32 aRetVal)
break;
default:
// XXX bogus. but for now..
NS_WARNING("nsLDAPChannel::OnLDAPMessage(): unexpected LDAP message "
"received");
// get the console service so we can log a message
//
#ifdef DEBUG
PR_fprintf(PR_STDERR, "unexpected LDAP message received.\n");
#endif
nsCOMPtr<nsIConsoleService> consoleSvc =
do_GetService("@mozilla.org/consoleservice;1", &rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::OnLDAPMessage() couldn't get console "
"service");
break;
}
// log the message
//
rv = consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: WARNING: nsLDAPChannel::OnLDAPMessage(): "
"unexpected LDAP message received"));
NS_ASSERTION(NS_SUCCEEDED(rv), "nsLDAPChannel::OnLDAPMessage(): "
"consoleSvc->LogStringMessage() failed");
break;
}
@ -827,13 +914,18 @@ nsLDAPChannel::OnLDAPBind(nsILDAPMessage *aMessage)
// XXX should call ldap_parse_result() here
mCurrentOperation = 0; // done with bind operation
mCurrentOperation = 0; // done with bind op; make nsCOMPtr release it
// create and initialize an LDAP operation (to be used for the bind)
// create and initialize an LDAP operation (to be used for the search
//
mCurrentOperation = do_CreateInstance(
"@mozilla.org/network/ldap-operation;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPChannel::OnLDAPBind(): couldn't create "
"@mozilla.org/network/ldap-operation;1");
// XXX abort entire asyncread
return NS_ERROR_FAILURE;
}
rv = mCurrentOperation->Init(mConnection, mCallback);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -33,12 +33,15 @@
*/
#include "nsLDAPInternal.h"
#include "nsIServiceManager.h"
#include "nsString.h"
#include "nsIComponentManager.h"
#include "nsLDAPConnection.h"
#include "nsLDAPMessage.h"
#include "nsIEventQueueService.h"
#include "nsIConsoleService.h"
static NS_DEFINE_CID(kLDAPMessageCID, NS_LDAPMESSAGE_CID);
const char kConsoleServiceContractId[] = "@mozilla.org/consoleservice;1";
extern "C" int nsLDAPThreadDataInit(void);
extern "C" int nsLDAPThreadFuncsInit(LDAP *aLDAP);
@ -85,8 +88,9 @@ nsLDAPConnection::Init(const char *aHost, PRInt16 aPort, const char *aBindName)
{
nsresult rv;
NS_ENSURE_ARG(aHost);
NS_ENSURE_ARG(aPort);
if ( !aHost ) {
return NS_ERROR_ILLEGAL_VALUE;
}
#ifdef DEBUG
// initialize logging, if it hasn't been already
@ -112,15 +116,15 @@ nsLDAPConnection::Init(const char *aHost, PRInt16 aPort, const char *aBindName)
mBindName = NULL;
}
this->mConnectionHandle = ldap_init(aHost, aPort);
if ( this->mConnectionHandle == NULL) {
this->mConnectionHandle = ldap_init(aHost, aPort ? aPort : LDAP_PORT);
if ( this->mConnectionHandle == NULL ) {
return NS_ERROR_FAILURE; // the LDAP C SDK API gives no useful error
}
// initialize the threading functions for this connection
//
if (!nsLDAPThreadFuncsInit(this->mConnectionHandle)) {
return NS_ERROR_FAILURE;
return NS_ERROR_UNEXPECTED;
}
// initialize the thread-specific data for the calling thread as necessary
@ -147,7 +151,7 @@ nsLDAPConnection::Init(const char *aHost, PRInt16 aPort, const char *aBindName)
#endif
// kick off a thread for result listening and marshalling
// XXXdmose - fourth: should be JOINABLE?
// XXXdmose - should this be JOINABLE?
//
rv = NS_NewThread(getter_AddRefs(mThread), this, 0, PR_UNJOINABLE_THREAD);
if (NS_FAILED(rv)) {
@ -220,7 +224,10 @@ nsLDAPConnection::GetErrorString(char **_retval)
NS_IMETHODIMP
nsLDAPConnection::GetConnectionHandle(LDAP* *aConnectionHandle)
{
NS_ENSURE_ARG_POINTER(aConnectionHandle);
if (!aConnectionHandle) {
NS_ERROR("nsLDAPConnection::GetConnectionHandle(): null pointer "
"passed in");
}
*aConnectionHandle = mConnectionHandle;
return NS_OK;
@ -234,15 +241,15 @@ nsLDAPConnection::GetConnectionHandle(LDAP* *aConnectionHandle)
NS_IMETHODIMP
nsLDAPConnection::AddPendingOperation(nsILDAPOperation *aOperation)
{
nsresult rv;
PRInt32 msgId;
NS_ENSURE_ARG_POINTER(aOperation);
if (!aOperation) {
return NS_ERROR_ILLEGAL_VALUE;
}
// find the message id
//
rv = aOperation->GetMessageId(&msgId);
NS_ENSURE_SUCCESS(rv, rv);
aOperation->GetMessageId(&msgId);
// turn it into an nsVoidKey. note that this is another spot that
// assumes that sizeof(void*) >= sizeof(PRInt32).
@ -257,12 +264,10 @@ nsLDAPConnection::AddPendingOperation(nsILDAPOperation *aOperation)
// actually add it to the queue. if Put indicates that an item in
// the hashtable was actually overwritten, something is really wrong.
//
if (mPendingOperations->Put(key, aOperation) == PR_TRUE) {
#ifdef DEBUG
PR_fprintf(PR_STDERR, "nsLDAPConnection::AddPendingOperation() "
"mPendingOperations->Put() overwrote an item. msgId "
"is supposed to be unique\n");
#endif
if (mPendingOperations->Put(key, aOperation)) {
NS_ERROR("nsLDAPConnection::AddPendingOperation() "
"mPendingOperations->Put() overwrote an item. msgId "
"is supposed to be unique\n");
delete key;
return NS_ERROR_UNEXPECTED;
}
@ -334,31 +339,49 @@ nsLDAPConnection::RemovePendingOperation(nsILDAPOperation *aOperation)
// for nsIRunnable. this thread spins in ldap_result() awaiting the next
// message. once one arrives, it dispatches it to the nsILDAPMessageListener
// on the main thread.
//
// XXX do all returns from this function need to do thread cleanup?
//
NS_IMETHODIMP
nsLDAPConnection::Run(void)
{
int lderrno;
nsresult rv;
PRInt32 returnCode;
LDAPMessage *msgHandle;
nsCOMPtr<nsILDAPMessage> msg;
#ifdef DEBUG
char *errString;
#endif
PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
("nsLDAPConnection::Run() entered\n"));
// get the console service so we can log messages
//
nsCOMPtr<nsIConsoleService> consoleSvc =
do_GetService(kConsoleServiceContractId, &rv);
if (NS_FAILED(rv)) {
NS_ERROR("nsLDAPConnection::Run() couldn't get console service");
return NS_ERROR_FAILURE;
}
// initialize the thread-specific data for the child thread (as necessary)
//
if (!nsLDAPThreadDataInit()) {
NS_ERROR("nsLDAPConnection::Run() couldn't initialize "
"thread-specific data");
return NS_ERROR_FAILURE;
}
PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
("nsLDAPConnection::Run() entered\n"));
// wait for results
//
while(1) {
PRBool operationFinished = PR_TRUE;
// in case something went wrong on the last iteration, be sure to
// cause nsCOMPtr to release the message before going to sleep in
// ldap_result
//
msg = 0;
// XXX deal with timeouts better
//
@ -373,6 +396,7 @@ nsLDAPConnection::Run(void)
// the connection may not exist yet. sleep for a while
// and try again
//
PR_LOG(gLDAPLogModule, PR_LOG_WARNING,
("ldap_result() timed out.\n"));
PR_Sleep(2000); // XXXdmose - reasonable timeslice?
@ -381,16 +405,43 @@ nsLDAPConnection::Run(void)
break;
case -1: // something went wrong
// XXXdmose should propagate the error to the listener
#ifdef DEBUG
(void)this->GetErrorString(&errString);
PR_fprintf(PR_STDERR,"nsLDAPConnection::Run(): "
"ldap_result() failed: %s\n", errString);
ldap_memfree(errString);
#if DEBUG_dmose
PR_Sleep(2000); // don't flood my scrollback
#endif
#endif
lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0);
switch (lderrno) {
case LDAP_SERVER_DOWN:
// XXXreconnect or fail ?
break;
case LDAP_DECODING_ERROR:
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: WARNING: decoding error; "
"possible corrupt data received"));
NS_WARNING("nsLDAPConnection::Run(): ldaperrno = "
"LDAP_DECODING_ERROR after ldap_result()");
break;
case LDAP_NO_MEMORY:
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: ERROR: couldn't allocate memory "
"while getting async operation result"));
// punt and hope things work out better next time around
break;
default:
// shouldn't happen; internal error
//
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: DEBUG: ldaperrno set to "
"unexpected value after ldap_result() "
"call in nsLDAPConnection::Run()"));
NS_WARNING("nsLDAPConnection::Run(): ldaperrno set to "
"unexpected value after ldap_result() "
"call in nsLDAPConnection::Run()");
break;
}
break;
case LDAP_RES_SEARCH_ENTRY:
@ -404,22 +455,73 @@ nsLDAPConnection::Run(void)
default: // initialize the message and call the callback
msg = do_CreateInstance(kLDAPMessageCID, &rv);
NS_ENSURE_SUCCESS(rv, rv); // XXX get rid of return
// we want nsLDAPMessage specifically, not a compatible, since
// we're sharing native objects used by the LDAP C SDK
//
msg = new nsLDAPMessage();
if (!msg) {
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: ERROR: couldn't allocate memory "
"for new LDAP message; search entry "
"dropped"));
// punt and hope things work out better next time around
break;
}
rv = msg->Init(this, msgHandle);
NS_ENSURE_SUCCESS(rv, rv); // XXX get rid of return
switch (rv) {
// call the callback on the nsILDAPOperation corresponding to this
//
rv = InvokeMessageCallback(msgHandle, msg, returnCode,
operationFinished);
NS_ASSERTION(NS_SUCCEEDED(rv), "nsLDAPConnection::Run(): "
"InvokeMessageCallback() failed");
case NS_OK:
break;
// we're all done with the message here. make nsCOMPtr release it.
case NS_ERROR_LDAP_DECODING_ERROR:
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: WARNING: decoding error; "
"possible corrupt data received"));
NS_WARNING("nsLDAPConnection::Run(): ldaperrno = "
"LDAP_DECODING_ERROR after ldap_result()");
continue;
break;
case NS_ERROR_OUT_OF_MEMORY:
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: ERROR: couldn't allocate memory "
"for new LDAP message; search entry "
"dropped"));
// punt and hope things work out better next time around
continue;
break;
case NS_ERROR_ILLEGAL_VALUE:
case NS_ERROR_UNEXPECTED:
default:
// shouldn't happen; internal error
//
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: DEBUG: nsLDAPConnection::Run(): "
"nsLDAPMessage::Init() returned "
"unexpected value"));
NS_WARNING("nsLDAPConnection::Run(): nsLDAPMessage::Init() "
"returned unexpected value.");
// punt and hope things work out better next time around
continue;
break;
}
// invoke the callback on the nsILDAPOperation corresponding to
// this message
//
msg = 0;
rv = InvokeMessageCallback(msgHandle, msg, operationFinished);
if (NS_FAILED(rv)) {
consoleSvc->LogStringMessage(
NS_LITERAL_STRING("LDAP: ERROR: problem invoking "
"message callback"));
NS_ERROR("LDAP: ERROR: problem invoking message callback");
// punt and hope things work out better next time around
continue;
break;
}
#if 0
// sleep for a while to workaround event queue flooding
@ -444,7 +546,6 @@ nsLDAPConnection::Run(void)
nsresult
nsLDAPConnection::InvokeMessageCallback(LDAPMessage *aMsgHandle,
nsILDAPMessage *aMsg,
PRInt32 aReturnCode,
PRBool aRemoveOpFromConnQ)
{
PRInt32 msgId;
@ -458,10 +559,8 @@ nsLDAPConnection::InvokeMessageCallback(LDAPMessage *aMsgHandle,
//
msgId = ldap_msgid(aMsgHandle);
if (msgId == -1) {
#ifdef DEBUG
PR_fprintf(PR_STDERR, "nsLDAPConnection::GetCallbackByMessage():"
"ldap_msgid() failed\n");
#endif
NS_ERROR("nsLDAPConnection::GetCallbackByMessage(): "
"ldap_msgid() failed\n");
return NS_ERROR_FAILURE;
}
@ -494,11 +593,16 @@ nsLDAPConnection::InvokeMessageCallback(LDAPMessage *aMsgHandle,
// callback which should happen on another thread)
//
rv = operation->GetMessageListener(getter_AddRefs(listener));
NS_ENSURE_SUCCESS(rv, rv);
if (!NS_SUCCEEDED(rv)) {
NS_ERROR("nsLDAPConnection::InvokeMessageCallback(): probable "
"memory corruption: GetMessageListener() returned error");
delete key;
return NS_ERROR_UNEXPECTED;
}
// invoke the callback
//
listener->OnLDAPMessage(aMsg, aReturnCode);
listener->OnLDAPMessage(aMsg);
// if requested (ie the operation is done), remove the operation
// from the connection queue.

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

@ -72,7 +72,6 @@ class nsLDAPConnection : public nsILDAPConnection, nsIRunnable
//
nsresult InvokeMessageCallback(LDAPMessage *aMsgHandle,
nsILDAPMessage *aMsg,
PRInt32 aReturnCode,
PRBool aRemoveOpFromConnQ);
LDAP *mConnectionHandle; // the LDAP C SDK's connection object

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

@ -197,7 +197,6 @@ nsLDAPThreadFuncsInit(LDAP *aLDAP)
if (ldap_set_option(aLDAP, LDAP_OPT_THREAD_FN_PTRS,
(void *)&kLDAPThreadFuncs) != 0) {
ldap_perror(aLDAP, "ldap_set_option: LDAP_OPT_THREAD_FN_PTRS\n" );
return 0;
}

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

@ -46,8 +46,15 @@ nsLDAPMessage::nsLDAPMessage()
{
NS_INIT_ISUPPORTS();
mMsgHandle = NULL;
mConnectionHandle = NULL;
mMsgHandle = 0;
mConnectionHandle = 0;
// stuff returned by ldap_parse_result
//
mMatchedDn = 0;
mErrorMessage = 0;
mReferrals = 0;
mServerControls = 0;
}
// destructor
@ -56,7 +63,7 @@ nsLDAPMessage::~nsLDAPMessage(void)
{
int rc;
if (mMsgHandle != NULL) {
if (mMsgHandle) {
rc = ldap_msgfree(mMsgHandle);
switch(rc) {
@ -73,12 +80,14 @@ nsLDAPMessage::~nsLDAPMessage(void)
case LDAP_RES_ANY:
// success
break;
case LDAP_SUCCESS:
// timed out (dunno why LDAP_SUCCESS is used to indicate this)
PR_LOG(gLDAPLogModule, PR_LOG_WARNING,
("nsLDAPMessage::~nsLDAPMessage: ldap_msgfree() "
"timed out\n"));
break;
default:
// other failure
PR_LOG(gLDAPLogModule, PR_LOG_WARNING,
@ -88,6 +97,22 @@ nsLDAPMessage::~nsLDAPMessage(void)
}
}
if (mMatchedDn) {
ldap_memfree(mMatchedDn);
}
if (mErrorMessage) {
ldap_memfree(mErrorMessage);
}
if (mReferrals) {
ldap_value_free(mReferrals);
}
if (mServerControls) {
ldap_controls_free(mServerControls);
}
}
// associate this message with an existing operation
@ -95,11 +120,13 @@ nsLDAPMessage::~nsLDAPMessage(void)
NS_IMETHODIMP
nsLDAPMessage::Init(nsILDAPConnection *aConnection, LDAPMessage *aMsgHandle)
{
nsresult rv;
int parseResult;
if (!aConnection || !aMsgHandle) {
NS_WARNING("Null pointer passed in to nsLDAPMessage::Init()");
return NS_ERROR_ILLEGAL_VALUE;
}
NS_ENSURE_ARG_POINTER(aConnection);
NS_ENSURE_ARG_POINTER(aMsgHandle);
// initialize the appropriate member vars
//
mConnection = aConnection;
@ -107,67 +134,115 @@ nsLDAPMessage::Init(nsILDAPConnection *aConnection, LDAPMessage *aMsgHandle)
// cache the connection handle associated with this operation
//
rv = mConnection->GetConnectionHandle(&mConnectionHandle);
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
nsresult rv = mConnection->GetConnectionHandle(&mConnectionHandle);
if (NS_FAILED(rv)) {
NS_WARNING("nsLDAPMessage::Init(): mConnection->GetConnectionHandle() "
"failed");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
// do any useful message parsing
//
const int msgType = ldap_msgtype(mMsgHandle);
if ( msgType == -1) {
NS_ERROR("nsLDAPMessage::Init(): ldap_msgtype() failed");
return NS_ERROR_UNEXPECTED;
}
// XXX - both this and GetErrorString should be based on a separately
// broken out ldap_parse_result
//
NS_IMETHODIMP
nsLDAPMessage::GetErrorCode(PRInt32 *aErrCode)
{
PRInt32 rc;
switch (msgType) {
rc = ldap_parse_result(mConnectionHandle, mMsgHandle, aErrCode,
NULL, NULL, NULL, NULL, 0);
case LDAP_RES_SEARCH_REFERENCE:
// XXX should do something here?
break;
if (rc != LDAP_SUCCESS) {
case LDAP_RES_SEARCH_ENTRY:
// nothing to do here
break;
#ifdef DEBUG
PR_fprintf(PR_STDERR,
"nsLDAPMessage::ErrorToString: ldap_parse_result: %s\n",
ldap_err2string(rc));
#endif
return NS_ERROR_FAILURE;
case LDAP_RES_EXTENDED:
// XXX should do something here?
break;
case LDAP_RES_BIND:
case LDAP_RES_SEARCH_RESULT:
case LDAP_RES_MODIFY:
case LDAP_RES_ADD:
case LDAP_RES_DELETE:
case LDAP_RES_MODRDN:
case LDAP_RES_COMPARE:
parseResult = ldap_parse_result(mConnectionHandle, mMsgHandle,
&mErrorCode, &mMatchedDn,
&mErrorMessage,&mReferrals,
&mServerControls, 0);
switch (parseResult) {
case LDAP_SUCCESS:
// we're good
break;
case LDAP_DECODING_ERROR:
NS_WARNING("nsLDAPMessage::Init(): ldap_parse_result() hit a "
"decoding error");
return NS_ERROR_LDAP_DECODING_ERROR;
break;
case LDAP_NO_MEMORY:
NS_WARNING("nsLDAPMessage::Init(): ldap_parse_result() ran out "
"of memory");
return NS_ERROR_OUT_OF_MEMORY;
break;
case LDAP_PARAM_ERROR:
case LDAP_MORE_RESULTS_TO_RETURN:
case LDAP_NO_RESULTS_RETURNED:
default:
NS_ERROR("nsLDAPMessage::Init(): ldap_parse_result returned "
"unexpected return code");
return NS_ERROR_UNEXPECTED;
break;
}
break;
default:
NS_ERROR("nsLDAPMessage::Init(): unexpected message type");
return NS_ERROR_UNEXPECTED;
break;
}
return NS_OK;
}
// XXX deal with extra params (make client not have to use ldap_memfree() on
// result)
// XXX better error-handling than fprintf()
//
char *
nsLDAPMessage::GetErrorString(void)
/**
* The result code of the (possibly partial) operation.
*
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
*
* readonly attribute long errorCode;
*/
NS_IMETHODIMP
nsLDAPMessage::GetErrorCode(PRInt32 *aErrorCode)
{
int errcode;
char *matcheddn;
char *errmsg;
char **referrals;
LDAPControl **serverctrls;
if (!aErrorCode) {
return NS_ERROR_ILLEGAL_VALUE;
}
int rc;
*aErrorCode = mErrorCode;
return NS_OK;
}
rc = ldap_parse_result(mConnectionHandle, mMsgHandle, &errcode, &matcheddn,
&errmsg, &referrals, &serverctrls, 0);
if (rc != LDAP_SUCCESS) {
PR_fprintf(PR_STDERR,
"nsLDAPMessage::ErrorToString: ldap_parse_result: %s\n",
ldap_err2string(rc));
// XXX need real err handling here
}
NS_IMETHODIMP
nsLDAPMessage::GetType(PRInt32 *aType)
{
if (!aType) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (matcheddn) ldap_memfree(matcheddn);
if (errmsg) ldap_memfree(errmsg);
if (referrals) ldap_memfree(referrals);
if (serverctrls) ldap_memfree(serverctrls);
*aType = ldap_msgtype(mMsgHandle);
if (*aType == -1) {
return NS_ERROR_UNEXPECTED;
};
return(ldap_err2string(errcode));
return NS_OK;
}
// we don't get to use exceptions, so we'll fake it. this is an error
@ -352,14 +427,6 @@ nsLDAPMessage::IterateAttributes(PRUint32 *aAttrCount, char** *aAttributes,
return NS_OK;
}
// wrapper for ldap_msgtype()
//
int
nsLDAPMessage::Type(void)
{
return (ldap_msgtype(mMsgHandle));
}
/*
* Wrapper for ldap_get_dn(). Returns the Distinguished Name of the
* entry associated with this message.

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

@ -60,15 +60,6 @@ class nsLDAPMessage : public nsILDAPMessage
nsLDAPMessage();
virtual ~nsLDAPMessage();
// XXXdmose - cleanup: turn an error condition associated with this
// message into a string
//
char *GetErrorString(void);
// XXXdmose - cleanup: wrapper for ldap_msgtype()
//
int Type(void);
protected:
nsresult IterateAttrErrHandler(PRInt32 aLderrno, PRUint32 *aAttrCount,
char** *aAttributes, BerElement *position);
@ -78,6 +69,14 @@ class nsLDAPMessage : public nsILDAPMessage
nsCOMPtr<nsILDAPOperation> mOperation; // operation this msg relates to
nsCOMPtr<nsILDAPConnection> mConnection; // cached connection this op is on
LDAP *mConnectionHandle; // cached connection handle
// the next five member vars are returned by ldap_parse_result()
//
int mErrorCode;
char *mMatchedDn;
char *mErrorMessage;
char **mReferrals;
LDAPControl **mServerControls;
};
#endif /* _nsLDAPMessage_h */

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

@ -61,7 +61,9 @@ NS_IMETHODIMP
nsLDAPOperation::Init(nsILDAPConnection *aConnection,
nsILDAPMessageListener *aMessageListener)
{
NS_ENSURE_ARG_POINTER(aConnection);
if (!aConnection) {
return NS_ERROR_ILLEGAL_VALUE;
}
// so we know that the operation is not yet running (and therefore don't
// try and call ldap_abandon_ext() on it) or remove it from the queue.
@ -77,7 +79,7 @@ nsLDAPOperation::Init(nsILDAPConnection *aConnection,
//
nsresult rv = mConnection->GetConnectionHandle(&mConnectionHandle);
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
@ -85,7 +87,9 @@ nsLDAPOperation::Init(nsILDAPConnection *aConnection,
NS_IMETHODIMP
nsLDAPOperation::GetConnection(nsILDAPConnection* *aConnection)
{
NS_ENSURE_ARG_POINTER(aConnection);
if (!aConnection) {
return NS_ERROR_ILLEGAL_VALUE;
}
*aConnection = mConnection;
NS_IF_ADDREF(*aConnection);
@ -96,7 +100,9 @@ nsLDAPOperation::GetConnection(nsILDAPConnection* *aConnection)
NS_IMETHODIMP
nsLDAPOperation::GetMessageListener(nsILDAPMessageListener **aMessageListener)
{
NS_ENSURE_ARG_POINTER(aMessageListener);
if (!aMessageListener) {
return NS_ERROR_ILLEGAL_VALUE;
}
*aMessageListener = mMessageListener;
NS_IF_ADDREF(*aMessageListener);
@ -121,15 +127,48 @@ nsLDAPOperation::SimpleBind(const char *passwd)
this->mMsgId = ldap_simple_bind(this->mConnectionHandle, bindName, passwd);
if (this->mMsgId == -1) {
return NS_ERROR_FAILURE;
const int lderrno = ldap_get_lderrno(this->mConnectionHandle, 0, 0);
switch (lderrno) {
case LDAP_ENCODING_ERROR:
return NS_ERROR_LDAP_ENCODING_ERROR;
case LDAP_SERVER_DOWN:
// XXXdmose rebind here?
return NS_ERROR_FAILURE;
case LDAP_NO_MEMORY:
return NS_ERROR_OUT_OF_MEMORY;
default:
return NS_ERROR_UNEXPECTED;
}
}
// make sure the connection knows where to call back once the messages
// for this operation start coming in
//
// XXX should abandon operation if this fails
rv = mConnection->AddPendingOperation(this);
NS_ENSURE_SUCCESS(rv, rv);
switch (rv) {
case NS_OK:
break;
// note that the return value of ldap_abandon_ext() is ignored, as
// there's nothing useful to do with it
case NS_ERROR_OUT_OF_MEMORY:
(void *)ldap_abandon_ext(mConnectionHandle, mMsgId, 0, 0);
return NS_ERROR_OUT_OF_MEMORY;
break;
case NS_ERROR_UNEXPECTED:
case NS_ERROR_ILLEGAL_VALUE:
default:
(void *)ldap_abandon_ext(mConnectionHandle, mMsgId, 0, 0);
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
@ -147,7 +186,10 @@ nsLDAPOperation::SearchExt(const char *base, // base DN to search
struct timeval *timeoutp, // how long to wait
int sizelimit) // max # of entries to return
{
NS_PRECONDITION(mMessageListener != 0, "MessageListener not set");
if (mMessageListener == 0) {
NS_ERROR("nsLDAPOperation::SearchExt(): mMessageListener not set");
return NS_ERROR_NOT_INITIALIZED;
}
return ldap_search_ext(this->mConnectionHandle, base, scope,
filter, attrs, attrsOnly, serverctrls,
@ -176,8 +218,6 @@ nsLDAPOperation::SearchExt(const char *aBaseDn, PRInt32 aScope,
const char *aFilter, PRIntervalTime aTimeOut,
PRInt32 aSizeLimit)
{
NS_PRECONDITION(mMessageListener != 0, "MessageListener not set");
// XXX deal with timeouts
//
int retVal = nsLDAPOperation::SearchExt(aBaseDn, aScope, aFilter, NULL, 0,
@ -188,10 +228,6 @@ nsLDAPOperation::SearchExt(const char *aBaseDn, PRInt32 aScope,
case LDAP_SUCCESS:
break;
case LDAP_PARAM_ERROR:
return NS_ERROR_ILLEGAL_VALUE;
break;
case LDAP_ENCODING_ERROR:
return NS_ERROR_LDAP_ENCODING_ERROR;
break;
@ -208,16 +244,31 @@ nsLDAPOperation::SearchExt(const char *aBaseDn, PRInt32 aScope,
return NS_ERROR_LDAP_NOT_SUPPORTED;
break;
case LDAP_PARAM_ERROR:
default:
NS_ERROR("nsLDAPOperation::SearchExt(): unexpected return value");
return NS_ERROR_UNEXPECTED;
}
// make sure the connection knows where to call back once the messages
// for this operation start coming in
// XXX should abandon operation if this fails
//
nsresult rv = mConnection->AddPendingOperation(this);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
switch (rv) {
case NS_ERROR_OUT_OF_MEMORY:
(void *)ldap_abandon_ext(mConnectionHandle, mMsgId, 0, 0);
return NS_ERROR_OUT_OF_MEMORY;
break;
default:
(void *)ldap_abandon_ext(mConnectionHandle, mMsgId, 0, 0);
NS_ERROR("nsLDAPOperation::SearchExt(): unexpected error in "
"mConnection->AddPendingOperation");
return NS_ERROR_UNEXPECTED;
break;
}
}
return NS_OK;
}
@ -258,12 +309,18 @@ nsLDAPOperation::UrlSearch(const char *aURL, // the search URL
NS_IMETHODIMP
nsLDAPOperation::GetMessageId(PRInt32 *aMsgId)
{
NS_ENSURE_ARG_POINTER(aMsgId);
if (!aMsgId) {
return NS_ERROR_ILLEGAL_VALUE;
}
*aMsgId = this->mMsgId;
return NS_OK;
}
// as far as I can tell from reading the LDAP C SDK code, abandoning something
// that has already been abandoned does not return an error
//
nsresult
nsLDAPOperation::AbandonExt(LDAPControl **serverctrls,
LDAPControl **clientctrls)
@ -271,20 +328,19 @@ nsLDAPOperation::AbandonExt(LDAPControl **serverctrls,
nsresult rv;
int retVal;
NS_ENSURE_TRUE(mMessageListener != 0, NS_ERROR_NOT_INITIALIZED);
NS_ENSURE_TRUE(mMsgId != 0, NS_ERROR_NOT_INITIALIZED);
if ( mMessageListener == 0 || mMsgId == 0 ) {
NS_ERROR("nsLDAPOperation::AbandonExt(): mMessageListener or "
"mMsgId not initialized");
return NS_ERROR_NOT_INITIALIZED;
}
retVal = ldap_abandon_ext(mConnectionHandle, mMsgId, serverctrls,
clientctrls);
clientctrls);
switch (retVal) {
case LDAP_SUCCESS:
break;
case LDAP_PARAM_ERROR:
return NS_ERROR_ILLEGAL_VALUE;
break;
case LDAP_ENCODING_ERROR:
return NS_ERROR_LDAP_ENCODING_ERROR;
break;
@ -297,9 +353,10 @@ nsLDAPOperation::AbandonExt(LDAPControl **serverctrls,
return NS_ERROR_OUT_OF_MEMORY;
break;
case LDAP_PARAM_ERROR:
default:
// XXX PR_Log stuff here
//
NS_ERROR("nsLDAPOperation::AbandonExt(): unexpected return value from "
"ldap_abandon_ext");
return NS_ERROR_UNEXPECTED;
}
@ -309,8 +366,15 @@ nsLDAPOperation::AbandonExt(LDAPControl **serverctrls,
// so we only pay attention to this in debug builds.
//
rv = mConnection->RemovePendingOperation(this);
NS_ASSERTION(NS_SUCCEEDED(rv), "nsLDAPOperation::AbandonExt: "
"mConnection->RemovePendingOperation(this) failed\n");
if (NS_FAILED(rv)) {
// XXXdmose should we use keep Abandon from happening on multiple
// threads at the same time? that's when this condition is most
// likely to occur. i _think_ the LDAP C SDK is ok with this; need
// to verify.
//
NS_WARNING("nsLDAPOperation::AbandonExt: "
"mConnection->RemovePendingOperation(this) failed.");
}
return NS_OK;
}
@ -319,7 +383,7 @@ nsLDAPOperation::AbandonExt(LDAPControl **serverctrls,
* wrapper for ldap_abandon_ext() with NULL LDAPControl
* parameters, equivalent to old-style ldap_abandon(), thus the name.
*
* @exception NS_ERROR_ILLEGAL_VALUE an argument was invalid
* @exception NS_ERROR_NOT_INITIALIZED operation not initialized
* @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
* @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
* receive the request or the

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

@ -62,9 +62,6 @@ nsLDAPURL::GetSpec(char* *aSpec)
// copy it out
//
// XXXdmose: should this (and netwerk base stuff) use ToNewUTF8String
// instead?
//
*aSpec = mSpec.ToNewCString();
// XXXdmose - presumably this is the right thing. nsString.h doesn't
@ -252,8 +249,13 @@ NS_IMETHODIMP nsLDAPURL::Resolve(const char *relativePath, char **_retval)
/* attribute string dn; */
NS_IMETHODIMP nsLDAPURL::GetDn(char * *aDn)
{
NS_ENSURE_ARG_POINTER(aDn);
NS_ENSURE_FALSE(mDesc == nsnull, NS_ERROR_NOT_INITIALIZED);
if (!aDn) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (!mDesc) {
return NS_ERROR_NOT_INITIALIZED;
}
if ( mDesc->lud_dn == NULL ) {
*aDn = nsCRT::strdup(kEmptyString);

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

@ -231,19 +231,18 @@ nsLDAPDataSource.prototype = {
getTargetsBoundCallback.prototype.onLDAPMessage =
function(aMessage, aRetVal) {
function(aMessage) {
if (DEBUG) {
dump("boundCallback() called with scope: \n\t" +
aSource.Value + "\n\t" + aProperty.Value +
"\n\t" + aTruthValue + "\n");
dump("\taRetVal = " + aRetVal + "\n\n");
}
// XXX how do we deal with this in release builds?
// XXX deal with already bound case
//
if (aRetVal != LDAP_RES_BIND) {
if (aMessage.type != LDAP_RES_BIND) {
dump("bind failed\n");
}
@ -271,9 +270,9 @@ nsLDAPDataSource.prototype = {
getTargetsSearchCallback.prototype.onLDAPMessage =
function(aMessage, aRetVal ) {
dump("getTargetsSearchCallback() called with aRetVal=" +
aRetVal + "\n\n");
function(aMessage) {
dump("getTargetsSearchCallback() called with message " +
"of type " + aMessage.type + "\n\n");
}
return new getTargetsSearchCallback();
}