* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
-// $Id: LDAPMessageQueue.cpp,v 1.17 2000/08/31 17:43:48 rhafer Exp $
#include "config.h"
#include "debug.h"
#include "LDAPUrlList.h"
#include "LDAPException.h"
-// TODO: How to handel unsolicited notifications, like notice of
+using namespace std;
+
+// TODO: How to handle unsolicited notifications, like notice of
// disconnection
LDAPMessageQueue::LDAPMessageQueue(LDAPRequest *req){
- DEBUG(LDAP_DEBUG_TRACE, "LDAPMessageQueue::LDAPMessageQueue()" << endl);
- m_reqQueue.push(req);
+ DEBUG(LDAP_DEBUG_CONSTRUCT, "LDAPMessageQueue::LDAPMessageQueue()" << endl);
+ m_activeReq.push(req);
+ m_issuedReq.push_back(req);
}
LDAPMessageQueue::~LDAPMessageQueue(){
- DEBUG(LDAP_DEBUG_TRACE, "LDAPMessageQueue::~LDAPMessageQueue()" << endl);
- LDAPRequest *req;
- while(! m_reqQueue.empty()){
- req=m_reqQueue.top();
- delete req;
- m_reqQueue.pop();
+ 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);
- LDAPMessage *msg;
- LDAPRequest *req=m_reqQueue.top();
- const LDAPConstraints *constr=req->getConstraints();
+ LDAPMessage *msg;
+ LDAPRequest *req=m_activeReq.top();
int msg_id = req->getMsgID();
- int res;
+ int res;
const LDAPAsynConnection *con=req->getConnection();
- res=ldap_result(con->getSessionHandle(),msg_id,0,0,&msg);
- if (res <= 0){
- ldap_msgfree(msg);
- throw LDAPException(con);
- }else{
- LDAPMsg *ret = LDAPMsg::create(req,msg);
- ldap_msgfree(msg);
+ res=ldap_result(con->getSessionHandle(),msg_id,0,0,&msg);
+ if (res <= 0){
+ if(msg != 0){
+ ldap_msgfree(msg);
+ }
+ throw LDAPException(con);
+ }else{
+ const LDAPConstraints *constr=req->getConstraints();
+ LDAPMsg *ret=0;
+ //this can throw an exception (Decoding Error)
+ try{
+ ret = LDAPMsg::create(req,msg);
+ ldap_msgfree(msg);
+ }catch(LDAPException e){
+ //do some clean up
+ delete req;
+ m_activeReq.top();
+ throw;
+ }
switch (ret->getMessageType()) {
case LDAPMsg::SEARCH_REFERENCE :
if (constr->getReferralChase() ){
- LDAPSearchReference *ref=(LDAPSearchReference *)ret;
- LDAPRequest *refReq=chaseReferral(ref->getURLs());
+ //throws Exception (limit Exceeded)
+ LDAPRequest *refReq=chaseReferral(ret);
if(refReq != 0){
- m_reqQueue.push(refReq);
+ m_activeReq.push(refReq);
+ m_issuedReq.push_back(refReq);
+ delete ret;
return getNext();
}
}
return ret;
break;
case LDAPMsg::SEARCH_DONE :
- if (req->isReferral()){
- LDAPResult* res_p=(LDAPResult*)ret;
- switch (res_p->getResultCode()) {
- case LDAPResult::REFERRAL :
- DEBUG(LDAP_DEBUG_TRACE,
- "referral chasing to be implemented"
- << endl);
- return ret;
- break;
- default:
+ 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;
- }
- delete req;
- m_reqQueue.pop();
- return getNext();
- }else{
- 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 :
- DEBUG(LDAP_DEBUG_TRACE,
- "referral chasing to be implemented"
- << endl);
- //for now just end it here
- delete req;
+ 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:
- delete req;
- m_reqQueue.pop();
+ m_activeReq.pop();
return ret;
}
break;
}
- }
+ }
}
// TODO Maybe moved to LDAPRequest::followReferral seems more reasonable
//there
-LDAPRequest* LDAPMessageQueue::chaseReferral(LDAPUrlList *refs){
+LDAPRequest* LDAPMessageQueue::chaseReferral(LDAPMsg* ref){
DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::chaseReferra()" << endl);
- LDAPRequest *req=m_reqQueue.top();
- LDAPRequest *refReq=req->followReferral(refs);
+ 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){
- cout << e << endl;
DEBUG(LDAP_DEBUG_TRACE," caught exception" << endl);
return 0;
}
}
LDAPRequestStack* LDAPMessageQueue::getRequestStack(){
- return &m_reqQueue;
+ DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::getRequestStack()" << endl);
+ return &m_activeReq;
}