NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPMessage(nsILDAPMessage *aMessage) { NS_ENSURE_ARG_POINTER(aMessage); if (!mInitialized) return NS_ERROR_NOT_INITIALIZED; PRInt32 messageType; nsresult rv = aMessage->GetType(&messageType); if (NS_FAILED(rv)) { Done(PR_FALSE); return rv; } switch (messageType) { case nsILDAPMessage::RES_BIND: rv = OnLDAPMessageBind(aMessage); if (NS_FAILED(rv)) rv = Abort(); break; case nsILDAPMessage::RES_SEARCH_ENTRY: rv = OnLDAPSearchEntry(aMessage); break; case nsILDAPMessage::RES_SEARCH_RESULT: rv = OnLDAPSearchResult(aMessage); break; default: // for messageTypes we do not handle return NS_OK to LDAP and move ahead. rv = NS_OK; break; } return rv; }
/** * Messages received are passed back via this function. * * @arg aMessage The message that was returned, NULL if none was. * * void OnLDAPMessage (in nsILDAPMessage aMessage) */ NS_IMETHODIMP nsLDAPAutoCompleteSession::OnLDAPMessage(nsILDAPMessage *aMessage) { PRInt32 messageType; // Just in case. // XXXdmose the semantics of NULL are currently undefined, but are likely // to be defined once we insert timeout handling code into the XPCOM SDK // At that time we should figure out if this still the right thing to do. if (!aMessage) { return NS_OK; } // Figure out what sort of message was returned. nsresult rv = aMessage->GetType(&messageType); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPMessage(): unexpected " "error in aMessage->GetType()"); // Don't call FinishAutoCompleteLookup(), as this could conceivably // be an anomaly, and perhaps the next message will be ok. If this // really was a problem, this search should eventually get // reaped by a timeout (once that code gets implemented). return NS_ERROR_UNEXPECTED; } // If this message is not associated with the current operation, // discard it, since it is probably from a previous (aborted) // operation. bool isCurrent; rv = IsMessageCurrent(aMessage, &isCurrent); if (NS_FAILED(rv)) { // IsMessageCurrent will have logged any necessary errors return rv; } if ( ! isCurrent ) { PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, ("nsLDAPAutoCompleteSession::OnLDAPMessage(): received message " "from operation other than current one; discarded")); return NS_OK; } // XXXdmose - we may want a small state machine either here or // or in the nsLDAPConnection object, to make sure that things are // happening in the right order and timing out appropriately. This will // certainly depend on how timeouts are implemented, and how binding // gets is dealt with by nsILDAPService. Also need to deal with the case // where a bind callback happens after onStopLookup was called. switch (messageType) { case nsILDAPMessage::RES_BIND: // A bind has completed if (mState != BINDING) { PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, ("nsLDAPAutoCompleteSession::OnLDAPMessage(): LDAP bind " "entry returned after OnStopLookup() called; ignoring")); // XXXdmose when nsLDAPService integration happens, need to make // sure that the possibility of having an already bound // connection, due to a previously unaborted bind, doesn't cause // any problems. return NS_OK; } rv = OnLDAPMessageBind(aMessage); if (NS_FAILED(rv)) { mState = UNBOUND; FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, UNBOUND); } else mState = SEARCHING; return rv; case nsILDAPMessage::RES_SEARCH_ENTRY: // Ignore this if OnStopLookup was already called. if (mState != SEARCHING) { PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, ("nsLDAPAutoCompleteSession::OnLDAPMessage(): LDAP search " "entry returned after OnStopLoookup() called; ignoring")); return NS_OK; } // A search entry has been returned. return OnLDAPSearchEntry(aMessage); case nsILDAPMessage::RES_SEARCH_RESULT: // Ignore this if OnStopLookup was already called. if (mState != SEARCHING) { PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, ("nsLDAPAutoCompleteSession::OnLDAPMessage(): LDAP search " "result returned after OnStopLookup called; ignoring")); return NS_OK; } // The search is finished; we're all done. return OnLDAPSearchResult(aMessage); default: // Given the LDAP operations nsLDAPAutoCompleteSession uses, we should // never get here. If we do get here in a release build, it's // probably a bug, but maybe it's the LDAP server doing something // weird. Might as well try and continue anyway. The session should // eventually get reaped by the timeout code, if necessary. // NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPMessage(): unexpected " "LDAP message received"); return NS_OK; } }
NS_IMETHODIMP nsAbQueryLDAPMessageListener::OnLDAPMessage(nsILDAPMessage *aMessage) { nsresult rv; rv = Initiate(); NS_ENSURE_SUCCESS(rv, rv); PRInt32 messageType; rv = aMessage->GetType(&messageType); NS_ENSURE_SUCCESS(rv, rv); PRBool cancelOperation = PR_FALSE; // Enter lock { nsAutoLock lock (mLock); if (mFinished) return NS_OK; if (messageType == nsILDAPMessage::RES_SEARCH_RESULT) mFinished = PR_TRUE; else if (mCanceled) { mFinished = PR_TRUE; cancelOperation = PR_TRUE; } } // Leave lock if (!mDirectoryQuery) return NS_ERROR_NULL_POINTER; nsCOMPtr<nsIAbDirectoryQueryResult> queryResult; if (!cancelOperation) { switch (messageType) { case nsILDAPMessage::RES_BIND: rv = OnLDAPMessageBind (aMessage); NS_ENSURE_SUCCESS(rv, rv); break; case nsILDAPMessage::RES_SEARCH_ENTRY: if (!mFinished && !mWaitingForPrevQueryToFinish) { rv = OnLDAPMessageSearchEntry (aMessage, getter_AddRefs (queryResult)); } break; case nsILDAPMessage::RES_SEARCH_RESULT: mWaitingForPrevQueryToFinish = PR_FALSE; rv = OnLDAPMessageSearchResult (aMessage, getter_AddRefs (queryResult)); NS_ENSURE_SUCCESS(rv, rv); default: break; } } else { if (mSearchOperation) rv = mSearchOperation->AbandonExt (); rv = QueryResultStatus (nsnull, getter_AddRefs (queryResult), nsIAbDirectoryQueryResult::queryResultStopped); // reset because we might re-use this listener...except don't do this // until the search is done, so we'll ignore results from a previous // search. if (messageType == nsILDAPMessage::RES_SEARCH_RESULT) mCanceled = mFinished = PR_FALSE; } if (queryResult && mQueryListener) rv = mQueryListener->OnQueryItem (queryResult); return rv; }