Back to index

openldap  2.4.31
LDAPMessageQueue.cpp
Go to the documentation of this file.
00001 // $OpenLDAP$
00002 /*
00003  * Copyright 2000-2012 The OpenLDAP Foundation, All Rights Reserved.
00004  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
00005  */
00006 
00007 
00008 #include "config.h"
00009 #include "debug.h"
00010 #include "LDAPMessageQueue.h"
00011 #include "LDAPRequest.h"
00012 #include "LDAPResult.h"
00013 #include "LDAPSearchReference.h"
00014 #include "LDAPSearchRequest.h"
00015 #include "LDAPUrl.h"
00016 #include "LDAPUrlList.h"
00017 #include "LDAPException.h"
00018 
00019 using namespace std;
00020 
00021 // TODO: How to handle unsolicited notifications, like notice of
00022 //       disconnection
00023 
00024 LDAPMessageQueue::LDAPMessageQueue(LDAPRequest *req){
00025     DEBUG(LDAP_DEBUG_CONSTRUCT, "LDAPMessageQueue::LDAPMessageQueue()" << endl);
00026        m_activeReq.push(req);
00027     m_issuedReq.push_back(req);
00028 }
00029 
00030 LDAPMessageQueue::~LDAPMessageQueue(){
00031     DEBUG(LDAP_DEBUG_DESTROY, "LDAPMessageQueue::~LDAPMessageQueue()" << endl);
00032     for(LDAPRequestList::iterator i=m_issuedReq.begin(); 
00033             i != m_issuedReq.end(); i++){
00034         delete *i;
00035     }
00036     m_issuedReq.clear();
00037 }
00038 
00039 
00040 LDAPMsg *LDAPMessageQueue::getNext(){
00041     DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::getNext()" << endl);
00042 
00043     if ( m_activeReq.empty() ) {
00044         return 0;
00045     }
00046 
00047     LDAPRequest *req=m_activeReq.top();
00048     LDAPMsg *ret=0;
00049 
00050     try{
00051         ret = req->getNextMessage();
00052     }catch(LDAPException e){
00053         //do some clean up
00054         m_activeReq.pop();
00055         throw;   
00056     }
00057 
00058     const LDAPConstraints *constr=req->getConstraints();
00059     switch (ret->getMessageType()) {
00060         case LDAPMsg::SEARCH_REFERENCE : 
00061             if (constr->getReferralChase() ){
00062                 //throws Exception (limit Exceeded)
00063                 LDAPRequest *refReq=chaseReferral(ret);
00064                 if(refReq != 0){
00065                     m_activeReq.push(refReq);
00066                     m_issuedReq.push_back(refReq);
00067                     delete ret;
00068                     return getNext();
00069                 }
00070             }
00071             return ret;
00072         break;
00073         case LDAPMsg::SEARCH_ENTRY :
00074             return ret;
00075         break;
00076         case LDAPMsg::SEARCH_DONE :
00077             if(req->isReferral()){
00078                 req->unbind();
00079             }
00080             switch ( ((LDAPResult*)ret)->getResultCode()) {
00081                 case LDAPResult::REFERRAL :
00082                     if(constr->getReferralChase()){
00083                         //throws Exception (limit Exceeded)
00084                         LDAPRequest *refReq=chaseReferral(ret);
00085                         if(refReq != 0){
00086                             m_activeReq.pop();
00087                             m_activeReq.push(refReq);
00088                             m_issuedReq.push_back(refReq);
00089                             delete ret;
00090                             return getNext();
00091                         }
00092                     }    
00093                     return ret;
00094                 break;
00095                 case LDAPResult::SUCCESS :
00096                     if(req->isReferral()){
00097                         delete ret;
00098                         m_activeReq.pop();
00099                         return getNext();
00100                     }else{
00101                         m_activeReq.pop();
00102                         return ret;
00103                     }
00104                 break;
00105                 default:
00106                     m_activeReq.pop();
00107                     return ret;
00108                 break;
00109             }
00110         break;
00111         //must be some kind of LDAPResultMessage
00112         default:
00113             if(req->isReferral()){
00114                 req->unbind();
00115             }
00116             LDAPResult* res_p=(LDAPResult*)ret;
00117             switch (res_p->getResultCode()) {
00118                 case LDAPResult::REFERRAL :
00119                     if(constr->getReferralChase()){
00120                         //throws Exception (limit Exceeded)
00121                         LDAPRequest *refReq=chaseReferral(ret);
00122                         if(refReq != 0){
00123                             m_activeReq.pop();
00124                             m_activeReq.push(refReq);
00125                             m_issuedReq.push_back(refReq);
00126                             delete ret;
00127                             return getNext();
00128                         }
00129                     }    
00130                     return ret;
00131                 break;
00132                 default:
00133                     m_activeReq.pop();
00134                     return ret;
00135             }
00136         break;
00137     }
00138 }
00139 
00140 // TODO Maybe moved to LDAPRequest::followReferral seems more reasonable
00141 //there
00142 LDAPRequest* LDAPMessageQueue::chaseReferral(LDAPMsg* ref){
00143     DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::chaseReferral()" << endl);
00144     LDAPRequest *req=m_activeReq.top();
00145     LDAPRequest *refReq=req->followReferral(ref);
00146     if(refReq !=0){
00147         if(refReq->getConstraints()->getHopLimit() < refReq->getHopCount()){
00148             delete(refReq);
00149             throw LDAPException(LDAP_REFERRAL_LIMIT_EXCEEDED);
00150         }
00151         if(refReq->isCycle()){
00152             delete(refReq);
00153             throw LDAPException(LDAP_CLIENT_LOOP);
00154         }
00155         try {
00156             refReq->sendRequest();
00157             return refReq;
00158         }catch (LDAPException e){
00159             DEBUG(LDAP_DEBUG_TRACE,"   caught exception" << endl);
00160             return 0;
00161         }
00162     }else{ 
00163         return 0;
00164     }
00165 }
00166 
00167 LDAPRequestStack* LDAPMessageQueue::getRequestStack(){
00168     DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::getRequestStack()" << endl);
00169     return &m_activeReq;
00170 }
00171