diff options
Diffstat (limited to 'contrib/ldapc++/src/LDAPMessageQueue.cpp')
-rw-r--r-- | contrib/ldapc++/src/LDAPMessageQueue.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/contrib/ldapc++/src/LDAPMessageQueue.cpp b/contrib/ldapc++/src/LDAPMessageQueue.cpp new file mode 100644 index 0000000..92ca02d --- /dev/null +++ b/contrib/ldapc++/src/LDAPMessageQueue.cpp @@ -0,0 +1,171 @@ +// $OpenLDAP$ +/* + * Copyright 2000-2021 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ + + +#include "config.h" +#include "debug.h" +#include "LDAPMessageQueue.h" +#include "LDAPRequest.h" +#include "LDAPResult.h" +#include "LDAPSearchReference.h" +#include "LDAPSearchRequest.h" +#include "LDAPUrl.h" +#include "LDAPUrlList.h" +#include "LDAPException.h" + +using namespace std; + +// TODO: How to handle unsolicited notifications, like notice of +// disconnection + +LDAPMessageQueue::LDAPMessageQueue(LDAPRequest *req){ + DEBUG(LDAP_DEBUG_CONSTRUCT, "LDAPMessageQueue::LDAPMessageQueue()" << endl); + m_activeReq.push(req); + m_issuedReq.push_back(req); +} + +LDAPMessageQueue::~LDAPMessageQueue(){ + DEBUG(LDAP_DEBUG_DESTROY, "LDAPMessageQueue::~LDAPMessageQueue()" << endl); + for(LDAPRequestList::iterator i=m_issuedReq.begin(); + i != m_issuedReq.end(); i++){ + delete *i; + } + m_issuedReq.clear(); +} + + +LDAPMsg *LDAPMessageQueue::getNext(){ + DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::getNext()" << endl); + + if ( m_activeReq.empty() ) { + return 0; + } + + LDAPRequest *req=m_activeReq.top(); + LDAPMsg *ret=0; + + try{ + ret = req->getNextMessage(); + }catch(LDAPException e){ + //do some clean up + m_activeReq.pop(); + throw; + } + + const LDAPConstraints *constr=req->getConstraints(); + switch (ret->getMessageType()) { + case LDAPMsg::SEARCH_REFERENCE : + if (constr->getReferralChase() ){ + //throws Exception (limit Exceeded) + LDAPRequest *refReq=chaseReferral(ret); + if(refReq != 0){ + m_activeReq.push(refReq); + m_issuedReq.push_back(refReq); + delete ret; + return getNext(); + } + } + return ret; + break; + case LDAPMsg::SEARCH_ENTRY : + return ret; + break; + case LDAPMsg::SEARCH_DONE : + if(req->isReferral()){ + req->unbind(); + } + switch ( ((LDAPResult*)ret)->getResultCode()) { + case LDAPResult::REFERRAL : + if(constr->getReferralChase()){ + //throws Exception (limit Exceeded) + LDAPRequest *refReq=chaseReferral(ret); + if(refReq != 0){ + m_activeReq.pop(); + m_activeReq.push(refReq); + m_issuedReq.push_back(refReq); + delete ret; + return getNext(); + } + } + return ret; + break; + case LDAPResult::SUCCESS : + if(req->isReferral()){ + delete ret; + m_activeReq.pop(); + return getNext(); + }else{ + m_activeReq.pop(); + return ret; + } + break; + default: + m_activeReq.pop(); + return ret; + break; + } + break; + //must be some kind of LDAPResultMessage + default: + if(req->isReferral()){ + req->unbind(); + } + LDAPResult* res_p=(LDAPResult*)ret; + switch (res_p->getResultCode()) { + case LDAPResult::REFERRAL : + if(constr->getReferralChase()){ + //throws Exception (limit Exceeded) + LDAPRequest *refReq=chaseReferral(ret); + if(refReq != 0){ + m_activeReq.pop(); + m_activeReq.push(refReq); + m_issuedReq.push_back(refReq); + delete ret; + return getNext(); + } + } + return ret; + break; + default: + m_activeReq.pop(); + return ret; + } + break; + } +} + +// TODO Maybe moved to LDAPRequest::followReferral seems more reasonable +//there +LDAPRequest* LDAPMessageQueue::chaseReferral(LDAPMsg* ref){ + DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::chaseReferral()" << endl); + LDAPRequest *req=m_activeReq.top(); + LDAPRequest *refReq=req->followReferral(ref); + if(refReq !=0){ + if(refReq->getConstraints()->getHopLimit() < refReq->getHopCount()){ + delete(refReq); + throw LDAPException(LDAP_REFERRAL_LIMIT_EXCEEDED); + } + if(refReq->isCycle()){ + delete(refReq); + throw LDAPException(LDAP_CLIENT_LOOP); + } + try { + refReq->sendRequest(); + return refReq; + }catch (LDAPException e){ + DEBUG(LDAP_DEBUG_TRACE," caught exception" << endl); + return 0; + } + }else{ + return 0; + } +} + +LDAPRequestStack* LDAPMessageQueue::getRequestStack(){ + DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::getRequestStack()" << endl); + return &m_activeReq; +} + |